From b97123460acac454d2dad44b75a6a239b7361d95 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 | 23 +++++++++++++---------- test/behavior/eval.zig | 8 ++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/Type.zig b/src/Type.zig index e6fc9c7d6ab0..b2d4e4f53d57 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -597,12 +597,21 @@ 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 => {}, + } + switch (strat) { + .sema => try ty.resolveFields(strat.pt(zcu, tid)), + .eager => assert(union_flags.status.haveFieldTypes()), + .lazy => if (!union_flags.status.haveFieldTypes()) + return error.NeedLazy, + } + switch (union_flags.runtime_tag) { + .none => {}, .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( + // tag_ty should have been resolved above + assert(tag_ty != .none); + if (try Type.fromInterned(tag_ty).hasRuntimeBitsInner( ignore_comptime_only, strat, zcu, @@ -612,12 +621,6 @@ pub fn hasRuntimeBitsInner( } }, } - switch (strat) { - .sema => try ty.resolveFields(strat.pt(zcu, tid)), - .eager => assert(union_flags.status.haveFieldTypes()), - .lazy => if (!union_flags.status.haveFieldTypes()) - return error.NeedLazy, - } 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 4c67d292738b..bdcb3a893865 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