aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-01-18 14:28:15 +0000
committermlugg <mlugg@mlugg.co.uk>2025-01-18 14:30:06 +0000
commit3b6e5ba4909b7db68bfde7f19bb23a3b9431649b (patch)
treee3d312b35bb3af05e89eef1c3f76461556be82c8
parentf7b9f84df2183e01c5f21b7fc5b358b86b73f74d (diff)
downloadzig-3b6e5ba4909b7db68bfde7f19bb23a3b9431649b.tar.gz
zig-3b6e5ba4909b7db68bfde7f19bb23a3b9431649b.zip
Sema: don't try to initialize global union pointer at comptime
Resolves: #19832
-rw-r--r--src/Sema.zig4
-rw-r--r--test/behavior/union.zig19
2 files changed, 23 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 153a2aad72..2b9fa82ce8 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -28498,6 +28498,10 @@ fn unionFieldPtr(
if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {
switch (union_obj.flagsUnordered(ip).layout) {
.auto => if (initializing) {
+ if (!sema.isComptimeMutablePtr(union_ptr_val)) {
+ // The initialization is a runtime operation.
+ break :ct;
+ }
// Store to the union to initialize the tag.
const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
diff --git a/test/behavior/union.zig b/test/behavior/union.zig
index ef269c2688..364a83814a 100644
--- a/test/behavior/union.zig
+++ b/test/behavior/union.zig
@@ -2303,3 +2303,22 @@ test "extern union @FieldType" {
comptime assert(@FieldType(U, "b") == f64);
comptime assert(@FieldType(U, "c") == *U);
}
+
+test "assign global tagged union" {
+ const U = union(enum) {
+ a: u16,
+ b: u32,
+
+ var global: @This() = undefined;
+ };
+
+ U.global = .{ .a = 123 };
+ try expect(U.global == .a);
+ try expect(U.global != .b);
+ try expect(U.global.a == 123);
+
+ U.global = .{ .b = 123456 };
+ try expect(U.global != .a);
+ try expect(U.global == .b);
+ try expect(U.global.b == 123456);
+}