From 84aac8b6c7721d53a93e636e803e867933ae6e99 Mon Sep 17 00:00:00 2001 From: David Rubin Date: Wed, 29 Jan 2025 18:17:27 -0800 Subject: [PATCH] Type: resolve union tag type before checking for runtime bits --- src/Type.zig | 31 ++++++++++++++++--------------- test/behavior/eval.zig | 8 ++++++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Type.zig b/src/Type.zig index 106aa3d2d8..1d30894aba 100644 --- a/src/Type.zig +++ b/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)) diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 0cafa1f676..0a5f8b531c 100644 --- a/test/behavior/eval.zig +++ b/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