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(...@@ -319,7 +319,7 @@ fn reachableExpr(
319) InnerError!Zir.Inst.Ref {319) InnerError!Zir.Inst.Ref {
320 const result_inst = try expr(gz, scope, rl, node);320 const result_inst = try expr(gz, scope, rl, node);
321 if (gz.refIsNoReturn(result_inst)) {321 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{
323 try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}),323 try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}),
324 });324 });
325 }325 }
...@@ -1011,7 +1011,7 @@ fn nosuspendExpr(...@@ -1011,7 +1011,7 @@ fn nosuspendExpr(
1011 const body_node = node_datas[node].lhs;1011 const body_node = node_datas[node].lhs;
1012 assert(body_node != 0);1012 assert(body_node != 0);
1013 if (gz.nosuspend_node != 0) {1013 if (gz.nosuspend_node != 0) {
1014 return astgen.failNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{1014 try astgen.appendErrorNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{
1015 try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}),1015 try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}),
1016 });1016 });
1017 }1017 }
...@@ -1923,7 +1923,7 @@ fn labeledBlockExpr(...@@ -1923,7 +1923,7 @@ fn labeledBlockExpr(
1923 try blockExprStmts(&block_scope, &block_scope.base, statements);1923 try blockExprStmts(&block_scope, &block_scope.base, statements);
19241924
1925 if (!block_scope.label.?.used) {1925 if (!block_scope.label.?.used) {
1926 return astgen.failTok(label_token, "unused block label", .{});1926 try astgen.appendErrorTok(label_token, "unused block label", .{});
1927 }1927 }
19281928
1929 const zir_tags = gz.astgen.instructions.items(.tag);1929 const zir_tags = gz.astgen.instructions.items(.tag);
...@@ -1975,7 +1975,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod...@@ -1975,7 +1975,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
1975 var scope = parent_scope;1975 var scope = parent_scope;
1976 for (statements) |statement| {1976 for (statements) |statement| {
1977 if (noreturn_src_node != 0) {1977 if (noreturn_src_node != 0) {
1978 return astgen.failNodeNotes(1978 try astgen.appendErrorNodeNotes(
1979 statement,1979 statement,
1980 "unreachable code",1980 "unreachable code",
1981 .{},1981 .{},
...@@ -2469,14 +2469,14 @@ fn checkUsed(...@@ -2469,14 +2469,14 @@ fn checkUsed(
2469 .local_val => {2469 .local_val => {
2470 const s = scope.cast(Scope.LocalVal).?;2470 const s = scope.cast(Scope.LocalVal).?;
2471 if (!s.used) {2471 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)});
2473 }2473 }
2474 scope = s.parent;2474 scope = s.parent;
2475 },2475 },
2476 .local_ptr => {2476 .local_ptr => {
2477 const s = scope.cast(Scope.LocalPtr).?;2477 const s = scope.cast(Scope.LocalPtr).?;
2478 if (!s.used) {2478 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)});
2480 }2480 }
2481 scope = s.parent;2481 scope = s.parent;
2482 },2482 },
...@@ -2555,7 +2555,7 @@ fn varDecl(...@@ -2555,7 +2555,7 @@ fn varDecl(
2555 switch (token_tags[var_decl.ast.mut_token]) {2555 switch (token_tags[var_decl.ast.mut_token]) {
2556 .keyword_const => {2556 .keyword_const => {
2557 if (var_decl.comptime_token) |comptime_token| {2557 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'", .{});
2559 }2559 }
25602560
2561 // Depending on the type of AST the initialization expression is, we may need an lvalue2561 // Depending on the type of AST the initialization expression is, we may need an lvalue
...@@ -4183,10 +4183,10 @@ fn containerDecl(...@@ -4183,10 +4183,10 @@ fn containerDecl(
4183 // One can construct an enum with no tags, and it functions the same as `noreturn`. But4183 // One can construct an enum with no tags, and it functions the same as `noreturn`. But
4184 // this is only useful for generic code; when explicitly using `enum {}` syntax, there4184 // this is only useful for generic code; when explicitly using `enum {}` syntax, there
4185 // must be at least one tag.4185 // 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", .{});
4187 }4187 }
4188 if (counts.nonexhaustive_node != 0 and container_decl.ast.arg == 0) {4188 if (counts.nonexhaustive_node != 0 and container_decl.ast.arg == 0) {
4189 return astgen.failNodeNotes(4189 try astgen.appendErrorNodeNotes(
4190 node,4190 node,
4191 "non-exhaustive enum missing integer tag type",4191 "non-exhaustive enum missing integer tag type",
4192 .{},4192 .{},
...@@ -5338,7 +5338,7 @@ fn whileExpr(...@@ -5338,7 +5338,7 @@ fn whileExpr(
53385338
5339 if (loop_scope.label) |some| {5339 if (loop_scope.label) |some| {
5340 if (!some.used) {5340 if (!some.used) {
5341 return astgen.failTok(some.token, "unused while loop label", .{});5341 try astgen.appendErrorTok(some.token, "unused while loop label", .{});
5342 }5342 }
5343 }5343 }
5344 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";5344 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
...@@ -5526,7 +5526,7 @@ fn forExpr(...@@ -5526,7 +5526,7 @@ fn forExpr(
55265526
5527 if (loop_scope.label) |some| {5527 if (loop_scope.label) |some| {
5528 if (!some.used) {5528 if (!some.used) {
5529 return astgen.failTok(some.token, "unused for loop label", .{});5529 try astgen.appendErrorTok(some.token, "unused for loop label", .{});
5530 }5530 }
5531 }5531 }
5532 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";5532 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
...@@ -8521,13 +8521,22 @@ fn failNode(...@@ -8521,13 +8521,22 @@ fn failNode(
8521 return astgen.failNodeNotes(node, format, args, &[0]u32{});8521 return astgen.failNodeNotes(node, format, args, &[0]u32{});
8522}8522}
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(
8525 astgen: *AstGen,8534 astgen: *AstGen,
8526 node: Ast.Node.Index,8535 node: Ast.Node.Index,
8527 comptime format: []const u8,8536 comptime format: []const u8,
8528 args: anytype,8537 args: anytype,
8529 notes: []const u32,8538 notes: []const u32,
8530) InnerError {8539) Allocator.Error!void {
8531 @setCold(true);8540 @setCold(true);
8532 const string_bytes = &astgen.string_bytes;8541 const string_bytes = &astgen.string_bytes;
8533 const msg = @intCast(u32, string_bytes.items.len);8542 const msg = @intCast(u32, string_bytes.items.len);
...@@ -8546,6 +8555,16 @@ fn failNodeNotes(...@@ -8546,6 +8555,16 @@ fn failNodeNotes(
8546 .byte_offset = 0,8555 .byte_offset = 0,
8547 .notes = notes_index,8556 .notes = notes_index,
8548 });8557 });
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);
8549 return error.AnalysisFail;8568 return error.AnalysisFail;
8550}8569}
85518570
...@@ -8558,6 +8577,15 @@ fn failTok(...@@ -8558,6 +8577,15 @@ fn failTok(
8558 return astgen.failTokNotes(token, format, args, &[0]u32{});8577 return astgen.failTokNotes(token, format, args, &[0]u32{});
8559}8578}
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
8561fn failTokNotes(8589fn failTokNotes(
8562 astgen: *AstGen,8590 astgen: *AstGen,
8563 token: Ast.TokenIndex,8591 token: Ast.TokenIndex,
...@@ -8565,6 +8593,17 @@ fn failTokNotes(...@@ -8565,6 +8593,17 @@ fn failTokNotes(
8565 args: anytype,8593 args: anytype,
8566 notes: []const u32,8594 notes: []const u32,
8567) InnerError {8595) 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 {
8568 @setCold(true);8607 @setCold(true);
8569 const string_bytes = &astgen.string_bytes;8608 const string_bytes = &astgen.string_bytes;
8570 const msg = @intCast(u32, string_bytes.items.len);8609 const msg = @intCast(u32, string_bytes.items.len);
...@@ -8583,7 +8622,6 @@ fn failTokNotes(...@@ -8583,7 +8622,6 @@ fn failTokNotes(
8583 .byte_offset = 0,8622 .byte_offset = 0,
8584 .notes = notes_index,8623 .notes = notes_index,
8585 });8624 });
8586 return error.AnalysisFail;
8587}8625}
85888626
8589/// Same as `fail`, except given an absolute byte offset.8627/// Same as `fail`, except given an absolute byte offset.
...@@ -8594,6 +8632,17 @@ fn failOff(...@@ -8594,6 +8632,17 @@ fn failOff(
8594 comptime format: []const u8,8632 comptime format: []const u8,
8595 args: anytype,8633 args: anytype,
8596) InnerError {8634) 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 {
8597 @setCold(true);8646 @setCold(true);
8598 const string_bytes = &astgen.string_bytes;8647 const string_bytes = &astgen.string_bytes;
8599 const msg = @intCast(u32, string_bytes.items.len);8648 const msg = @intCast(u32, string_bytes.items.len);
...@@ -8605,7 +8654,6 @@ fn failOff(...@@ -8605,7 +8654,6 @@ fn failOff(
8605 .byte_offset = byte_offset,8654 .byte_offset = byte_offset,
8606 .notes = 0,8655 .notes = 0,
8607 });8656 });
8608 return error.AnalysisFail;
8609}8657}
86108658
8611fn errNoteTok(8659fn errNoteTok(