authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-15 14:33:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-16 01:41:22-04:00
log394252c9db6ae82a2cddf49b986a4e6b72cadb70
treedc76189c8da1677bbed1614a5680564006fc96b4
parent9a6fa67cbc7e5771f3770c0cb7d6d2c6bafb6957

stage2: move duplicate error set check to AstGen


3 files changed, 26 insertions(+), 8 deletions(-)

src/AstGen.zig+23-1
......@@ -4723,14 +4723,36 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
47234723 const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len);
47244724 var fields_len: usize = 0;
47254725 {
4726 var idents: std.AutoHashMapUnmanaged(u32, Ast.TokenIndex) = .{};
4727 defer idents.deinit(gpa);
4728
47264729 const error_token = main_tokens[node];
47274730 var tok_i = error_token + 2;
47284731 while (true) : (tok_i += 1) {
47294732 switch (token_tags[tok_i]) {
47304733 .doc_comment, .comma => {},
47314734 .identifier => {
4732 try astgen.extra.ensureUnusedCapacity(gpa, 2);
47334735 const str_index = try astgen.identAsString(tok_i);
4736 const gop = try idents.getOrPut(gpa, str_index);
4737 if (gop.found_existing) {
4738 const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(str_index)));
4739 defer gpa.free(name);
4740 return astgen.failTokNotes(
4741 tok_i,
4742 "duplicate error set field '{s}'",
4743 .{name},
4744 &[_]u32{
4745 try astgen.errNoteTok(
4746 gop.value_ptr.*,
4747 "previous declaration here",
4748 .{},
4749 ),
4750 },
4751 );
4752 }
4753 gop.value_ptr.* = tok_i;
4754
4755 try astgen.extra.ensureUnusedCapacity(gpa, 2);
47344756 astgen.extra.appendAssumeCapacity(str_index);
47354757 const doc_comment_index = try astgen.docCommentAsString(tok_i);
47364758 astgen.extra.appendAssumeCapacity(doc_comment_index);
src/Sema.zig+1-5
......@@ -2220,12 +2220,8 @@ fn zirErrorSetDecl(
22202220 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
22212221 const str_index = sema.code.extra[extra_index];
22222222 const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index));
2223
2224 // TODO: This check should be performed in AstGen instead.
22252223 const result = names.getOrPutAssumeCapacity(name);
2226 if (result.found_existing) {
2227 return sema.fail(block, src, "duplicate error set field {s}", .{name});
2228 }
2224 assert(!result.found_existing); // verified in AstGen
22292225 }
22302226
22312227 // names must be sorted.
test/compile_errors.zig+2-2
......@@ -4487,8 +4487,8 @@ pub fn addCases(ctx: *TestContext) !void {
44874487 \\ _ = a;
44884488 \\}
44894489 , &[_][]const u8{
4490 "tmp.zig:3:5: error: duplicate error: 'Bar'",
4491 "tmp.zig:2:5: note: other error here",
4490 "tmp.zig:3:5: error: duplicate error set field 'Bar'",
4491 "tmp.zig:2:5: note: previous declaration here",
44924492 });
44934493
44944494 ctx.objErrStage1("cast negative integer literal to usize",