stage2: move duplicate error set check to AstGen

This commit is contained in:
Mitchell Hashimoto 2022-03-15 14:33:23 -07:00 committed by Andrew Kelley
parent 9a6fa67cbc
commit 394252c9db
3 changed files with 26 additions and 8 deletions

View file

@ -4723,14 +4723,36 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len); const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len);
var fields_len: usize = 0; var fields_len: usize = 0;
{ {
var idents: std.AutoHashMapUnmanaged(u32, Ast.TokenIndex) = .{};
defer idents.deinit(gpa);
const error_token = main_tokens[node]; const error_token = main_tokens[node];
var tok_i = error_token + 2; var tok_i = error_token + 2;
while (true) : (tok_i += 1) { while (true) : (tok_i += 1) {
switch (token_tags[tok_i]) { switch (token_tags[tok_i]) {
.doc_comment, .comma => {}, .doc_comment, .comma => {},
.identifier => { .identifier => {
try astgen.extra.ensureUnusedCapacity(gpa, 2);
const str_index = try astgen.identAsString(tok_i); const str_index = try astgen.identAsString(tok_i);
const gop = try idents.getOrPut(gpa, str_index);
if (gop.found_existing) {
const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(str_index)));
defer gpa.free(name);
return astgen.failTokNotes(
tok_i,
"duplicate error set field '{s}'",
.{name},
&[_]u32{
try astgen.errNoteTok(
gop.value_ptr.*,
"previous declaration here",
.{},
),
},
);
}
gop.value_ptr.* = tok_i;
try astgen.extra.ensureUnusedCapacity(gpa, 2);
astgen.extra.appendAssumeCapacity(str_index); astgen.extra.appendAssumeCapacity(str_index);
const doc_comment_index = try astgen.docCommentAsString(tok_i); const doc_comment_index = try astgen.docCommentAsString(tok_i);
astgen.extra.appendAssumeCapacity(doc_comment_index); astgen.extra.appendAssumeCapacity(doc_comment_index);

View file

@ -2220,12 +2220,8 @@ fn zirErrorSetDecl(
while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
const str_index = sema.code.extra[extra_index]; const str_index = sema.code.extra[extra_index];
const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index)); const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index));
// TODO: This check should be performed in AstGen instead.
const result = names.getOrPutAssumeCapacity(name); const result = names.getOrPutAssumeCapacity(name);
if (result.found_existing) { assert(!result.found_existing); // verified in AstGen
return sema.fail(block, src, "duplicate error set field {s}", .{name});
}
} }
// names must be sorted. // names must be sorted.

View file

@ -4487,8 +4487,8 @@ pub fn addCases(ctx: *TestContext) !void {
\\ _ = a; \\ _ = a;
\\} \\}
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:3:5: error: duplicate error: 'Bar'", "tmp.zig:3:5: error: duplicate error set field 'Bar'",
"tmp.zig:2:5: note: other error here", "tmp.zig:2:5: note: previous declaration here",
}); });
ctx.objErrStage1("cast negative integer literal to usize", ctx.objErrStage1("cast negative integer literal to usize",