You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: []Type{elem, ...} composite-literal sugar for arrays; fix named-array-value type checking
Go-style typed array literal syntax, e.g. `xs := []int{1, 2, 3}`.
Desugars to exactly the same construction `var xs []int = [1, 2, 3]`
already compiles to (an anonymous array named_type built once, its
object pushed as a constant, the plain array value passed to it as a
single-arg call) -- reusing that machinery rather than a second
implementation of element-type checking. Supports primitive, struct,
named-type, empty, and nested ([][]int{...}) element types.
Disambiguating this from a plain array literal or an empty [] is
genuinely ambiguous by token lookahead alone: Gengo is newline-
insensitive, so `xs := []` immediately followed by an unrelated new
statement (`func foo() {...}`, `std.io.println(...)`, another `[...]`)
is completely ordinary code that happens to start with a type-spec-like
token. Resolved with real speculative parsing + rollback (save the 4
parser-position fields, attempt to parse a type spec followed by `{`,
restore and fall back to the plain literal on failure) rather than
token-type heuristics.
Two more pre-existing bugs found and fixed along the way (reproduced
with the equivalent `var` syntax too, so not introduced by this sugar):
- vm_types.zig matchesTypeAlt's .array/.map cases never unwrapped a
.named_value before checking isArrayObject/isMapObject -- passing an
already-[]T-typed value to a []T-typed function parameter always
failed with a confusingly identical-looking "expected []T, got []T"
(both sides render the same runtime type name; the check just never
looked inside the wrapper constructNamedType's .array_t/.map_t cases
always produce). This is also why [][]int{...} previously failed:
each inner element is itself a named-array-typed value.
- The disambiguation logic's first draft (inline in parsePrecedence's
switch) increased that recursive function's per-call stack frame size
in an unoptimized/Debug build enough to trip a pre-existing
"expression too deep" stack-overflow guard test before its own
software depth counter could fire. Fixed by extracting the whole
disambiguation into its own function so those locals don't live in
the recursive function's frame.
Verified clean under standard, -Dpreset=stress, and -Dgc_stress=true.
0 commit comments