fix: coerce array/vector literal elements to element type (issue 0168)

[N]?T arrays were corrupted: a positional literal .{ null, 7 } stored
bare T/null elements into {T,i1} optional slots because array elements
were never coerced (getStructFields is empty for an array, so the
i<struct_fields.len field-coercion gate never fired). A present element
then read back as absent and direct indexing segfaulted.

lowerStructLiteral's positional branch now computes array_elem_ty for
array/vector targets and coerces each element to it; lowerArrayLiteral
generalizes its slice-only coercion to coerce every element via
coerceToType (layout-aware: scalar->{T,i1}, pointer-sentinel->one-word,
array->slice, concrete->protocol). Verified by 3 adversarial reviews,
suite 780/0.

Regression: examples/optionals/0913-optionals-array-of-optionals.sx.
Filed adjacent pre-existing bugs: 0173 (typed .[null,..] element), 0174
(tuple positional-element coercion), 0175 (positional struct literal
variable element zeroed).
This commit is contained in:
agra
2026-06-22 22:50:20 +03:00
parent 2ea25e84ec
commit 5a436eddb1
9 changed files with 253 additions and 17 deletions

View File

@@ -1,5 +1,22 @@
# 0168 — indexing an array of optionals `[N]?T` produces a wrong/garbage element (segfault or wrong value)
> **RESOLVED.** Not a GEP/stride bug — a positional literal `.{ null, 7 }` for an
> array target was storing bare `T`/`null` elements into the `{T,i1}` optional
> slots because array elements were never coerced to the element type
> (`getStructFields` is empty for an array, so the per-field coercion gate
> `i < struct_fields.len` never fired). Fix (`src/ir/lower/expr.zig`): in
> `lowerStructLiteral`'s positional branch, compute `array_elem_ty` for
> array/vector targets and coerce each positional element to it; in
> `lowerArrayLiteral`, generalize the previous slice-only coercion to coerce
> every element via `coerceToType` (which is layout-aware — scalar→`{T,i1}`,
> pointer-sentinel→one-word, array→slice, concrete→protocol). Verified across
> scalar/struct/pointer-sentinel optional elements, int→float/widening/erasure/
> array→slice element coercions, nested + vector arrays, by 3 adversarial
> reviews; suite 780/0. Regression:
> `examples/optionals/0913-optionals-array-of-optionals.sx`. (Adjacent
> pre-existing bugs found + filed: 0173 typed `.[null,…]` element, 0174 tuple
> positional-element coercion, 0175 positional struct literal variable element.)
## Symptom
Reading an element of an array whose element type is an optional (`[N]?T`) is