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:
15
specs.md
15
specs.md
@@ -840,13 +840,22 @@ zeroed : (i32, i32) = ---; // zero-initialized tuple
|
||||
Note: In value position, `(expr)` without a comma is a grouping expression, not a tuple. Use `(expr,)` for a 1-tuple value.
|
||||
|
||||
#### Type Syntax
|
||||
In type position, `(T)` is always a tuple type — no trailing comma needed. The `->` arrow disambiguates function types from tuple types:
|
||||
In type position, parentheses mirror value position: `(T)` (a single element, no
|
||||
trailing comma) is a **grouping** that resolves to the inner type `T`, while
|
||||
`(T,)` (trailing comma) is a 1-tuple. `(A, B)` is a 2-tuple. The `->` arrow
|
||||
disambiguates function types from grouped/tuple types:
|
||||
```sx
|
||||
(i64) // tuple type with one field
|
||||
(i64) // grouping: resolves to i64 (NOT a tuple)
|
||||
(i64,) // tuple type with one field
|
||||
(i64, i64) // tuple type with two fields
|
||||
(i64) -> i64 // function type: takes i64, returns i64
|
||||
(i64, i64) -> i64 // function type: takes two i64, returns i64
|
||||
?(?i64) // grouping → a genuine nested optional
|
||||
[1](Closure(i64,i64) -> i64) // grouping → array of one closure
|
||||
```
|
||||
Grouping lets a closure/optional/function type be parenthesized for readability
|
||||
without silently becoming a 1-tuple. A named single element `(x: T)` stays a
|
||||
(named) tuple.
|
||||
|
||||
#### Field Access
|
||||
```sx
|
||||
@@ -859,7 +868,7 @@ named.0; // 10 — numeric index also works on named tuples
|
||||
#### As Return Type
|
||||
```sx
|
||||
swap :: (a: i64, b: i64) -> (i64, i64) { (b, a); }
|
||||
wrap :: (x: i64) -> (i64) { (x,); }
|
||||
wrap :: (x: i64) -> (i64,) { (x,); } // 1-tuple return needs the trailing comma
|
||||
|
||||
s := swap(1, 2); // s.0 = 2, s.1 = 1
|
||||
t := wrap(42); // t.0 = 42
|
||||
|
||||
Reference in New Issue
Block a user