mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Sema: detect duplicate enum tag values
This commit is contained in:
parent
19dd6de180
commit
f094c4bce5
3 changed files with 64 additions and 8 deletions
30
src/Sema.zig
30
src/Sema.zig
|
|
@ -18264,9 +18264,9 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
});
|
});
|
||||||
|
|
||||||
var i: usize = 0;
|
var field_i: usize = 0;
|
||||||
while (i < fields_len) : (i += 1) {
|
while (field_i < fields_len) : (field_i += 1) {
|
||||||
const elem_val = try fields_val.elemValue(sema.mod, sema.arena, i);
|
const elem_val = try fields_val.elemValue(sema.mod, sema.arena, field_i);
|
||||||
const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;
|
const field_struct_val: []const Value = elem_val.castTag(.aggregate).?.data;
|
||||||
// TODO use reflection instead of magic numbers here
|
// TODO use reflection instead of magic numbers here
|
||||||
// name: []const u8
|
// name: []const u8
|
||||||
|
|
@ -18289,17 +18289,31 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
|
const gop_field = enum_obj.fields.getOrPutAssumeCapacity(field_name);
|
||||||
if (gop.found_existing) {
|
if (gop_field.found_existing) {
|
||||||
// TODO: better source location
|
const msg = msg: {
|
||||||
return sema.fail(block, src, "duplicate enum tag {s}", .{field_name});
|
const msg = try sema.errMsg(block, src, "duplicate enum field '{s}'", .{field_name});
|
||||||
|
errdefer msg.destroy(gpa);
|
||||||
|
try sema.errNote(block, src, msg, "other field here", .{});
|
||||||
|
break :msg msg;
|
||||||
|
};
|
||||||
|
return sema.failWithOwnedErrorMsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
|
const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
|
||||||
enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
|
const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{
|
||||||
.ty = enum_obj.tag_ty,
|
.ty = enum_obj.tag_ty,
|
||||||
.mod = mod,
|
.mod = mod,
|
||||||
});
|
});
|
||||||
|
if (gop_val.found_existing) {
|
||||||
|
const msg = msg: {
|
||||||
|
const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
|
||||||
|
errdefer msg.destroy(gpa);
|
||||||
|
try sema.errNote(block, src, msg, "other enum tag value here", .{});
|
||||||
|
break :msg msg;
|
||||||
|
};
|
||||||
|
return sema.failWithOwnedErrorMsg(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try new_decl.finalizeNewArena(&new_decl_arena);
|
try new_decl.finalizeNewArena(&new_decl_arena);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
export fn entry() void {
|
||||||
|
_ = @Type(.{
|
||||||
|
.Enum = .{
|
||||||
|
.layout = .Auto,
|
||||||
|
.tag_type = u32,
|
||||||
|
.fields = &.{
|
||||||
|
.{ .name = "A", .value = 0 },
|
||||||
|
.{ .name = "A", .value = 1 },
|
||||||
|
},
|
||||||
|
.decls = &.{},
|
||||||
|
.is_exhaustive = false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:9: error: duplicate enum field 'A'
|
||||||
|
// :2:9: note: other field here
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
export fn entry() void {
|
||||||
|
_ = @Type(.{
|
||||||
|
.Enum = .{
|
||||||
|
.layout = .Auto,
|
||||||
|
.tag_type = u32,
|
||||||
|
.fields = &.{
|
||||||
|
.{ .name = "A", .value = 10 },
|
||||||
|
.{ .name = "B", .value = 10 },
|
||||||
|
},
|
||||||
|
.decls = &.{},
|
||||||
|
.is_exhaustive = false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:9: error: enum tag value 10 already taken
|
||||||
|
// :2:9: note: other enum tag value here
|
||||||
Loading…
Add table
Reference in a new issue