Commit 84aac8b6c7

David Rubin <daviru007@icloud.com>
2025-01-30 03:17:27
Type: resolve union tag type before checking for runtime bits
1 parent a502301
Changed files (2)
src
test
behavior
src/Type.zig
@@ -604,21 +604,7 @@ pub fn hasRuntimeBitsInner(
                         // and then later if our guess was incorrect, we emit a compile error.
                         if (union_type.assumeRuntimeBitsIfFieldTypesWip(ip)) return true;
                     },
-                    .safety, .tagged => {
-                        const tag_ty = union_type.tagTypeUnordered(ip);
-                        // tag_ty will be `none` if this union's tag type is not resolved yet,
-                        // in which case we want control flow to continue down below.
-                        if (tag_ty != .none and
-                            try Type.fromInterned(tag_ty).hasRuntimeBitsInner(
-                                ignore_comptime_only,
-                                strat,
-                                zcu,
-                                tid,
-                            ))
-                        {
-                            return true;
-                        }
-                    },
+                    .safety, .tagged => {},
                 }
                 switch (strat) {
                     .sema => try ty.resolveFields(strat.pt(zcu, tid)),
@@ -626,6 +612,21 @@ pub fn hasRuntimeBitsInner(
                     .lazy => if (!union_flags.status.haveFieldTypes())
                         return error.NeedLazy,
                 }
+                switch (union_flags.runtime_tag) {
+                    .none => {},
+                    .safety, .tagged => {
+                        const tag_ty = union_type.tagTypeUnordered(ip);
+                        assert(tag_ty != .none); // tag_ty should have been resolved above
+                        if (try Type.fromInterned(tag_ty).hasRuntimeBitsInner(
+                            ignore_comptime_only,
+                            strat,
+                            zcu,
+                            tid,
+                        )) {
+                            return true;
+                        }
+                    },
+                }
                 for (0..union_type.field_types.len) |field_index| {
                     const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);
                     if (try field_ty.hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid))
test/behavior/eval.zig
@@ -1360,6 +1360,14 @@ test "lazy sizeof is resolved in division" {
     try expect(@sizeOf(A) - a == 2);
 }
 
+test "lazy sizeof union tag size in compare" {
+    const A = union(enum) {
+        a: void,
+        b: void,
+    };
+    try expect(@sizeOf(A) == 1);
+}
+
 test "lazy value is resolved as slice operand" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO