From d03668ecb6f06844febb33b8edecb8995fe308d1 Mon Sep 17 00:00:00 2001 From: Gabriel Uehlein Date: Thu, 26 Jun 2025 09:06:22 -0400 Subject: [PATCH 1/3] Dwarf: set alignment to 1 for noreturn types in untagged unions Fixes #24265 --- src/link/Dwarf.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 605d1d23a491..d084641af6a0 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -3032,7 +3032,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]); try wip_nav.refType(field_type); try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); + if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?); } try uleb128(diw, @intFromEnum(AbbrevCode.null)); break :tag .done; From f90bb09b11277bd5d28e4e6430656855f362ac90 Mon Sep 17 00:00:00 2001 From: Gabriel Uehlein Date: Fri, 27 Jun 2025 07:22:31 -0400 Subject: [PATCH 2/3] Sema: fail if analyzing a nonempty union with an empty enum tag Fixes #24262; as a bonus, adresses a potential issue I introduced in #21665 --- src/Sema.zig | 9 +++++++-- .../empty_enum_as_nonempty_union_tag_type.zig | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig diff --git a/src/Sema.zig b/src/Sema.zig index 20be9e705274..01b5e2b98ccc 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -29442,8 +29442,6 @@ fn coerceExtra( if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty); } - if (!opts.report_err) return error.NotCoercible; - if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) { const msg = msg: { const msg = try sema.errMsg(inst_src, "function declared 'noreturn' returns", .{}); @@ -29459,6 +29457,8 @@ fn coerceExtra( return sema.failWithOwnedErrorMsg(block, msg); } + if (!opts.report_err) return error.NotCoercible; + const msg = msg: { const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) }); errdefer msg.destroy(sema.gpa); @@ -36141,6 +36141,11 @@ fn unionFields( }; return sema.failWithOwnedErrorMsg(&block_scope, msg); } + } else if (!small.auto_enum_tag and tag_type_ref != .none) { + const tag_ty = union_type.tagTypeUnordered(ip); + return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{ + field_name.fmt(ip), Type.fromInterned(tag_ty).fmt(pt), + }); } if (field_ty.zigTypeTag(zcu) == .@"opaque") { diff --git a/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig b/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig new file mode 100644 index 000000000000..74c4ac87040e --- /dev/null +++ b/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig @@ -0,0 +1,16 @@ +const E = enum {}; +const U = union(E) { + one, + two, +}; + +pub fn main() void { + _ = U.one; +} + +// error +// backend=stage2 +// target=native +// +// :4:5: error: no field named 'one' in enum 'tmp.E' +// :2:11: note: enum declared here From 46db59bbe8fbbd610aaf874741feff682583edf2 Mon Sep 17 00:00:00 2001 From: Gabriel Uehlein Date: Fri, 27 Jun 2025 10:02:09 -0400 Subject: [PATCH 3/3] decrement line number in expected test output guess I'm bad at math --- .../compile_errors/empty_enum_as_nonempty_union_tag_type.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig b/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig index 74c4ac87040e..6942d801c3e2 100644 --- a/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig +++ b/test/cases/compile_errors/empty_enum_as_nonempty_union_tag_type.zig @@ -12,5 +12,5 @@ pub fn main() void { // backend=stage2 // target=native // -// :4:5: error: no field named 'one' in enum 'tmp.E' -// :2:11: note: enum declared here +// :3:5: error: no field named 'one' in enum 'tmp.E' +// :1:11: note: enum declared here