From 27a58ea8832aece227bde9d333970046fb5cfee9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 10 Oct 2026 00:20:25 +0200 Subject: [PATCH] Merge pull request 'InternPool: inherit captures from owner union in generated enums' (#37043) from pentuppup/zig:push-srptskmumtto into master Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37043 Reviewed-by: Andrew Kelley --- src/InternPool.zig | 2 +- src/Sema/type_resolution.zig | 2 +- test/behavior/union.zig | 17 +++++++++++++++++ .../compile_errors/undefined_enum_value.zig | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/undefined_enum_value.zig diff --git a/src/InternPool.zig b/src/InternPool.zig index f97b8c0a8be6f5fddfbaf6508f34519c6bd3a68f..88c454fc2f3b414710886a524c80f4ecc7b09134 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -3851,7 +3851,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { .generated_union_tag => info: { const owner_union: Index = @fromBackingInt(@intCast(extra_items[extra_index])); extra_index += 1; - break :info .{ .none, .empty, owner_union }; + break :info .{ .none, ip.loadUnionType(owner_union).captures, owner_union }; }, _ => |n| info: { const zir_index: TrackedInst.Index = @fromBackingInt(@intCast(extra_items[extra_index])); diff --git a/src/Sema/type_resolution.zig b/src/Sema/type_resolution.zig index a862afa9efa3a524a3b2eaeac8dbef5c2b896f11..a6e6a7609f63a50b18dbc41eeafeb3213f06a823 100644 --- a/src/Sema/type_resolution.zig +++ b/src/Sema/type_resolution.zig @@ -1478,7 +1478,7 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void { }; const uncoerced = try sema.resolveInlineBody(&block, value_body, zir_index); const coerced = try sema.coerce(&block, int_tag_ty, uncoerced, field_val_src); - const val = try sema.resolveConstValue(&block, field_val_src, coerced, null); + const val = try sema.resolveConstDefinedValue(&block, field_val_src, coerced, null); enum_obj.field_values.get(ip)[zir_field.idx] = val.toIntern(); } } diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 298b77f122410c1a94698f48c4eca16b1880ae9e..e0f294557def1e340f6ffc2d7f1f9e8cfbec2856 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -2174,6 +2174,23 @@ test "matching captures causes union equivalence" { try expect(a.u == b.u); } +test "capture used as explicit field value" { + const S = struct { + fn Union(n: u8) type { + return union(enum(u8)) { + a: u32 = n, + b, + }; + } + }; + + comptime assert(@typeInfo(S.Union(0)).@"union".tag_type.? != @typeInfo(S.Union(1)).@"union".tag_type.?); + + const s: S.Union(1) = .{ .a = 0 }; + try expect(@backingInt(s) == 1); + try expect(@backingInt(@as(@typeInfo(S.Union(1)).@"union".tag_type.?, s)) == 1); +} + test "signed enum tag with negative value" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; diff --git a/test/cases/compile_errors/undefined_enum_value.zig b/test/cases/compile_errors/undefined_enum_value.zig new file mode 100644 index 0000000000000000000000000000000000000000..9ed69fa2ebf4171d53d716e9271a32807f10944e --- /dev/null +++ b/test/cases/compile_errors/undefined_enum_value.zig @@ -0,0 +1,19 @@ +const E = enum(u8) { + a = undefined, + b, +}; +const U = union(enum(u8)) { + a: u32 = undefined, + b, +}; +comptime { + _ = E.a; +} +comptime { + _ = U.a; +} + +// error +// +// :2:9: error: use of undefined value here causes illegal behavior +// :6:14: error: use of undefined value here causes illegal behavior -- 2.54.0