diff --git a/src/Sema.zig b/src/Sema.zig index 17a7a8eb1c..ae13298337 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -22106,7 +22106,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil // The fields of the union must match the enum exactly. // Store a copy of the enum field names so we can check for // missing or extraneous fields later. - tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(decl_arena_allocator); + tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(sema.arena); } } else { // If auto_enum_tag is false, this is an untagged union. However, for semantic analysis @@ -22200,20 +22200,6 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil set.putAssumeCapacity(field_name, {}); } - if (tag_ty_field_names) |*names| { - const enum_has_field = names.contains(field_name); - if (!enum_has_field) { - const msg = msg: { - const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(target), field_name }); - errdefer msg.destroy(sema.gpa); - try sema.addDeclaredHereNote(msg, union_obj.tag_ty); - break :msg msg; - }; - return sema.failWithOwnedErrorMsg(block, msg); - } - _ = names.orderedRemove(field_name); - } - const field_ty: Type = if (!has_type) Type.void else if (field_type_ref == .none) @@ -22245,6 +22231,19 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil return sema.failWithOwnedErrorMsg(&block_scope, msg); } + if (tag_ty_field_names) |*names| { + const enum_has_field = names.orderedRemove(field_name); + if (!enum_has_field) { + const msg = msg: { + const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(target), field_name }); + errdefer msg.destroy(sema.gpa); + try sema.addDeclaredHereNote(msg, union_obj.tag_ty); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); + } + } + gop.value_ptr.* = .{ .ty = try field_ty.copy(decl_arena_allocator), .abi_align = 0, diff --git a/test/compile_errors/stage2/union_duplicate_enum_field.zig b/test/compile_errors/stage2/union_duplicate_enum_field.zig new file mode 100644 index 0000000000..9044f9e97e --- /dev/null +++ b/test/compile_errors/stage2/union_duplicate_enum_field.zig @@ -0,0 +1,16 @@ +const E = enum {a, b}; +const U = union(E) { + a: u32, + a: u32, +}; + +export fn foo() void { + var u: U = .{ .a = 123 }; + _ = u; +} + +// union with enum and duplicate fields +// +// :4:5: error: duplicate union field: 'a' +// :3:5: note: other field here +// :2:11: note: union declared here