authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-04-04 16:48:01+02:00
committergravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-04-04 17:03:09+02:00
log94fd914e584d466808f40b9eb5fac49c1cc3c66a
tree2c226d3ef0599d032eb8157a810c305608022510
parent17b804f56b0e75962d3e78a8bade1affa7984b4e

Address review comments


2 files changed, 30 insertions(+), 15 deletions(-)

src/Sema.zig+14-15
......@@ -22106,7 +22106,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2210622106 // The fields of the union must match the enum exactly.
2210722107 // Store a copy of the enum field names so we can check for
2210822108 // missing or extraneous fields later.
22109 tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(decl_arena_allocator);
22109 tag_ty_field_names = try union_obj.tag_ty.enumFields().clone(sema.arena);
2211022110 }
2211122111 } else {
2211222112 // 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
2220022200 set.putAssumeCapacity(field_name, {});
2220122201 }
2220222202
22203 if (tag_ty_field_names) |*names| {
22204 const enum_has_field = names.contains(field_name);
22205 if (!enum_has_field) {
22206 const msg = msg: {
22207 const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(target), field_name });
22208 errdefer msg.destroy(sema.gpa);
22209 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
22210 break :msg msg;
22211 };
22212 return sema.failWithOwnedErrorMsg(block, msg);
22213 }
22214 _ = names.orderedRemove(field_name);
22215 }
22216
2221722203 const field_ty: Type = if (!has_type)
2221822204 Type.void
2221922205 else if (field_type_ref == .none)
......@@ -22245,6 +22231,19 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil
2224522231 return sema.failWithOwnedErrorMsg(&block_scope, msg);
2224622232 }
2224722233
22234 if (tag_ty_field_names) |*names| {
22235 const enum_has_field = names.orderedRemove(field_name);
22236 if (!enum_has_field) {
22237 const msg = msg: {
22238 const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(target), field_name });
22239 errdefer msg.destroy(sema.gpa);
22240 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
22241 break :msg msg;
22242 };
22243 return sema.failWithOwnedErrorMsg(block, msg);
22244 }
22245 }
22246
2224822247 gop.value_ptr.* = .{
2224922248 .ty = try field_ty.copy(decl_arena_allocator),
2225022249 .abi_align = 0,
test/compile_errors/stage2/union_duplicate_enum_field.zig created+16
......@@ -0,0 +1,16 @@
1const E = enum {a, b};
2const U = union(E) {
3 a: u32,
4 a: u32,
5};
6
7export fn foo() void {
8 var u: U = .{ .a = 123 };
9 _ = u;
10}
11
12// union with enum and duplicate fields
13//
14// :4:5: error: duplicate union field: 'a'
15// :3:5: note: other field here
16// :2:11: note: union declared here