authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-18 14:28:15+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-18 14:30:06+00:00
log3b6e5ba4909b7db68bfde7f19bb23a3b9431649b
treee3d312b35bb3af05e89eef1c3f76461556be82c8
parentf7b9f84df2183e01c5f21b7fc5b358b86b73f74d
signaturelock-open Commit is signed but in an unrecognized format.

Sema: don't try to initialize global union pointer at comptime

Resolves: #19832

2 files changed, 23 insertions(+), 0 deletions(-)

src/Sema.zig+4
...@@ -28498,6 +28498,10 @@ fn unionFieldPtr(...@@ -28498,6 +28498,10 @@ fn unionFieldPtr(
28498 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {28498 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {
28499 switch (union_obj.flagsUnordered(ip).layout) {28499 switch (union_obj.flagsUnordered(ip).layout) {
28500 .auto => if (initializing) {28500 .auto => if (initializing) {
28501 if (!sema.isComptimeMutablePtr(union_ptr_val)) {
28502 // The initialization is a runtime operation.
28503 break :ct;
28504 }
28501 // Store to the union to initialize the tag.28505 // Store to the union to initialize the tag.
28502 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28506 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28503 const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);28507 const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
test/behavior/union.zig+19
...@@ -2303,3 +2303,22 @@ test "extern union @FieldType" {...@@ -2303,3 +2303,22 @@ test "extern union @FieldType" {
2303 comptime assert(@FieldType(U, "b") == f64);2303 comptime assert(@FieldType(U, "b") == f64);
2304 comptime assert(@FieldType(U, "c") == *U);2304 comptime assert(@FieldType(U, "c") == *U);
2305}2305}
2306
2307test "assign global tagged union" {
2308 const U = union(enum) {
2309 a: u16,
2310 b: u32,
2311
2312 var global: @This() = undefined;
2313 };
2314
2315 U.global = .{ .a = 123 };
2316 try expect(U.global == .a);
2317 try expect(U.global != .b);
2318 try expect(U.global.a == 123);
2319
2320 U.global = .{ .b = 123456 };
2321 try expect(U.global != .a);
2322 try expect(U.global == .b);
2323 try expect(U.global.b == 123456);
2324}