feat: parenthesized type grouping — (T) groups, (T,) is a 1-tuple (issue 0177)
In type position, parentheses now mirror value position: (T) (a single unnamed element, no trailing comma) is a GROUPING that resolves to the inner type; (T,) is a 1-tuple; (A, B) a 2-tuple; named (x: T) and spread (..Ts) stay tuples; (...) -> R stays a function type. This lets a closure/optional/function type be parenthesized for readability without silently becoming a 1-tuple: [1](Closure(i64,i64) -> i64) // array of closures (issue 0177) -> 7 ?(?i64) // genuine nested optional (issue 0165 intent) Parser: src/parser.zig returns the inner node for a single unnamed non-spread no-trailing-comma parenthesized type. formatTypeName (both generic.zig diagnostics + types.zig reflection) now render a 1-tuple as (T,) so the spelling is unambiguous and diagnostics are self-consistent. The 0165 coerce/stmt note reworded accordingly. specs.md §Type Syntax updated; basic/0036 wrap return -> (i64,); obsolete diagnostic 1195 removed (?(?i64) now compiles); regression examples/types/0201-types-parenthesized-type-grouping.sx added; 0414 .ir golden regenerated for the (T,) rendering. Resolves 0177; updates 0165/0170. Verified by 3 adversarial reviews; suite 792/0.
This commit is contained in:
@@ -14,6 +14,11 @@
|
||||
> Genuine nested optionals via alias (`Opt :: ?i64; ?Opt`) work and round-trip.
|
||||
> Regressions: `examples/optionals/0911-nested-optional-via-alias.sx`,
|
||||
> `examples/diagnostics/1195-diagnostics-err-parenthesized-optional-tuple.sx`.
|
||||
> **UPDATE (grouping):** `(T)` in type position is now a GROUPING, not a
|
||||
> 1-tuple, so `?(?i64)` is a genuine NESTED OPTIONAL and compiles (what this
|
||||
> issue originally wanted). The coerce guard now only fires for an explicit
|
||||
> 1-tuple child `?(T,)` mismatch (note reworded). The obsolete diagnostic
|
||||
> example 1195 was removed; see `examples/types/0201-types-parenthesized-type-grouping.sx`.
|
||||
> Verified by 3 adversarial reviews. (A review noted `?any` over-rejection;
|
||||
> that turned out to be a casing non-bug — lowercase `any` is an undefined name,
|
||||
> the type is `Any`; see 0171, closed NOT-A-BUG.)
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
> `examples/closures/0311-closures-optional-closure.sx`. (Adjacent pre-existing
|
||||
> bug found + filed: 0177 — array-element closure direct call `fns[i](args)`
|
||||
> crashes.)
|
||||
>
|
||||
> **UPDATE (grouping):** with parenthesized-type grouping now in place,
|
||||
> `?(() -> void)` parses as optional-of-(bare function pointer) `() -> void`,
|
||||
> not a tuple-optional; assigning a closure literal to it correctly diagnoses the
|
||||
> closure-vs-bare-fnptr mismatch (use `?Closure() -> void`). The `g!()`
|
||||
> call-through fix here is unchanged and still correct for `?Closure(...)`.
|
||||
|
||||
## Symptom
|
||||
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# 0177 — calling a closure stored in an array element directly (`fns[i](args)`) crashes / miscompiles
|
||||
|
||||
> **RESOLVED via parenthesized-type grouping.** The repro
|
||||
> `[1](Closure(i64,i64) -> i64) = .[ add ]` was not an array of closures — under
|
||||
> the old rule `(Closure(...) -> R)` was a 1-tuple, so it was an array of
|
||||
> 1-tuples and `fns[0](...)` tried to call a tuple → LLVM "Called function must
|
||||
> be a pointer!". Per the user's direction, parentheses in TYPE position are now
|
||||
> a GROUPING (mirroring value position): `(T)` (no trailing comma) resolves to
|
||||
> the inner type, `(T,)` is the 1-tuple. So `[1](Closure(...) -> R)` is now an
|
||||
> array of closures and `fns[0](3,4)` returns `7`. (The canonical non-paren
|
||||
> `[1]Closure(...) -> R = .[ add ]` already worked.) Implemented in
|
||||
> `src/parser.zig` (single unnamed non-spread element, no trailing comma →
|
||||
> return the inner type node). Regression:
|
||||
> `examples/types/0201-types-parenthesized-type-grouping.sx`. specs.md §Type
|
||||
> Syntax updated. Verified by 3 adversarial reviews; suite 792/0.
|
||||
|
||||
## Symptom
|
||||
|
||||
A closure (or `Closure(...)`-typed value) stored in an array, called DIRECTLY via
|
||||
|
||||
Reference in New Issue
Block a user