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:
33
examples/optionals/0913-optionals-array-of-optionals.sx
Normal file
33
examples/optionals/0913-optionals-array-of-optionals.sx
Normal file
@@ -0,0 +1,33 @@
|
||||
// Indexing an array whose element type is an optional `[N]?T` must load the
|
||||
// full `{T,i1}` element aggregate: a positional `.{ ... }` literal coerces each
|
||||
// element to the optional element type, so a present element reads back present
|
||||
// and an absent one absent. Covers a scalar payload (`?i64`), a struct payload
|
||||
// (`?Pt`), write-then-read, and direct-use of the indexed value (`??`, `if`).
|
||||
//
|
||||
// Regression (issue 0168): the positional struct-literal path treated array
|
||||
// targets as having no named fields and skipped per-element coercion, storing a
|
||||
// bare `T`/`null` into a `{T,i1}` slot — corrupting the array (a present
|
||||
// element read back as absent; indexing it segfaulted).
|
||||
#import "modules/std.sx";
|
||||
|
||||
Pt :: struct { x: i64; y: i64; }
|
||||
|
||||
main :: () {
|
||||
// Scalar payload — read present + absent.
|
||||
arr : [2]?i64 = .{ null, 7 };
|
||||
print("idx ?? : {}\n", arr[1] ?? -1); // 7
|
||||
e := arr[1];
|
||||
if e { print("e present\n"); } else { print("e absent\n"); } // present
|
||||
if arr[0] { print("a0 present\n"); } else { print("a0 absent\n"); } // absent
|
||||
|
||||
// Write an absent slot, then read it back.
|
||||
w : [2]?i64 = .{ null, null };
|
||||
w[0] = 99;
|
||||
print("w0: {}\n", w[0] ?? -1); // 99
|
||||
print("w1: {}\n", w[1] ?? -1); // -1
|
||||
|
||||
// Struct payload `?Pt`.
|
||||
pts : [2]?Pt = .{ null, .{ x = 5, y = 6 } };
|
||||
if pts[0] { print("pt0 present\n"); } else { print("pt0 absent\n"); } // absent
|
||||
if p := pts[1] { print("pt1: {} {}\n", p.x, p.y); } // 5 6
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
idx ?? : 7
|
||||
e present
|
||||
a0 absent
|
||||
w0: 99
|
||||
w1: -1
|
||||
pt0 absent
|
||||
pt1: 5 6
|
||||
Reference in New Issue
Block a user