(C) regToValue (comptime_vm.zig) gained no array arm, so a #run returning an aggregate containing an array bailed 'reg->value: aggregate shape not bridged yet'. Add an .array arm: read N elements at stride typeSizeBytes(elem) from the array address, bridge each recursively via regToValue -> an .aggregate Value (serializeAggregateValue already emits arrays). Composes with struct fields, nested arrays, array-of-structs, and the ?Arr optional payload; unbridgeable elements bail loudly. (E) A global failing #run proceeded into LLVM emission and panicked 'unresolved type reached LLVM emission' when the unresolved const was used. Add 'if (self.comptime_failed) return;' in emit() after Pass 0 so it aborts cleanly (exit 1, the comptime diagnostic) across run/ir/build. Regression: examples/comptime/0644-comptime-run-array-aggregate.sx. Verified by 3 adversarial reviews, suite 793/0. Filed separate bugs found during review: 0181 (optional-chain ?. to array field + index panics), 0182 (body-local #run unbridged silently miscompiles).
63 lines
2.0 KiB
Plaintext
63 lines
2.0 KiB
Plaintext
// A `#run` (comptime const init) whose function returns an aggregate that
|
|
// CONTAINS AN ARRAY — or an array directly — evaluates: the comptime VM's
|
|
// reg→value bridge reads the array's elements out of comptime memory and
|
|
// produces a `Value` array the LLVM serializer emits as a constant.
|
|
//
|
|
// Regression (issue 0167 C): the array-in-aggregate shape used to bail with
|
|
// `reg→value: aggregate shape not bridged yet`.
|
|
// Covers: struct-with-array-field, array-of-structs, nested array `[2][2]`,
|
|
// a direct `[N]T` return, and the `?Arr` optional payload (composes with the
|
|
// optional bridge arm) unwrapped via `!`.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
Arr3 :: struct { xs: [3]i64; }
|
|
Pt :: struct { x: i64; y: i64; }
|
|
Box :: struct { items: [2]Pt; }
|
|
Mat :: struct { g: [2][2]i64; }
|
|
|
|
mk_struct :: () -> Arr3 {
|
|
r : Arr3 = ---;
|
|
r.xs[0] = 1; r.xs[1] = 2; r.xs[2] = 3;
|
|
return r;
|
|
}
|
|
|
|
mk_aos :: () -> Box {
|
|
r : Box = ---;
|
|
r.items[0].x = 1; r.items[0].y = 2;
|
|
r.items[1].x = 3; r.items[1].y = 4;
|
|
return r;
|
|
}
|
|
|
|
mk_nested :: () -> Mat {
|
|
r : Mat = ---;
|
|
r.g[0][0] = 1; r.g[0][1] = 2;
|
|
r.g[1][0] = 3; r.g[1][1] = 4;
|
|
return r;
|
|
}
|
|
|
|
mk_direct :: () -> [3]i64 {
|
|
r : [3]i64 = ---;
|
|
r[0] = 7; r[1] = 8; r[2] = 9;
|
|
return r;
|
|
}
|
|
|
|
mk_opt :: () -> ?Arr3 {
|
|
r : Arr3 = .{ xs = .[10, 20, 30] };
|
|
return r;
|
|
}
|
|
|
|
G :: #run mk_struct(); // struct { [3]i64 }
|
|
B :: #run mk_aos(); // struct { [2]Pt }
|
|
M :: #run mk_nested(); // struct { [2][2]i64 }
|
|
D :: #run mk_direct(); // [3]i64
|
|
A :: #run mk_opt(); // ?Arr3
|
|
|
|
main :: () {
|
|
print("{} {} {}\n", G.xs[0], G.xs[1], G.xs[2]); // 1 2 3
|
|
print("{} {} {} {}\n", B.items[0].x, B.items[0].y, B.items[1].x, B.items[1].y); // 1 2 3 4
|
|
print("{} {} {} {}\n", M.g[0][0], M.g[0][1], M.g[1][0], M.g[1][1]); // 1 2 3 4
|
|
print("{} {} {}\n", D[0], D[1], D[2]); // 7 8 9
|
|
print("{}\n", A!.xs[0]); // 10
|
|
}
|