Sema: remove redundant comptime-known initializer tracking

This logic predates certain Sema enhancements whose behavior it
essentially tries to emulate in one specific case in a problematic way.
In particular, this logic handled initializing comptime-known `const`s
through RLS, which was reworked a few years back in 644041b to not rely
on this logic, and catching runtime fields in comptime-only
initializers, which has since been *correctly* fixed with better checks
in `Sema.storePtr2`. That made the highly complex logic in
`validateStructInit`, `validateUnionInit`, and `zirValidatePtrArrayInit`
entirely redundant. Worse, it was also causing some tracked bugs, as
well as a bug which I have identified and fixed in this PR (a
corresponding behavior test is added).

This commit simplifies union initialization by bringing the runtime
logic more in line with the comptime logic: the tag is now always
populated by `Sema.unionFieldPtr` based on `initializing`, where this
previously happened only in the comptime case (with `validateUnionInit`
instead handling it in the runtime case). Notably, this means that
backends are now able to consider getting a pointer to an inactive union
field as Illegal Behavior, because the `set_union_tag` instruction now
appears *before* the `struct_field_ptr` instruction as you would
probably expect it to.

Resolves: #24520
Resolves: #24595
This commit is contained in:
mlugg
2025-07-29 10:04:15 +01:00
parent 3fbdd58a87
commit a8888afcc0
3 changed files with 105 additions and 544 deletions

View File

@@ -540,7 +540,6 @@ test "sentinel element count towards the ABI size calculation" {
}
test "zero-sized array with recursive type definition" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
@@ -1098,3 +1097,16 @@ test "initialize pointer to anyopaque with reference to empty array initializer"
// We can't check the value, but it's zero-bit, so the type matching is good enough.
comptime assert(@TypeOf(loaded) == @TypeOf(.{}));
}
test "sentinel of runtime-known array initialization is populated" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
var rt: u32 = undefined;
rt = 42;
const arr: [1:123]u32 = .{rt};
const elems: [*]const u32 = &arr;
try expect(elems[0] == 42);
try expect(elems[1] == 123);
}