authorgravatar for jarred@jarredsumner.comJarred Sumner <jarred@jarredsumner.com> 2021-12-30 16:29:53-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-30 22:45:43-05:00
log2d9508780a3578ecddb4948eb459768ad5bf8720
tree322014c6919e4a8f894a5bbc2bd69542550f6073
parent4645ec89f7e858121a22e3d6107cfa74151437a3

For unused references & redundant keywords, append the compiler error but continue running AstGen


1 files changed, 63 insertions(+), 15 deletions(-)

src/AstGen.zig+63-15
......@@ -319,7 +319,7 @@ fn reachableExpr(
319319) InnerError!Zir.Inst.Ref {
320320 const result_inst = try expr(gz, scope, rl, node);
321321 if (gz.refIsNoReturn(result_inst)) {
322 return gz.astgen.failNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{
322 try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{
323323 try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}),
324324 });
325325 }
......@@ -1011,7 +1011,7 @@ fn nosuspendExpr(
10111011 const body_node = node_datas[node].lhs;
10121012 assert(body_node != 0);
10131013 if (gz.nosuspend_node != 0) {
1014 return astgen.failNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{
1014 try astgen.appendErrorNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{
10151015 try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}),
10161016 });
10171017 }
......@@ -1923,7 +1923,7 @@ fn labeledBlockExpr(
19231923 try blockExprStmts(&block_scope, &block_scope.base, statements);
19241924
19251925 if (!block_scope.label.?.used) {
1926 return astgen.failTok(label_token, "unused block label", .{});
1926 try astgen.appendErrorTok(label_token, "unused block label", .{});
19271927 }
19281928
19291929 const zir_tags = gz.astgen.instructions.items(.tag);
......@@ -1975,7 +1975,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
19751975 var scope = parent_scope;
19761976 for (statements) |statement| {
19771977 if (noreturn_src_node != 0) {
1978 return astgen.failNodeNotes(
1978 try astgen.appendErrorNodeNotes(
19791979 statement,
19801980 "unreachable code",
19811981 .{},
......@@ -2469,14 +2469,14 @@ fn checkUsed(
24692469 .local_val => {
24702470 const s = scope.cast(Scope.LocalVal).?;
24712471 if (!s.used) {
2472 return astgen.failTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
2472 try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
24732473 }
24742474 scope = s.parent;
24752475 },
24762476 .local_ptr => {
24772477 const s = scope.cast(Scope.LocalPtr).?;
24782478 if (!s.used) {
2479 return astgen.failTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
2479 try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
24802480 }
24812481 scope = s.parent;
24822482 },
......@@ -2555,7 +2555,7 @@ fn varDecl(
25552555 switch (token_tags[var_decl.ast.mut_token]) {
25562556 .keyword_const => {
25572557 if (var_decl.comptime_token) |comptime_token| {
2558 return astgen.failTok(comptime_token, "'comptime const' is redundant; instead wrap the initialization expression with 'comptime'", .{});
2558 try astgen.appendErrorTok(comptime_token, "'comptime const' is redundant; instead wrap the initialization expression with 'comptime'", .{});
25592559 }
25602560
25612561 // Depending on the type of AST the initialization expression is, we may need an lvalue
......@@ -4183,10 +4183,10 @@ fn containerDecl(
41834183 // One can construct an enum with no tags, and it functions the same as `noreturn`. But
41844184 // this is only useful for generic code; when explicitly using `enum {}` syntax, there
41854185 // must be at least one tag.
4186 return astgen.failNode(node, "enum declarations must have at least one tag", .{});
4186 try astgen.appendErrorNode(node, "enum declarations must have at least one tag", .{});
41874187 }
41884188 if (counts.nonexhaustive_node != 0 and container_decl.ast.arg == 0) {
4189 return astgen.failNodeNotes(
4189 try astgen.appendErrorNodeNotes(
41904190 node,
41914191 "non-exhaustive enum missing integer tag type",
41924192 .{},
......@@ -5338,7 +5338,7 @@ fn whileExpr(
53385338
53395339 if (loop_scope.label) |some| {
53405340 if (!some.used) {
5341 return astgen.failTok(some.token, "unused while loop label", .{});
5341 try astgen.appendErrorTok(some.token, "unused while loop label", .{});
53425342 }
53435343 }
53445344 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
......@@ -5526,7 +5526,7 @@ fn forExpr(
55265526
55275527 if (loop_scope.label) |some| {
55285528 if (!some.used) {
5529 return astgen.failTok(some.token, "unused for loop label", .{});
5529 try astgen.appendErrorTok(some.token, "unused for loop label", .{});
55305530 }
55315531 }
55325532 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
......@@ -8521,13 +8521,22 @@ fn failNode(
85218521 return astgen.failNodeNotes(node, format, args, &[0]u32{});
85228522}
85238523
8524fn failNodeNotes(
8524fn appendErrorNode(
8525 astgen: *AstGen,
8526 node: Ast.Node.Index,
8527 comptime format: []const u8,
8528 args: anytype,
8529) Allocator.Error!void {
8530 try astgen.appendErrorNodeNotes(node, format, args, &[0]u32{});
8531}
8532
8533fn appendErrorNodeNotes(
85258534 astgen: *AstGen,
85268535 node: Ast.Node.Index,
85278536 comptime format: []const u8,
85288537 args: anytype,
85298538 notes: []const u32,
8530) InnerError {
8539) Allocator.Error!void {
85318540 @setCold(true);
85328541 const string_bytes = &astgen.string_bytes;
85338542 const msg = @intCast(u32, string_bytes.items.len);
......@@ -8546,6 +8555,16 @@ fn failNodeNotes(
85468555 .byte_offset = 0,
85478556 .notes = notes_index,
85488557 });
8558}
8559
8560fn failNodeNotes(
8561 astgen: *AstGen,
8562 node: Ast.Node.Index,
8563 comptime format: []const u8,
8564 args: anytype,
8565 notes: []const u32,
8566) InnerError {
8567 try appendErrorNodeNotes(astgen, node, format, args, notes);
85498568 return error.AnalysisFail;
85508569}
85518570
......@@ -8558,6 +8577,15 @@ fn failTok(
85588577 return astgen.failTokNotes(token, format, args, &[0]u32{});
85598578}
85608579
8580fn appendErrorTok(
8581 astgen: *AstGen,
8582 token: Ast.TokenIndex,
8583 comptime format: []const u8,
8584 args: anytype,
8585) !void {
8586 try astgen.appendErrorTokNotes(token, format, args, &[0]u32{});
8587}
8588
85618589fn failTokNotes(
85628590 astgen: *AstGen,
85638591 token: Ast.TokenIndex,
......@@ -8565,6 +8593,17 @@ fn failTokNotes(
85658593 args: anytype,
85668594 notes: []const u32,
85678595) InnerError {
8596 try appendErrorTokNotes(astgen, token, format, args, notes);
8597 return error.AnalysisFail;
8598}
8599
8600fn appendErrorTokNotes(
8601 astgen: *AstGen,
8602 token: Ast.TokenIndex,
8603 comptime format: []const u8,
8604 args: anytype,
8605 notes: []const u32,
8606) !void {
85688607 @setCold(true);
85698608 const string_bytes = &astgen.string_bytes;
85708609 const msg = @intCast(u32, string_bytes.items.len);
......@@ -8583,7 +8622,6 @@ fn failTokNotes(
85838622 .byte_offset = 0,
85848623 .notes = notes_index,
85858624 });
8586 return error.AnalysisFail;
85878625}
85888626
85898627/// Same as `fail`, except given an absolute byte offset.
......@@ -8594,6 +8632,17 @@ fn failOff(
85948632 comptime format: []const u8,
85958633 args: anytype,
85968634) InnerError {
8635 try appendErrorOff(astgen, token, byte_offset, format, args);
8636 return error.AnalysisFail;
8637}
8638
8639fn appendErrorOff(
8640 astgen: *AstGen,
8641 token: Ast.TokenIndex,
8642 byte_offset: u32,
8643 comptime format: []const u8,
8644 args: anytype,
8645) Allocator.Error!void {
85978646 @setCold(true);
85988647 const string_bytes = &astgen.string_bytes;
85998648 const msg = @intCast(u32, string_bytes.items.len);
......@@ -8605,7 +8654,6 @@ fn failOff(
86058654 .byte_offset = byte_offset,
86068655 .notes = 0,
86078656 });
8608 return error.AnalysisFail;
86098657}
86108658
86118659fn errNoteTok(