fix(metatype): reject duplicate variant names in define
Two same-named variants in a constructed enum silently succeeded — construction (.a) and matching would ambiguously pick one. defineEnum now bails when a variant name repeats, naming it. The name is dynamic so it sets last_bail_detail directly (bailDetail takes a comptime string); evalComptimeType renders it as a build-gating diagnostic.
This commit is contained in:
@@ -2129,7 +2129,18 @@ pub const Interpreter = struct {
|
||||
if (ev.len != 2) return bailDetail("comptime define(): EnumVariant must have `name` and `payload`");
|
||||
const vname = ev[0].asString(self) orelse return bailDetail("comptime define(): EnumVariant `name` is not a string");
|
||||
const payload_tid = ev[1].asTypeId() orelse return bailDetail("comptime define(): EnumVariant `payload` is not a Type value");
|
||||
fields.append(self.alloc, .{ .name = tbl.internString(vname), .ty = payload_tid }) catch return error.CannotEvalComptime;
|
||||
const vname_id = tbl.internString(vname);
|
||||
// Reject a duplicate variant name loudly — two same-named variants
|
||||
// make construction (`.a`) and matching ambiguous and would silently
|
||||
// pick one. The name is dynamic, so set the bail detail directly
|
||||
// (bailDetail takes a comptime string); evalComptimeType renders it.
|
||||
for (fields.items) |existing| {
|
||||
if (existing.name == vname_id) {
|
||||
last_bail_detail = std.fmt.allocPrint(self.alloc, "comptime define(): duplicate variant name '{s}'", .{vname}) catch "comptime define(): duplicate variant name";
|
||||
return error.CannotEvalComptime;
|
||||
}
|
||||
}
|
||||
fields.append(self.alloc, .{ .name = vname_id, .ty = payload_tid }) catch return error.CannotEvalComptime;
|
||||
}
|
||||
|
||||
// Complete the declared slot IN PLACE: it already has its name + nominal
|
||||
|
||||
Reference in New Issue
Block a user