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