authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-16 13:06:11+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 14:23:35+02:00
log9c36cf92f009eda14cb773e89148547dadb137c6
tree7be6ab7d21cd37709e3ed877264b9a4b135171d3
parent5283a52af565521094bcd1186efc179b4be7ee8c

parser: make some errors point to end of previous token

For some errors if the found token is not on the same line as the previous token, point to the end of the previous token. This usually results in more helpful errors.

8 files changed, 148 insertions(+), 169 deletions(-)

lib/std/zig/Ast.zig+30-40
......@@ -66,20 +66,11 @@ pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8)) RenderError!void
6666
6767/// Returns an extra offset for column and byte offset of errors that
6868/// should point after the token in the error message.
69pub fn errorOffset(tree: Ast, error_tag: Error.Tag, token: TokenIndex) u32 {
70 return switch (error_tag) {
71 .expected_semi_after_decl,
72 .expected_semi_after_stmt,
73 .expected_comma_after_field,
74 .expected_comma_after_arg,
75 .expected_comma_after_param,
76 .expected_comma_after_initializer,
77 .expected_comma_after_switch_prong,
78 .expected_semi_or_else,
79 .expected_semi_or_lbrace,
80 => @intCast(u32, tree.tokenSlice(token).len),
81 else => 0,
82 };
69pub fn errorOffset(tree: Ast, parse_error: Error) u32 {
70 return if (parse_error.token_is_prev)
71 @intCast(u32, tree.tokenSlice(parse_error.token).len)
72 else
73 0;
8374}
8475
8576pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location {
......@@ -162,22 +153,22 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
162153 },
163154 .expected_block => {
164155 return stream.print("expected block or field, found '{s}'", .{
165 token_tags[parse_error.token].symbol(),
156 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
166157 });
167158 },
168159 .expected_block_or_assignment => {
169160 return stream.print("expected block or assignment, found '{s}'", .{
170 token_tags[parse_error.token].symbol(),
161 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
171162 });
172163 },
173164 .expected_block_or_expr => {
174165 return stream.print("expected block or expression, found '{s}'", .{
175 token_tags[parse_error.token].symbol(),
166 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
176167 });
177168 },
178169 .expected_block_or_field => {
179170 return stream.print("expected block or field, found '{s}'", .{
180 token_tags[parse_error.token].symbol(),
171 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
181172 });
182173 },
183174 .expected_container_members => {
......@@ -187,42 +178,42 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
187178 },
188179 .expected_expr => {
189180 return stream.print("expected expression, found '{s}'", .{
190 token_tags[parse_error.token].symbol(),
181 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
191182 });
192183 },
193184 .expected_expr_or_assignment => {
194185 return stream.print("expected expression or assignment, found '{s}'", .{
195 token_tags[parse_error.token].symbol(),
186 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
196187 });
197188 },
198189 .expected_fn => {
199190 return stream.print("expected function, found '{s}'", .{
200 token_tags[parse_error.token].symbol(),
191 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
201192 });
202193 },
203194 .expected_inlinable => {
204195 return stream.print("expected 'while' or 'for', found '{s}'", .{
205 token_tags[parse_error.token].symbol(),
196 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
206197 });
207198 },
208199 .expected_labelable => {
209200 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
210 token_tags[parse_error.token].symbol(),
201 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
211202 });
212203 },
213204 .expected_param_list => {
214205 return stream.print("expected parameter list, found '{s}'", .{
215 token_tags[parse_error.token].symbol(),
206 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
216207 });
217208 },
218209 .expected_prefix_expr => {
219210 return stream.print("expected prefix expression, found '{s}'", .{
220 token_tags[parse_error.token].symbol(),
211 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
221212 });
222213 },
223214 .expected_primary_type_expr => {
224215 return stream.print("expected primary type expression, found '{s}'", .{
225 token_tags[parse_error.token].symbol(),
216 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
226217 });
227218 },
228219 .expected_pub_item => {
......@@ -230,7 +221,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
230221 },
231222 .expected_return_type => {
232223 return stream.print("expected return type expression, found '{s}'", .{
233 token_tags[parse_error.token].symbol(),
224 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
234225 });
235226 },
236227 .expected_semi_or_else => {
......@@ -244,39 +235,34 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
244235 token_tags[parse_error.token].symbol(),
245236 });
246237 },
247 .expected_string_literal => {
248 return stream.print("expected string literal, found '{s}'", .{
249 token_tags[parse_error.token].symbol(),
250 });
251 },
252238 .expected_suffix_op => {
253239 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
254 token_tags[parse_error.token].symbol(),
240 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
255241 });
256242 },
257243 .expected_type_expr => {
258244 return stream.print("expected type expression, found '{s}'", .{
259 token_tags[parse_error.token].symbol(),
245 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
260246 });
261247 },
262248 .expected_var_decl => {
263249 return stream.print("expected variable declaration, found '{s}'", .{
264 token_tags[parse_error.token].symbol(),
250 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
265251 });
266252 },
267253 .expected_var_decl_or_fn => {
268254 return stream.print("expected variable declaration or function, found '{s}'", .{
269 token_tags[parse_error.token].symbol(),
255 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
270256 });
271257 },
272258 .expected_loop_payload => {
273259 return stream.print("expected loop payload, found '{s}'", .{
274 token_tags[parse_error.token].symbol(),
260 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
275261 });
276262 },
277263 .expected_container => {
278264 return stream.print("expected a struct, enum or union, found '{s}'", .{
279 token_tags[parse_error.token].symbol(),
265 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
280266 });
281267 },
282268 .extern_fn_body => {
......@@ -341,9 +327,12 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
341327 .expected_comma_after_switch_prong => {
342328 return stream.writeAll("expected ',' after switch prong");
343329 },
330 .expected_initializer => {
331 return stream.writeAll("expected field initializer");
332 },
344333
345334 .expected_token => {
346 const found_tag = token_tags[parse_error.token];
335 const found_tag = token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)];
347336 const expected_symbol = parse_error.extra.expected_tag.symbol();
348337 switch (found_tag) {
349338 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
......@@ -2483,6 +2472,7 @@ pub const full = struct {
24832472
24842473pub const Error = struct {
24852474 tag: Tag,
2475 token_is_prev: bool = false,
24862476 token: TokenIndex,
24872477 extra: union {
24882478 none: void,
......@@ -2511,7 +2501,6 @@ pub const Error = struct {
25112501 expected_semi_or_else,
25122502 expected_semi_or_lbrace,
25132503 expected_statement,
2514 expected_string_literal,
25152504 expected_suffix_op,
25162505 expected_type_expr,
25172506 expected_var_decl,
......@@ -2539,6 +2528,7 @@ pub const Error = struct {
25392528 expected_comma_after_param,
25402529 expected_comma_after_initializer,
25412530 expected_comma_after_switch_prong,
2531 expected_initializer,
25422532
25432533 /// `expected_tag` is populated.
25442534 expected_token,
lib/std/zig/parse.zig+69-93
......@@ -147,11 +147,6 @@ const Parser = struct {
147147 return result;
148148 }
149149
150 fn warn(p: *Parser, tag: Ast.Error.Tag) error{OutOfMemory}!void {
151 @setCold(true);
152 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });
153 }
154
155150 fn warnExpected(p: *Parser, expected_token: Token.Tag) error{OutOfMemory}!void {
156151 @setCold(true);
157152 try p.warnMsg(.{
......@@ -161,13 +156,53 @@ const Parser = struct {
161156 });
162157 }
163158
164 fn warnExpectedAfter(p: *Parser, error_tag: AstError.Tag) error{OutOfMemory}!void {
159 fn warn(p: *Parser, error_tag: AstError.Tag) error{OutOfMemory}!void {
165160 @setCold(true);
166 try p.warnMsg(.{ .tag = error_tag, .token = p.tok_i - 1 });
161 try p.warnMsg(.{ .tag = error_tag, .token = p.tok_i });
167162 }
168163
169164 fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void {
170165 @setCold(true);
166 switch (msg.tag) {
167 .expected_semi_after_decl,
168 .expected_semi_after_stmt,
169 .expected_comma_after_field,
170 .expected_comma_after_arg,
171 .expected_comma_after_param,
172 .expected_comma_after_initializer,
173 .expected_comma_after_switch_prong,
174 .expected_semi_or_else,
175 .expected_semi_or_lbrace,
176 .expected_token,
177 .expected_block,
178 .expected_block_or_assignment,
179 .expected_block_or_expr,
180 .expected_block_or_field,
181 .expected_container_members,
182 .expected_expr,
183 .expected_expr_or_assignment,
184 .expected_fn,
185 .expected_inlinable,
186 .expected_labelable,
187 .expected_param_list,
188 .expected_prefix_expr,
189 .expected_primary_type_expr,
190 .expected_pub_item,
191 .expected_return_type,
192 .expected_suffix_op,
193 .expected_type_expr,
194 .expected_var_decl,
195 .expected_var_decl_or_fn,
196 .expected_loop_payload,
197 .expected_container,
198 => if (msg.token != 0 and !p.tokensOnSameLine(msg.token - 1, msg.token)) {
199 var copy = msg;
200 copy.token_is_prev = true;
201 copy.token -= 1;
202 return p.errors.append(p.gpa, copy);
203 },
204 else => {},
205 }
171206 try p.errors.append(p.gpa, msg);
172207 }
173208
......@@ -264,7 +299,7 @@ const Parser = struct {
264299 }
265300 // There is not allowed to be a decl after a field with no comma.
266301 // Report error but recover parser.
267 try p.warnExpectedAfter(.expected_comma_after_field);
302 try p.warn(.expected_comma_after_field);
268303 p.findNextContainerMember();
269304 }
270305 },
......@@ -367,7 +402,7 @@ const Parser = struct {
367402 }
368403 // There is not allowed to be a decl after a field with no comma.
369404 // Report error but recover parser.
370 try p.warnExpectedAfter(.expected_comma_after_field);
405 try p.warn(.expected_comma_after_field);
371406 p.findNextContainerMember();
372407 }
373408 },
......@@ -585,7 +620,7 @@ const Parser = struct {
585620 // Since parseBlock only return error.ParseError on
586621 // a missing '}' we can assume this function was
587622 // supposed to end here.
588 try p.warnExpectedAfter(.expected_semi_or_lbrace);
623 try p.warn(.expected_semi_or_lbrace);
589624 return null_node;
590625 },
591626 }
......@@ -996,7 +1031,7 @@ const Parser = struct {
9961031 };
9971032 _ = p.eatToken(.keyword_else) orelse {
9981033 if (else_required) {
999 try p.warnExpectedAfter(.expected_semi_or_else);
1034 try p.warn(.expected_semi_or_else);
10001035 }
10011036 return p.addNode(.{
10021037 .tag = .if_simple,
......@@ -1091,7 +1126,7 @@ const Parser = struct {
10911126 };
10921127 _ = p.eatToken(.keyword_else) orelse {
10931128 if (else_required) {
1094 try p.warnExpectedAfter(.expected_semi_or_else);
1129 try p.warn(.expected_semi_or_else);
10951130 }
10961131 return p.addNode(.{
10971132 .tag = .for_simple,
......@@ -1166,7 +1201,7 @@ const Parser = struct {
11661201 };
11671202 _ = p.eatToken(.keyword_else) orelse {
11681203 if (else_required) {
1169 try p.warnExpectedAfter(.expected_semi_or_else);
1204 try p.warn(.expected_semi_or_else);
11701205 }
11711206 if (cont_expr == 0) {
11721207 return p.addNode(.{
......@@ -2050,7 +2085,7 @@ const Parser = struct {
20502085 },
20512086 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
20522087 // Likely just a missing comma; give error but continue parsing.
2053 else => try p.warnExpectedAfter(.expected_comma_after_initializer),
2088 else => try p.warn(.expected_comma_after_initializer),
20542089 }
20552090 if (p.eatToken(.r_brace)) |_| break;
20562091 const next = try p.expectFieldInit();
......@@ -2091,7 +2126,7 @@ const Parser = struct {
20912126 },
20922127 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
20932128 // Likely just a missing comma; give error but continue parsing.
2094 else => try p.warnExpectedAfter(.expected_comma_after_initializer),
2129 else => try p.warn(.expected_comma_after_initializer),
20952130 }
20962131 }
20972132 const comma = (p.token_tags[p.tok_i - 2] == .comma);
......@@ -2170,7 +2205,7 @@ const Parser = struct {
21702205 },
21712206 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),
21722207 // Likely just a missing comma; give error but continue parsing.
2173 else => try p.warnExpectedAfter(.expected_comma_after_arg),
2208 else => try p.warn(.expected_comma_after_arg),
21742209 }
21752210 }
21762211 const comma = (p.token_tags[p.tok_i - 2] == .comma);
......@@ -2226,7 +2261,7 @@ const Parser = struct {
22262261 },
22272262 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),
22282263 // Likely just a missing comma; give error but continue parsing.
2229 else => try p.warnExpectedAfter(.expected_comma_after_arg),
2264 else => try p.warn(.expected_comma_after_arg),
22302265 }
22312266 }
22322267 const comma = (p.token_tags[p.tok_i - 2] == .comma);
......@@ -2467,7 +2502,7 @@ const Parser = struct {
24672502 },
24682503 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
24692504 // Likely just a missing comma; give error but continue parsing.
2470 else => try p.warnExpectedAfter(.expected_comma_after_initializer),
2505 else => try p.warn(.expected_comma_after_initializer),
24712506 }
24722507 if (p.eatToken(.r_brace)) |_| break;
24732508 const next = try p.expectFieldInit();
......@@ -2519,7 +2554,7 @@ const Parser = struct {
25192554 },
25202555 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
25212556 // Likely just a missing comma; give error but continue parsing.
2522 else => try p.warnExpectedAfter(.expected_comma_after_initializer),
2557 else => try p.warn(.expected_comma_after_initializer),
25232558 }
25242559 }
25252560 const comma = (p.token_tags[p.tok_i - 2] == .comma);
......@@ -2580,7 +2615,7 @@ const Parser = struct {
25802615 },
25812616 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
25822617 // Likely just a missing comma; give error but continue parsing.
2583 else => try p.warnExpectedAfter(.expected_comma_after_field),
2618 else => try p.warn(.expected_comma_after_field),
25842619 }
25852620 }
25862621 return p.addNode(.{
......@@ -2879,7 +2914,7 @@ const Parser = struct {
28792914 p.tok_i += 2;
28802915 return identifier;
28812916 }
2882 return 0;
2917 return null_node;
28832918 }
28842919
28852920 /// FieldInit <- DOT IDENTIFIER EQUAL Expr
......@@ -2896,9 +2931,12 @@ const Parser = struct {
28962931 }
28972932
28982933 fn expectFieldInit(p: *Parser) !Node.Index {
2899 _ = try p.expectToken(.period);
2900 _ = try p.expectToken(.identifier);
2901 _ = try p.expectToken(.equal);
2934 if (p.token_tags[p.tok_i] != .period or
2935 p.token_tags[p.tok_i + 1] != .identifier or
2936 p.token_tags[p.tok_i + 2] != .equal)
2937 return p.fail(.expected_initializer);
2938
2939 p.tok_i += 3;
29022940 return p.expectExpr();
29032941 }
29042942
......@@ -3413,7 +3451,7 @@ const Parser = struct {
34133451 // All possible delimiters.
34143452 .colon, .r_paren, .r_brace, .r_bracket => break,
34153453 // Likely just a missing comma; give error but continue parsing.
3416 else => try p.warnExpectedAfter(.expected_comma_after_switch_prong),
3454 else => try p.warn(.expected_comma_after_switch_prong),
34173455 }
34183456 }
34193457 return p.listToSpan(p.scratch.items[scratch_top..]);
......@@ -3442,7 +3480,7 @@ const Parser = struct {
34423480 },
34433481 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),
34443482 // Likely just a missing comma; give error but continue parsing.
3445 else => try p.warnExpectedAfter(.expected_comma_after_param),
3483 else => try p.warn(.expected_comma_after_param),
34463484 }
34473485 }
34483486 if (varargs == .nonfinal) {
......@@ -3486,7 +3524,7 @@ const Parser = struct {
34863524 break;
34873525 },
34883526 // Likely just a missing comma; give error but continue parsing.
3489 else => try p.warnExpectedAfter(.expected_comma_after_arg),
3527 else => try p.warn(.expected_comma_after_arg),
34903528 }
34913529 }
34923530 const comma = (p.token_tags[p.tok_i - 2] == .comma);
......@@ -3530,57 +3568,6 @@ const Parser = struct {
35303568 }
35313569 }
35323570
3533 // string literal or multiline string literal
3534 fn parseStringLiteral(p: *Parser) !Node.Index {
3535 switch (p.token_tags[p.tok_i]) {
3536 .string_literal => {
3537 const main_token = p.nextToken();
3538 return p.addNode(.{
3539 .tag = .string_literal,
3540 .main_token = main_token,
3541 .data = .{
3542 .lhs = undefined,
3543 .rhs = undefined,
3544 },
3545 });
3546 },
3547 .multiline_string_literal_line => {
3548 const first_line = p.nextToken();
3549 while (p.token_tags[p.tok_i] == .multiline_string_literal_line) {
3550 p.tok_i += 1;
3551 }
3552 return p.addNode(.{
3553 .tag = .multiline_string_literal,
3554 .main_token = first_line,
3555 .data = .{
3556 .lhs = first_line,
3557 .rhs = p.tok_i - 1,
3558 },
3559 });
3560 },
3561 else => return null_node,
3562 }
3563 }
3564
3565 fn expectStringLiteral(p: *Parser) !Node.Index {
3566 const node = try p.parseStringLiteral();
3567 if (node == 0) {
3568 return p.fail(.expected_string_literal);
3569 }
3570 return node;
3571 }
3572
3573 fn expectIntegerLiteral(p: *Parser) !Node.Index {
3574 return p.addNode(.{
3575 .tag = .integer_literal,
3576 .main_token = try p.expectToken(.integer_literal),
3577 .data = .{
3578 .lhs = undefined,
3579 .rhs = undefined,
3580 },
3581 });
3582 }
3583
35843571 /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?
35853572 fn parseIf(p: *Parser, bodyParseFn: fn (p: *Parser) Error!Node.Index) !Node.Index {
35863573 const if_token = p.eatToken(.keyword_if) orelse return null_node;
......@@ -3649,25 +3636,14 @@ const Parser = struct {
36493636 }
36503637
36513638 fn expectToken(p: *Parser, tag: Token.Tag) Error!TokenIndex {
3652 const token = p.nextToken();
3653 if (p.token_tags[token] != tag) {
3654 p.tok_i -= 1; // Go back so that we can recover properly.
3639 if (p.token_tags[p.tok_i] != tag) {
36553640 return p.failMsg(.{
36563641 .tag = .expected_token,
3657 .token = token,
3642 .token = p.tok_i,
36583643 .extra = .{ .expected_tag = tag },
36593644 });
36603645 }
3661 return token;
3662 }
3663
3664 fn expectTokenRecoverable(p: *Parser, tag: Token.Tag) !?TokenIndex {
3665 if (p.token_tags[p.tok_i] != tag) {
3666 try p.warnExpected(tag);
3667 return null;
3668 } else {
3669 return p.nextToken();
3670 }
3646 return p.nextToken();
36713647 }
36723648
36733649 fn expectSemicolon(p: *Parser, error_tag: AstError.Tag, recoverable: bool) Error!void {
......@@ -3675,7 +3651,7 @@ const Parser = struct {
36753651 _ = p.nextToken();
36763652 return;
36773653 }
3678 try p.warnExpectedAfter(error_tag);
3654 try p.warn(error_tag);
36793655 if (!recoverable) return error.ParseError;
36803656 }
36813657
lib/std/zig/parser_test.zig+4-2
......@@ -5057,7 +5057,9 @@ test "recovery: block statements" {
50575057 \\ inline;
50585058 \\}
50595059 , &[_]Error{
5060 .invalid_token,
5060 .expected_expr,
5061 .expected_semi_after_stmt,
5062 .expected_statement,
50615063 .expected_inlinable,
50625064 });
50635065}
......@@ -5076,7 +5078,7 @@ test "recovery: missing comma" {
50765078 , &[_]Error{
50775079 .expected_comma_after_switch_prong,
50785080 .expected_comma_after_switch_prong,
5079 .invalid_token,
5081 .expected_expr,
50805082 });
50815083}
50825084
lib/std/zig/tokenizer.zig+12-1
......@@ -322,7 +322,18 @@ pub const Token = struct {
322322 }
323323
324324 pub fn symbol(tag: Tag) []const u8 {
325 return tag.lexeme() orelse @tagName(tag);
325 return tag.lexeme() orelse switch (tag) {
326 .invalid => "invalid bytes",
327 .identifier => "an identifier",
328 .string_literal, .multiline_string_literal_line => "a string literal",
329 .char_literal => "a character literal",
330 .eof => "EOF",
331 .builtin => "a builtin function",
332 .integer_literal => "an integer literal",
333 .float_literal => "a floating point literal",
334 .doc_comment, .container_doc_comment => "a document comment",
335 else => unreachable,
336 };
326337 }
327338 };
328339};
src/Module.zig+4-4
......@@ -2995,7 +2995,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
29952995 const token_starts = file.tree.tokens.items(.start);
29962996 const token_tags = file.tree.tokens.items(.tag);
29972997
2998 const extra_offset = file.tree.errorOffset(parse_err.tag, parse_err.token);
2998 const extra_offset = file.tree.errorOffset(parse_err);
29992999 try file.tree.renderError(parse_err, msg.writer());
30003000 const err_msg = try gpa.create(ErrorMsg);
30013001 err_msg.* = .{
......@@ -3006,9 +3006,9 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
30063006 },
30073007 .msg = msg.toOwnedSlice(),
30083008 };
3009 if (token_tags[parse_err.token] == .invalid) {
3010 const bad_off = @intCast(u32, file.tree.tokenSlice(parse_err.token).len);
3011 const byte_abs = token_starts[parse_err.token] + bad_off;
3009 if (token_tags[parse_err.token + @boolToInt(parse_err.token_is_prev)] == .invalid) {
3010 const bad_off = @intCast(u32, file.tree.tokenSlice(parse_err.token + @boolToInt(parse_err.token_is_prev)).len);
3011 const byte_abs = token_starts[parse_err.token + @boolToInt(parse_err.token_is_prev)] + bad_off;
30123012 try mod.errNoteNonLazy(.{
30133013 .file_scope = file,
30143014 .parent_decl_node = 0,
src/main.zig+4-4
......@@ -4063,9 +4063,9 @@ fn printErrMsgToStdErr(
40634063 var notes_buffer: [1]Compilation.AllErrors.Message = undefined;
40644064 var notes_len: usize = 0;
40654065
4066 if (token_tags[parse_error.token] == .invalid) {
4067 const bad_off = @intCast(u32, tree.tokenSlice(parse_error.token).len);
4068 const byte_offset = @intCast(u32, start_loc.line_start) + bad_off;
4066 if (token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)] == .invalid) {
4067 const bad_off = @intCast(u32, tree.tokenSlice(parse_error.token + @boolToInt(parse_error.token_is_prev)).len);
4068 const byte_offset = @intCast(u32, start_loc.line_start) + @intCast(u32, start_loc.column) + bad_off;
40694069 notes_buffer[notes_len] = .{
40704070 .src = .{
40714071 .src_path = path,
......@@ -4081,7 +4081,7 @@ fn printErrMsgToStdErr(
40814081 notes_len += 1;
40824082 }
40834083
4084 const extra_offset = tree.errorOffset(parse_error.tag, parse_error.token);
4084 const extra_offset = tree.errorOffset(parse_error);
40854085 const message: Compilation.AllErrors.Message = .{
40864086 .src = .{
40874087 .src_path = path,
test/compile_errors.zig+24-24
......@@ -1540,7 +1540,7 @@ pub fn addCases(ctx: *TestContext) !void {
15401540 \\ std.debug.assert(bad_float < 1.0);
15411541 \\}
15421542 , &[_][]const u8{
1543 "tmp.zig:5:29: error: invalid token: '.'",
1543 "tmp.zig:5:29: error: expected expression, found '.'",
15441544 });
15451545
15461546 ctx.objErrStage1("invalid exponent in float literal - 1",
......@@ -1549,7 +1549,7 @@ pub fn addCases(ctx: *TestContext) !void {
15491549 \\ _ = bad;
15501550 \\}
15511551 , &[_][]const u8{
1552 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1552 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
15531553 "tmp.zig:2:28: note: invalid byte: 'a'",
15541554 });
15551555
......@@ -1559,7 +1559,7 @@ pub fn addCases(ctx: *TestContext) !void {
15591559 \\ _ = bad;
15601560 \\}
15611561 , &[_][]const u8{
1562 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1562 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
15631563 "tmp.zig:2:29: note: invalid byte: 'F'",
15641564 });
15651565
......@@ -1569,7 +1569,7 @@ pub fn addCases(ctx: *TestContext) !void {
15691569 \\ _ = bad;
15701570 \\}
15711571 , &[_][]const u8{
1572 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1572 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
15731573 "tmp.zig:2:23: note: invalid byte: '_'",
15741574 });
15751575
......@@ -1579,7 +1579,7 @@ pub fn addCases(ctx: *TestContext) !void {
15791579 \\ _ = bad;
15801580 \\}
15811581 , &[_][]const u8{
1582 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1582 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
15831583 "tmp.zig:2:23: note: invalid byte: '.'",
15841584 });
15851585
......@@ -1589,7 +1589,7 @@ pub fn addCases(ctx: *TestContext) !void {
15891589 \\ _ = bad;
15901590 \\}
15911591 , &[_][]const u8{
1592 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1592 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
15931593 "tmp.zig:2:25: note: invalid byte: ';'",
15941594 });
15951595
......@@ -1599,7 +1599,7 @@ pub fn addCases(ctx: *TestContext) !void {
15991599 \\ _ = bad;
16001600 \\}
16011601 , &[_][]const u8{
1602 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1602 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16031603 "tmp.zig:2:25: note: invalid byte: '_'",
16041604 });
16051605
......@@ -1609,7 +1609,7 @@ pub fn addCases(ctx: *TestContext) !void {
16091609 \\ _ = bad;
16101610 \\}
16111611 , &[_][]const u8{
1612 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1612 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16131613 "tmp.zig:2:26: note: invalid byte: '_'",
16141614 });
16151615
......@@ -1619,7 +1619,7 @@ pub fn addCases(ctx: *TestContext) !void {
16191619 \\ _ = bad;
16201620 \\}
16211621 , &[_][]const u8{
1622 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1622 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16231623 "tmp.zig:2:26: note: invalid byte: '_'",
16241624 });
16251625
......@@ -1629,7 +1629,7 @@ pub fn addCases(ctx: *TestContext) !void {
16291629 \\ _ = bad;
16301630 \\}
16311631 , &[_][]const u8{
1632 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1632 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16331633 "tmp.zig:2:28: note: invalid byte: ';'",
16341634 });
16351635
......@@ -1639,7 +1639,7 @@ pub fn addCases(ctx: *TestContext) !void {
16391639 \\ _ = bad;
16401640 \\}
16411641 , &[_][]const u8{
1642 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1642 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16431643 "tmp.zig:2:23: note: invalid byte: '_'",
16441644 });
16451645
......@@ -1649,7 +1649,7 @@ pub fn addCases(ctx: *TestContext) !void {
16491649 \\ _ = bad;
16501650 \\}
16511651 , &[_][]const u8{
1652 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1652 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16531653 "tmp.zig:2:25: note: invalid byte: '_'",
16541654 });
16551655
......@@ -1659,7 +1659,7 @@ pub fn addCases(ctx: *TestContext) !void {
16591659 \\ _ = bad;
16601660 \\}
16611661 , &[_][]const u8{
1662 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1662 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16631663 "tmp.zig:2:28: note: invalid byte: '_'",
16641664 });
16651665
......@@ -1669,7 +1669,7 @@ pub fn addCases(ctx: *TestContext) !void {
16691669 \\ _ = bad;
16701670 \\}
16711671 , &[_][]const u8{
1672 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1672 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16731673 "tmp.zig:2:23: note: invalid byte: 'x'",
16741674 });
16751675
......@@ -1679,7 +1679,7 @@ pub fn addCases(ctx: *TestContext) !void {
16791679 \\ _ = bad;
16801680 \\}
16811681 , &[_][]const u8{
1682 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1682 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16831683 "tmp.zig:2:23: note: invalid byte: '_'",
16841684 });
16851685
......@@ -1689,7 +1689,7 @@ pub fn addCases(ctx: *TestContext) !void {
16891689 \\ _ = bad;
16901690 \\}
16911691 , &[_][]const u8{
1692 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1692 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
16931693 "tmp.zig:2:27: note: invalid byte: 'p'",
16941694 });
16951695
......@@ -1699,7 +1699,7 @@ pub fn addCases(ctx: *TestContext) !void {
16991699 \\ _ = bad;
17001700 \\}
17011701 , &[_][]const u8{
1702 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1702 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
17031703 "tmp.zig:2:26: note: invalid byte: ';'",
17041704 });
17051705
......@@ -1709,7 +1709,7 @@ pub fn addCases(ctx: *TestContext) !void {
17091709 \\ _ = bad;
17101710 \\}
17111711 , &[_][]const u8{
1712 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1712 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
17131713 "tmp.zig:2:28: note: invalid byte: ';'",
17141714 });
17151715
......@@ -1719,7 +1719,7 @@ pub fn addCases(ctx: *TestContext) !void {
17191719 \\ _ = bad;
17201720 \\}
17211721 , &[_][]const u8{
1722 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1722 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
17231723 "tmp.zig:2:28: note: invalid byte: ';'",
17241724 });
17251725
......@@ -1729,7 +1729,7 @@ pub fn addCases(ctx: *TestContext) !void {
17291729 \\ _ = bad;
17301730 \\}
17311731 , &[_][]const u8{
1732 "tmp.zig:2:21: error: expected expression, found 'invalid'",
1732 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
17331733 "tmp.zig:2:28: note: invalid byte: ';'",
17341734 });
17351735
......@@ -2171,7 +2171,7 @@ pub fn addCases(ctx: *TestContext) !void {
21712171 \\ _ = x;
21722172 \\}
21732173 , &[_][]const u8{
2174 "tmp.zig:3:6: error: expected ',' after field",
2174 "tmp.zig:3:7: error: expected ',' after field",
21752175 });
21762176
21772177 ctx.objErrStage1("bad alignment type",
......@@ -5733,7 +5733,7 @@ pub fn addCases(ctx: *TestContext) !void {
57335733 \\const foo = "a
57345734 \\b";
57355735 , &[_][]const u8{
5736 "tmp.zig:1:13: error: expected expression, found 'invalid'",
5736 "tmp.zig:1:13: error: expected expression, found 'invalid bytes'",
57375737 "tmp.zig:1:15: note: invalid byte: '\\n'",
57385738 });
57395739
......@@ -7638,7 +7638,7 @@ pub fn addCases(ctx: *TestContext) !void {
76387638 \\ const a = '\U1234';
76397639 \\}
76407640 , &[_][]const u8{
7641 "tmp.zig:2:15: error: expected expression, found 'invalid'",
7641 "tmp.zig:2:15: error: expected expression, found 'invalid bytes'",
76427642 "tmp.zig:2:18: note: invalid byte: '1'",
76437643 });
76447644
......@@ -7654,7 +7654,7 @@ pub fn addCases(ctx: *TestContext) !void {
76547654 "fn foo() bool {\r\n" ++
76557655 " return true;\r\n" ++
76567656 "}\r\n", &[_][]const u8{
7657 "tmp.zig:1:1: error: expected test, comptime, var decl, or container field, found 'invalid'",
7657 "tmp.zig:1:1: error: expected test, comptime, var decl, or container field, found 'invalid bytes'",
76587658 "tmp.zig:1:1: note: invalid byte: '\\xff'",
76597659 });
76607660
test/stage2/cbe.zig+1-1
......@@ -693,7 +693,7 @@ pub fn addCases(ctx: *TestContext) !void {
693693 \\ _ = E1.a;
694694 \\}
695695 , &.{
696 ":3:6: error: expected ',' after field",
696 ":3:7: error: expected ',' after field",
697697 });
698698
699699 // Redundant non-exhaustive enum mark.