| author | |
| committer | |
| log | f73044dae598da2b84bff7977be5a8e02093902a |
| tree | 892a4c07e5655404e94381f075f370d0e510008e |
| parent | 2a73700c0fc177fb8781b277a6ba5017dce875b9 |
| parent | 0699b29ce0c5d264bf39c5f88fa6025b61ca6303 |
| signature |
make some errors point to the end of the previous token6 files changed, 137 insertions(+), 81 deletions(-)
lib/std/zig/Ast.zig+51-6| ... | @@ -64,6 +64,24 @@ pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8)) RenderError!void | ... | @@ -64,6 +64,24 @@ pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8)) RenderError!void |
| 64 | return @import("./render.zig").renderTree(buffer, tree); | 64 | return @import("./render.zig").renderTree(buffer, tree); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | /// Returns an extra offset for column and byte offset of errors that | ||
| 68 | /// should point after the token in the error message. | ||
| 69 | pub 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 | }; | ||
| 83 | } | ||
| 84 | |||
| 67 | pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location { | 85 | pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location { |
| 68 | var loc = Location{ | 86 | var loc = Location{ |
| 69 | .line = 0, | 87 | .line = 0, |
| ... | @@ -216,14 +234,10 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -216,14 +234,10 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 216 | }); | 234 | }); |
| 217 | }, | 235 | }, |
| 218 | .expected_semi_or_else => { | 236 | .expected_semi_or_else => { |
| 219 | return stream.print("expected ';' or 'else', found '{s}'", .{ | 237 | return stream.writeAll("expected ';' or 'else' after statement"); |
| 220 | token_tags[parse_error.token].symbol(), | ||
| 221 | }); | ||
| 222 | }, | 238 | }, |
| 223 | .expected_semi_or_lbrace => { | 239 | .expected_semi_or_lbrace => { |
| 224 | return stream.print("expected ';' or '{{', found '{s}'", .{ | 240 | return stream.writeAll("expected ';' or block after function prototype"); |
| 225 | token_tags[parse_error.token].symbol(), | ||
| 226 | }); | ||
| 227 | }, | 241 | }, |
| 228 | .expected_statement => { | 242 | .expected_statement => { |
| 229 | return stream.print("expected statement, found '{s}'", .{ | 243 | return stream.print("expected statement, found '{s}'", .{ |
| ... | @@ -306,6 +320,28 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -306,6 +320,28 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 306 | return stream.writeAll("function prototype has parameter after varargs"); | 320 | return stream.writeAll("function prototype has parameter after varargs"); |
| 307 | }, | 321 | }, |
| 308 | 322 | ||
| 323 | .expected_semi_after_decl => { | ||
| 324 | return stream.writeAll("expected ';' after declaration"); | ||
| 325 | }, | ||
| 326 | .expected_semi_after_stmt => { | ||
| 327 | return stream.writeAll("expected ';' after statement"); | ||
| 328 | }, | ||
| 329 | .expected_comma_after_field => { | ||
| 330 | return stream.writeAll("expected ',' after field"); | ||
| 331 | }, | ||
| 332 | .expected_comma_after_arg => { | ||
| 333 | return stream.writeAll("expected ',' after argument"); | ||
| 334 | }, | ||
| 335 | .expected_comma_after_param => { | ||
| 336 | return stream.writeAll("expected ',' after parameter"); | ||
| 337 | }, | ||
| 338 | .expected_comma_after_initializer => { | ||
| 339 | return stream.writeAll("expected ',' after initializer"); | ||
| 340 | }, | ||
| 341 | .expected_comma_after_switch_prong => { | ||
| 342 | return stream.writeAll("expected ',' after switch prong"); | ||
| 343 | }, | ||
| 344 | |||
| 309 | .expected_token => { | 345 | .expected_token => { |
| 310 | const found_tag = token_tags[parse_error.token]; | 346 | const found_tag = token_tags[parse_error.token]; |
| 311 | const expected_symbol = parse_error.extra.expected_tag.symbol(); | 347 | const expected_symbol = parse_error.extra.expected_tag.symbol(); |
| ... | @@ -2495,6 +2531,15 @@ pub const Error = struct { | ... | @@ -2495,6 +2531,15 @@ pub const Error = struct { |
| 2495 | unattached_doc_comment, | 2531 | unattached_doc_comment, |
| 2496 | varargs_nonfinal, | 2532 | varargs_nonfinal, |
| 2497 | 2533 | ||
| 2534 | // these have `token` set to token after which a semicolon was expected | ||
| 2535 | expected_semi_after_decl, | ||
| 2536 | expected_semi_after_stmt, | ||
| 2537 | expected_comma_after_field, | ||
| 2538 | expected_comma_after_arg, | ||
| 2539 | expected_comma_after_param, | ||
| 2540 | expected_comma_after_initializer, | ||
| 2541 | expected_comma_after_switch_prong, | ||
| 2542 | |||
| 2498 | /// `expected_tag` is populated. | 2543 | /// `expected_tag` is populated. |
| 2499 | expected_token, | 2544 | expected_token, |
| 2500 | }; | 2545 | }; |
lib/std/zig/parse.zig+58-49| ... | @@ -160,6 +160,12 @@ const Parser = struct { | ... | @@ -160,6 +160,12 @@ const Parser = struct { |
| 160 | .extra = .{ .expected_tag = expected_token }, | 160 | .extra = .{ .expected_tag = expected_token }, |
| 161 | }); | 161 | }); |
| 162 | } | 162 | } |
| 163 | |||
| 164 | fn warnExpectedAfter(p: *Parser, error_tag: AstError.Tag) error{OutOfMemory}!void { | ||
| 165 | @setCold(true); | ||
| 166 | try p.warnMsg(.{ .tag = error_tag, .token = p.tok_i - 1 }); | ||
| 167 | } | ||
| 168 | |||
| 163 | fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void { | 169 | fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void { |
| 164 | @setCold(true); | 170 | @setCold(true); |
| 165 | try p.errors.append(p.gpa, msg); | 171 | try p.errors.append(p.gpa, msg); |
| ... | @@ -258,7 +264,7 @@ const Parser = struct { | ... | @@ -258,7 +264,7 @@ const Parser = struct { |
| 258 | } | 264 | } |
| 259 | // There is not allowed to be a decl after a field with no comma. | 265 | // There is not allowed to be a decl after a field with no comma. |
| 260 | // Report error but recover parser. | 266 | // Report error but recover parser. |
| 261 | try p.warnExpected(.comma); | 267 | try p.warnExpectedAfter(.expected_comma_after_field); |
| 262 | p.findNextContainerMember(); | 268 | p.findNextContainerMember(); |
| 263 | } | 269 | } |
| 264 | }, | 270 | }, |
| ... | @@ -361,7 +367,7 @@ const Parser = struct { | ... | @@ -361,7 +367,7 @@ const Parser = struct { |
| 361 | } | 367 | } |
| 362 | // There is not allowed to be a decl after a field with no comma. | 368 | // There is not allowed to be a decl after a field with no comma. |
| 363 | // Report error but recover parser. | 369 | // Report error but recover parser. |
| 364 | try p.warnExpected(.comma); | 370 | try p.warnExpectedAfter(.expected_comma_after_field); |
| 365 | p.findNextContainerMember(); | 371 | p.findNextContainerMember(); |
| 366 | } | 372 | } |
| 367 | }, | 373 | }, |
| ... | @@ -579,7 +585,7 @@ const Parser = struct { | ... | @@ -579,7 +585,7 @@ const Parser = struct { |
| 579 | // Since parseBlock only return error.ParseError on | 585 | // Since parseBlock only return error.ParseError on |
| 580 | // a missing '}' we can assume this function was | 586 | // a missing '}' we can assume this function was |
| 581 | // supposed to end here. | 587 | // supposed to end here. |
| 582 | try p.warn(.expected_semi_or_lbrace); | 588 | try p.warnExpectedAfter(.expected_semi_or_lbrace); |
| 583 | return null_node; | 589 | return null_node; |
| 584 | }, | 590 | }, |
| 585 | } | 591 | } |
| ... | @@ -592,7 +598,7 @@ const Parser = struct { | ... | @@ -592,7 +598,7 @@ const Parser = struct { |
| 592 | const thread_local_token = p.eatToken(.keyword_threadlocal); | 598 | const thread_local_token = p.eatToken(.keyword_threadlocal); |
| 593 | const var_decl = try p.parseVarDecl(); | 599 | const var_decl = try p.parseVarDecl(); |
| 594 | if (var_decl != 0) { | 600 | if (var_decl != 0) { |
| 595 | _ = try p.expectToken(.semicolon); | 601 | try p.expectSemicolon(.expected_semi_after_decl, false); |
| 596 | return var_decl; | 602 | return var_decl; |
| 597 | } | 603 | } |
| 598 | if (thread_local_token != null) { | 604 | if (thread_local_token != null) { |
| ... | @@ -620,7 +626,7 @@ const Parser = struct { | ... | @@ -620,7 +626,7 @@ const Parser = struct { |
| 620 | fn expectUsingNamespace(p: *Parser) !Node.Index { | 626 | fn expectUsingNamespace(p: *Parser) !Node.Index { |
| 621 | const usingnamespace_token = p.assertToken(.keyword_usingnamespace); | 627 | const usingnamespace_token = p.assertToken(.keyword_usingnamespace); |
| 622 | const expr = try p.expectExpr(); | 628 | const expr = try p.expectExpr(); |
| 623 | _ = try p.expectToken(.semicolon); | 629 | try p.expectSemicolon(.expected_semi_after_decl, false); |
| 624 | return p.addNode(.{ | 630 | return p.addNode(.{ |
| 625 | .tag = .@"usingnamespace", | 631 | .tag = .@"usingnamespace", |
| 626 | .main_token = usingnamespace_token, | 632 | .main_token = usingnamespace_token, |
| ... | @@ -857,7 +863,7 @@ const Parser = struct { | ... | @@ -857,7 +863,7 @@ const Parser = struct { |
| 857 | 863 | ||
| 858 | const var_decl = try p.parseVarDecl(); | 864 | const var_decl = try p.parseVarDecl(); |
| 859 | if (var_decl != 0) { | 865 | if (var_decl != 0) { |
| 860 | _ = try p.expectTokenRecoverable(.semicolon); | 866 | try p.expectSemicolon(.expected_semi_after_decl, true); |
| 861 | return var_decl; | 867 | return var_decl; |
| 862 | } | 868 | } |
| 863 | 869 | ||
| ... | @@ -921,7 +927,7 @@ const Parser = struct { | ... | @@ -921,7 +927,7 @@ const Parser = struct { |
| 921 | 927 | ||
| 922 | const assign_expr = try p.parseAssignExpr(); | 928 | const assign_expr = try p.parseAssignExpr(); |
| 923 | if (assign_expr != 0) { | 929 | if (assign_expr != 0) { |
| 924 | _ = try p.expectTokenRecoverable(.semicolon); | 930 | try p.expectSemicolon(.expected_semi_after_stmt, true); |
| 925 | return assign_expr; | 931 | return assign_expr; |
| 926 | } | 932 | } |
| 927 | 933 | ||
| ... | @@ -990,7 +996,7 @@ const Parser = struct { | ... | @@ -990,7 +996,7 @@ const Parser = struct { |
| 990 | }; | 996 | }; |
| 991 | _ = p.eatToken(.keyword_else) orelse { | 997 | _ = p.eatToken(.keyword_else) orelse { |
| 992 | if (else_required) { | 998 | if (else_required) { |
| 993 | try p.warn(.expected_semi_or_else); | 999 | try p.warnExpectedAfter(.expected_semi_or_else); |
| 994 | } | 1000 | } |
| 995 | return p.addNode(.{ | 1001 | return p.addNode(.{ |
| 996 | .tag = .if_simple, | 1002 | .tag = .if_simple, |
| ... | @@ -1085,7 +1091,7 @@ const Parser = struct { | ... | @@ -1085,7 +1091,7 @@ const Parser = struct { |
| 1085 | }; | 1091 | }; |
| 1086 | _ = p.eatToken(.keyword_else) orelse { | 1092 | _ = p.eatToken(.keyword_else) orelse { |
| 1087 | if (else_required) { | 1093 | if (else_required) { |
| 1088 | try p.warn(.expected_semi_or_else); | 1094 | try p.warnExpectedAfter(.expected_semi_or_else); |
| 1089 | } | 1095 | } |
| 1090 | return p.addNode(.{ | 1096 | return p.addNode(.{ |
| 1091 | .tag = .for_simple, | 1097 | .tag = .for_simple, |
| ... | @@ -1160,7 +1166,7 @@ const Parser = struct { | ... | @@ -1160,7 +1166,7 @@ const Parser = struct { |
| 1160 | }; | 1166 | }; |
| 1161 | _ = p.eatToken(.keyword_else) orelse { | 1167 | _ = p.eatToken(.keyword_else) orelse { |
| 1162 | if (else_required) { | 1168 | if (else_required) { |
| 1163 | try p.warn(.expected_semi_or_else); | 1169 | try p.warnExpectedAfter(.expected_semi_or_else); |
| 1164 | } | 1170 | } |
| 1165 | if (cont_expr == 0) { | 1171 | if (cont_expr == 0) { |
| 1166 | return p.addNode(.{ | 1172 | return p.addNode(.{ |
| ... | @@ -1211,7 +1217,7 @@ const Parser = struct { | ... | @@ -1211,7 +1217,7 @@ const Parser = struct { |
| 1211 | } | 1217 | } |
| 1212 | const assign_expr = try p.parseAssignExpr(); | 1218 | const assign_expr = try p.parseAssignExpr(); |
| 1213 | if (assign_expr != 0) { | 1219 | if (assign_expr != 0) { |
| 1214 | _ = try p.expectTokenRecoverable(.semicolon); | 1220 | try p.expectSemicolon(.expected_semi_after_stmt, true); |
| 1215 | return assign_expr; | 1221 | return assign_expr; |
| 1216 | } | 1222 | } |
| 1217 | return null_node; | 1223 | return null_node; |
| ... | @@ -2044,7 +2050,7 @@ const Parser = struct { | ... | @@ -2044,7 +2050,7 @@ const Parser = struct { |
| 2044 | }, | 2050 | }, |
| 2045 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), | 2051 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2046 | // Likely just a missing comma; give error but continue parsing. | 2052 | // Likely just a missing comma; give error but continue parsing. |
| 2047 | else => try p.warnExpected(.comma), | 2053 | else => try p.warnExpectedAfter(.expected_comma_after_initializer), |
| 2048 | } | 2054 | } |
| 2049 | if (p.eatToken(.r_brace)) |_| break; | 2055 | if (p.eatToken(.r_brace)) |_| break; |
| 2050 | const next = try p.expectFieldInit(); | 2056 | const next = try p.expectFieldInit(); |
| ... | @@ -2085,7 +2091,7 @@ const Parser = struct { | ... | @@ -2085,7 +2091,7 @@ const Parser = struct { |
| 2085 | }, | 2091 | }, |
| 2086 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), | 2092 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2087 | // Likely just a missing comma; give error but continue parsing. | 2093 | // Likely just a missing comma; give error but continue parsing. |
| 2088 | else => try p.warnExpected(.comma), | 2094 | else => try p.warnExpectedAfter(.expected_comma_after_initializer), |
| 2089 | } | 2095 | } |
| 2090 | } | 2096 | } |
| 2091 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2097 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| ... | @@ -2164,7 +2170,7 @@ const Parser = struct { | ... | @@ -2164,7 +2170,7 @@ const Parser = struct { |
| 2164 | }, | 2170 | }, |
| 2165 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), | 2171 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 2166 | // Likely just a missing comma; give error but continue parsing. | 2172 | // Likely just a missing comma; give error but continue parsing. |
| 2167 | else => try p.warnExpected(.comma), | 2173 | else => try p.warnExpectedAfter(.expected_comma_after_arg), |
| 2168 | } | 2174 | } |
| 2169 | } | 2175 | } |
| 2170 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2176 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| ... | @@ -2220,7 +2226,7 @@ const Parser = struct { | ... | @@ -2220,7 +2226,7 @@ const Parser = struct { |
| 2220 | }, | 2226 | }, |
| 2221 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), | 2227 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 2222 | // Likely just a missing comma; give error but continue parsing. | 2228 | // Likely just a missing comma; give error but continue parsing. |
| 2223 | else => try p.warnExpected(.comma), | 2229 | else => try p.warnExpectedAfter(.expected_comma_after_arg), |
| 2224 | } | 2230 | } |
| 2225 | } | 2231 | } |
| 2226 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2232 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| ... | @@ -2461,7 +2467,7 @@ const Parser = struct { | ... | @@ -2461,7 +2467,7 @@ const Parser = struct { |
| 2461 | }, | 2467 | }, |
| 2462 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), | 2468 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2463 | // Likely just a missing comma; give error but continue parsing. | 2469 | // Likely just a missing comma; give error but continue parsing. |
| 2464 | else => try p.warnExpected(.comma), | 2470 | else => try p.warnExpectedAfter(.expected_comma_after_initializer), |
| 2465 | } | 2471 | } |
| 2466 | if (p.eatToken(.r_brace)) |_| break; | 2472 | if (p.eatToken(.r_brace)) |_| break; |
| 2467 | const next = try p.expectFieldInit(); | 2473 | const next = try p.expectFieldInit(); |
| ... | @@ -2513,7 +2519,7 @@ const Parser = struct { | ... | @@ -2513,7 +2519,7 @@ const Parser = struct { |
| 2513 | }, | 2519 | }, |
| 2514 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), | 2520 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2515 | // Likely just a missing comma; give error but continue parsing. | 2521 | // Likely just a missing comma; give error but continue parsing. |
| 2516 | else => try p.warnExpected(.comma), | 2522 | else => try p.warnExpectedAfter(.expected_comma_after_initializer), |
| 2517 | } | 2523 | } |
| 2518 | } | 2524 | } |
| 2519 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2525 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| ... | @@ -2574,7 +2580,7 @@ const Parser = struct { | ... | @@ -2574,7 +2580,7 @@ const Parser = struct { |
| 2574 | }, | 2580 | }, |
| 2575 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), | 2581 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2576 | // Likely just a missing comma; give error but continue parsing. | 2582 | // Likely just a missing comma; give error but continue parsing. |
| 2577 | else => try p.warnExpected(.comma), | 2583 | else => try p.warnExpectedAfter(.expected_comma_after_field), |
| 2578 | } | 2584 | } |
| 2579 | } | 2585 | } |
| 2580 | return p.addNode(.{ | 2586 | return p.addNode(.{ |
| ... | @@ -3229,6 +3235,10 @@ const Parser = struct { | ... | @@ -3229,6 +3235,10 @@ const Parser = struct { |
| 3229 | .rhs = p.nextToken(), | 3235 | .rhs = p.nextToken(), |
| 3230 | }, | 3236 | }, |
| 3231 | }), | 3237 | }), |
| 3238 | .l_brace => { | ||
| 3239 | // this a misplaced `.{`, handle the error somewhere else | ||
| 3240 | return null_node; | ||
| 3241 | }, | ||
| 3232 | else => { | 3242 | else => { |
| 3233 | p.tok_i += 1; | 3243 | p.tok_i += 1; |
| 3234 | try p.warn(.expected_suffix_op); | 3244 | try p.warn(.expected_suffix_op); |
| ... | @@ -3389,7 +3399,24 @@ const Parser = struct { | ... | @@ -3389,7 +3399,24 @@ const Parser = struct { |
| 3389 | 3399 | ||
| 3390 | /// SwitchProngList <- (SwitchProng COMMA)* SwitchProng? | 3400 | /// SwitchProngList <- (SwitchProng COMMA)* SwitchProng? |
| 3391 | fn parseSwitchProngList(p: *Parser) !Node.SubRange { | 3401 | fn parseSwitchProngList(p: *Parser) !Node.SubRange { |
| 3392 | return ListParseFn(parseSwitchProng)(p); | 3402 | const scratch_top = p.scratch.items.len; |
| 3403 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | ||
| 3404 | |||
| 3405 | while (true) { | ||
| 3406 | const item = try parseSwitchProng(p); | ||
| 3407 | if (item == 0) break; | ||
| 3408 | |||
| 3409 | try p.scratch.append(p.gpa, item); | ||
| 3410 | |||
| 3411 | switch (p.token_tags[p.tok_i]) { | ||
| 3412 | .comma => p.tok_i += 1, | ||
| 3413 | // All possible delimiters. | ||
| 3414 | .colon, .r_paren, .r_brace, .r_bracket => break, | ||
| 3415 | // Likely just a missing comma; give error but continue parsing. | ||
| 3416 | else => try p.warnExpectedAfter(.expected_comma_after_switch_prong), | ||
| 3417 | } | ||
| 3418 | } | ||
| 3419 | return p.listToSpan(p.scratch.items[scratch_top..]); | ||
| 3393 | } | 3420 | } |
| 3394 | 3421 | ||
| 3395 | /// ParamDeclList <- (ParamDecl COMMA)* ParamDecl? | 3422 | /// ParamDeclList <- (ParamDecl COMMA)* ParamDecl? |
| ... | @@ -3415,7 +3442,7 @@ const Parser = struct { | ... | @@ -3415,7 +3442,7 @@ const Parser = struct { |
| 3415 | }, | 3442 | }, |
| 3416 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), | 3443 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 3417 | // Likely just a missing comma; give error but continue parsing. | 3444 | // Likely just a missing comma; give error but continue parsing. |
| 3418 | else => try p.warnExpected(.comma), | 3445 | else => try p.warnExpectedAfter(.expected_comma_after_param), |
| 3419 | } | 3446 | } |
| 3420 | } | 3447 | } |
| 3421 | if (varargs == .nonfinal) { | 3448 | if (varargs == .nonfinal) { |
| ... | @@ -3429,33 +3456,6 @@ const Parser = struct { | ... | @@ -3429,33 +3456,6 @@ const Parser = struct { |
| 3429 | }; | 3456 | }; |
| 3430 | } | 3457 | } |
| 3431 | 3458 | ||
| 3432 | const NodeParseFn = fn (p: *Parser) Error!Node.Index; | ||
| 3433 | |||
| 3434 | fn ListParseFn(comptime nodeParseFn: anytype) (fn (p: *Parser) Error!Node.SubRange) { | ||
| 3435 | return struct { | ||
| 3436 | pub fn parse(p: *Parser) Error!Node.SubRange { | ||
| 3437 | const scratch_top = p.scratch.items.len; | ||
| 3438 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | ||
| 3439 | |||
| 3440 | while (true) { | ||
| 3441 | const item = try nodeParseFn(p); | ||
| 3442 | if (item == 0) break; | ||
| 3443 | |||
| 3444 | try p.scratch.append(p.gpa, item); | ||
| 3445 | |||
| 3446 | switch (p.token_tags[p.tok_i]) { | ||
| 3447 | .comma => p.tok_i += 1, | ||
| 3448 | // All possible delimiters. | ||
| 3449 | .colon, .r_paren, .r_brace, .r_bracket => break, | ||
| 3450 | // Likely just a missing comma; give error but continue parsing. | ||
| 3451 | else => try p.warnExpected(.comma), | ||
| 3452 | } | ||
| 3453 | } | ||
| 3454 | return p.listToSpan(p.scratch.items[scratch_top..]); | ||
| 3455 | } | ||
| 3456 | }.parse; | ||
| 3457 | } | ||
| 3458 | |||
| 3459 | /// FnCallArguments <- LPAREN ExprList RPAREN | 3459 | /// FnCallArguments <- LPAREN ExprList RPAREN |
| 3460 | /// ExprList <- (Expr COMMA)* Expr? | 3460 | /// ExprList <- (Expr COMMA)* Expr? |
| 3461 | fn parseBuiltinCall(p: *Parser) !Node.Index { | 3461 | fn parseBuiltinCall(p: *Parser) !Node.Index { |
| ... | @@ -3486,7 +3486,7 @@ const Parser = struct { | ... | @@ -3486,7 +3486,7 @@ const Parser = struct { |
| 3486 | break; | 3486 | break; |
| 3487 | }, | 3487 | }, |
| 3488 | // Likely just a missing comma; give error but continue parsing. | 3488 | // Likely just a missing comma; give error but continue parsing. |
| 3489 | else => try p.warnExpected(.comma), | 3489 | else => try p.warnExpectedAfter(.expected_comma_after_arg), |
| 3490 | } | 3490 | } |
| 3491 | } | 3491 | } |
| 3492 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 3492 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| ... | @@ -3582,7 +3582,7 @@ const Parser = struct { | ... | @@ -3582,7 +3582,7 @@ const Parser = struct { |
| 3582 | } | 3582 | } |
| 3583 | 3583 | ||
| 3584 | /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)? | 3584 | /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)? |
| 3585 | fn parseIf(p: *Parser, bodyParseFn: NodeParseFn) !Node.Index { | 3585 | fn parseIf(p: *Parser, bodyParseFn: fn (p: *Parser) Error!Node.Index) !Node.Index { |
| 3586 | const if_token = p.eatToken(.keyword_if) orelse return null_node; | 3586 | const if_token = p.eatToken(.keyword_if) orelse return null_node; |
| 3587 | _ = try p.expectToken(.l_paren); | 3587 | _ = try p.expectToken(.l_paren); |
| 3588 | const condition = try p.expectExpr(); | 3588 | const condition = try p.expectExpr(); |
| ... | @@ -3670,6 +3670,15 @@ const Parser = struct { | ... | @@ -3670,6 +3670,15 @@ const Parser = struct { |
| 3670 | } | 3670 | } |
| 3671 | } | 3671 | } |
| 3672 | 3672 | ||
| 3673 | fn expectSemicolon(p: *Parser, error_tag: AstError.Tag, recoverable: bool) Error!void { | ||
| 3674 | if (p.token_tags[p.tok_i] == .semicolon) { | ||
| 3675 | _ = p.nextToken(); | ||
| 3676 | return; | ||
| 3677 | } | ||
| 3678 | try p.warnExpectedAfter(error_tag); | ||
| 3679 | if (!recoverable) return error.ParseError; | ||
| 3680 | } | ||
| 3681 | |||
| 3673 | fn nextToken(p: *Parser) TokenIndex { | 3682 | fn nextToken(p: *Parser) TokenIndex { |
| 3674 | const result = p.tok_i; | 3683 | const result = p.tok_i; |
| 3675 | p.tok_i += 1; | 3684 | p.tok_i += 1; |
src/Module.zig+2-1| ... | @@ -2995,13 +2995,14 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -2995,13 +2995,14 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2995 | const token_starts = file.tree.tokens.items(.start); | 2995 | const token_starts = file.tree.tokens.items(.start); |
| 2996 | const token_tags = file.tree.tokens.items(.tag); | 2996 | const token_tags = file.tree.tokens.items(.tag); |
| 2997 | 2997 | ||
| 2998 | const extra_offset = file.tree.errorOffset(parse_err.tag, parse_err.token); | ||
| 2998 | try file.tree.renderError(parse_err, msg.writer()); | 2999 | try file.tree.renderError(parse_err, msg.writer()); |
| 2999 | const err_msg = try gpa.create(ErrorMsg); | 3000 | const err_msg = try gpa.create(ErrorMsg); |
| 3000 | err_msg.* = .{ | 3001 | err_msg.* = .{ |
| 3001 | .src_loc = .{ | 3002 | .src_loc = .{ |
| 3002 | .file_scope = file, | 3003 | .file_scope = file, |
| 3003 | .parent_decl_node = 0, | 3004 | .parent_decl_node = 0, |
| 3004 | .lazy = .{ .byte_abs = token_starts[parse_err.token] }, | 3005 | .lazy = .{ .byte_abs = token_starts[parse_err.token] + extra_offset }, |
| 3005 | }, | 3006 | }, |
| 3006 | .msg = msg.toOwnedSlice(), | 3007 | .msg = msg.toOwnedSlice(), |
| 3007 | }; | 3008 | }; |
src/main.zig+3-2| ... | @@ -4040,13 +4040,14 @@ fn printErrMsgToStdErr( | ... | @@ -4040,13 +4040,14 @@ fn printErrMsgToStdErr( |
| 4040 | notes_len += 1; | 4040 | notes_len += 1; |
| 4041 | } | 4041 | } |
| 4042 | 4042 | ||
| 4043 | const extra_offset = tree.errorOffset(parse_error.tag, parse_error.token); | ||
| 4043 | const message: Compilation.AllErrors.Message = .{ | 4044 | const message: Compilation.AllErrors.Message = .{ |
| 4044 | .src = .{ | 4045 | .src = .{ |
| 4045 | .src_path = path, | 4046 | .src_path = path, |
| 4046 | .msg = text, | 4047 | .msg = text, |
| 4047 | .byte_offset = @intCast(u32, start_loc.line_start), | 4048 | .byte_offset = @intCast(u32, start_loc.line_start) + extra_offset, |
| 4048 | .line = @intCast(u32, start_loc.line), | 4049 | .line = @intCast(u32, start_loc.line), |
| 4049 | .column = @intCast(u32, start_loc.column), | 4050 | .column = @intCast(u32, start_loc.column) + extra_offset, |
| 4050 | .source_line = source_line, | 4051 | .source_line = source_line, |
| 4051 | .notes = notes_buffer[0..notes_len], | 4052 | .notes = notes_buffer[0..notes_len], |
| 4052 | }, | 4053 | }, |
test/compile_errors.zig+22-22| ... | @@ -2171,7 +2171,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -2171,7 +2171,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 2171 | \\ _ = x; | 2171 | \\ _ = x; |
| 2172 | \\} | 2172 | \\} |
| 2173 | , &[_][]const u8{ | 2173 | , &[_][]const u8{ |
| 2174 | "tmp.zig:3:7: error: expected ',', found 'align'", | 2174 | "tmp.zig:3:6: error: expected ',' after field", |
| 2175 | }); | 2175 | }); |
| 2176 | 2176 | ||
| 2177 | ctx.objErrStage1("bad alignment type", | 2177 | ctx.objErrStage1("bad alignment type", |
| ... | @@ -4704,7 +4704,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4704,7 +4704,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4704 | \\ var bad = {}; | 4704 | \\ var bad = {}; |
| 4705 | \\} | 4705 | \\} |
| 4706 | , &[_][]const u8{ | 4706 | , &[_][]const u8{ |
| 4707 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4707 | "tmp.zig:4:9: error: expected ';' after statement", |
| 4708 | }); | 4708 | }); |
| 4709 | 4709 | ||
| 4710 | ctx.objErrStage1("implicit semicolon - block expr", | 4710 | ctx.objErrStage1("implicit semicolon - block expr", |
| ... | @@ -4715,7 +4715,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4715,7 +4715,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4715 | \\ var bad = {}; | 4715 | \\ var bad = {}; |
| 4716 | \\} | 4716 | \\} |
| 4717 | , &[_][]const u8{ | 4717 | , &[_][]const u8{ |
| 4718 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4718 | "tmp.zig:4:11: error: expected ';' after statement", |
| 4719 | }); | 4719 | }); |
| 4720 | 4720 | ||
| 4721 | ctx.objErrStage1("implicit semicolon - comptime statement", | 4721 | ctx.objErrStage1("implicit semicolon - comptime statement", |
| ... | @@ -4726,7 +4726,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4726,7 +4726,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4726 | \\ var bad = {}; | 4726 | \\ var bad = {}; |
| 4727 | \\} | 4727 | \\} |
| 4728 | , &[_][]const u8{ | 4728 | , &[_][]const u8{ |
| 4729 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4729 | "tmp.zig:4:18: error: expected ';' after statement", |
| 4730 | }); | 4730 | }); |
| 4731 | 4731 | ||
| 4732 | ctx.objErrStage1("implicit semicolon - comptime expression", | 4732 | ctx.objErrStage1("implicit semicolon - comptime expression", |
| ... | @@ -4737,7 +4737,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4737,7 +4737,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4737 | \\ var bad = {}; | 4737 | \\ var bad = {}; |
| 4738 | \\} | 4738 | \\} |
| 4739 | , &[_][]const u8{ | 4739 | , &[_][]const u8{ |
| 4740 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4740 | "tmp.zig:4:20: error: expected ';' after statement", |
| 4741 | }); | 4741 | }); |
| 4742 | 4742 | ||
| 4743 | ctx.objErrStage1("implicit semicolon - defer", | 4743 | ctx.objErrStage1("implicit semicolon - defer", |
| ... | @@ -4748,7 +4748,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4748,7 +4748,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4748 | \\ var bad = {}; | 4748 | \\ var bad = {}; |
| 4749 | \\} | 4749 | \\} |
| 4750 | , &[_][]const u8{ | 4750 | , &[_][]const u8{ |
| 4751 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4751 | "tmp.zig:4:15: error: expected ';' after statement", |
| 4752 | }); | 4752 | }); |
| 4753 | 4753 | ||
| 4754 | ctx.objErrStage1("implicit semicolon - if statement", | 4754 | ctx.objErrStage1("implicit semicolon - if statement", |
| ... | @@ -4759,7 +4759,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4759,7 +4759,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4759 | \\ var bad = {}; | 4759 | \\ var bad = {}; |
| 4760 | \\} | 4760 | \\} |
| 4761 | , &[_][]const u8{ | 4761 | , &[_][]const u8{ |
| 4762 | "tmp.zig:5:5: error: expected ';' or 'else', found 'var'", | 4762 | "tmp.zig:4:18: error: expected ';' or 'else' after statement", |
| 4763 | }); | 4763 | }); |
| 4764 | 4764 | ||
| 4765 | ctx.objErrStage1("implicit semicolon - if expression", | 4765 | ctx.objErrStage1("implicit semicolon - if expression", |
| ... | @@ -4770,7 +4770,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4770,7 +4770,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4770 | \\ var bad = {}; | 4770 | \\ var bad = {}; |
| 4771 | \\} | 4771 | \\} |
| 4772 | , &[_][]const u8{ | 4772 | , &[_][]const u8{ |
| 4773 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4773 | "tmp.zig:4:20: error: expected ';' after statement", |
| 4774 | }); | 4774 | }); |
| 4775 | 4775 | ||
| 4776 | ctx.objErrStage1("implicit semicolon - if-else statement", | 4776 | ctx.objErrStage1("implicit semicolon - if-else statement", |
| ... | @@ -4781,7 +4781,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4781,7 +4781,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4781 | \\ var bad = {}; | 4781 | \\ var bad = {}; |
| 4782 | \\} | 4782 | \\} |
| 4783 | , &[_][]const u8{ | 4783 | , &[_][]const u8{ |
| 4784 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4784 | "tmp.zig:4:28: error: expected ';' after statement", |
| 4785 | }); | 4785 | }); |
| 4786 | 4786 | ||
| 4787 | ctx.objErrStage1("implicit semicolon - if-else expression", | 4787 | ctx.objErrStage1("implicit semicolon - if-else expression", |
| ... | @@ -4792,7 +4792,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4792,7 +4792,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4792 | \\ var bad = {}; | 4792 | \\ var bad = {}; |
| 4793 | \\} | 4793 | \\} |
| 4794 | , &[_][]const u8{ | 4794 | , &[_][]const u8{ |
| 4795 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4795 | "tmp.zig:4:28: error: expected ';' after statement", |
| 4796 | }); | 4796 | }); |
| 4797 | 4797 | ||
| 4798 | ctx.objErrStage1("implicit semicolon - if-else-if statement", | 4798 | ctx.objErrStage1("implicit semicolon - if-else-if statement", |
| ... | @@ -4803,7 +4803,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4803,7 +4803,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4803 | \\ var bad = {}; | 4803 | \\ var bad = {}; |
| 4804 | \\} | 4804 | \\} |
| 4805 | , &[_][]const u8{ | 4805 | , &[_][]const u8{ |
| 4806 | "tmp.zig:5:5: error: expected ';' or 'else', found 'var'", | 4806 | "tmp.zig:4:37: error: expected ';' or 'else' after statement", |
| 4807 | }); | 4807 | }); |
| 4808 | 4808 | ||
| 4809 | ctx.objErrStage1("implicit semicolon - if-else-if expression", | 4809 | ctx.objErrStage1("implicit semicolon - if-else-if expression", |
| ... | @@ -4814,7 +4814,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4814,7 +4814,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4814 | \\ var bad = {}; | 4814 | \\ var bad = {}; |
| 4815 | \\} | 4815 | \\} |
| 4816 | , &[_][]const u8{ | 4816 | , &[_][]const u8{ |
| 4817 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4817 | "tmp.zig:4:37: error: expected ';' after statement", |
| 4818 | }); | 4818 | }); |
| 4819 | 4819 | ||
| 4820 | ctx.objErrStage1("implicit semicolon - if-else-if-else statement", | 4820 | ctx.objErrStage1("implicit semicolon - if-else-if-else statement", |
| ... | @@ -4825,7 +4825,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4825,7 +4825,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4825 | \\ var bad = {}; | 4825 | \\ var bad = {}; |
| 4826 | \\} | 4826 | \\} |
| 4827 | , &[_][]const u8{ | 4827 | , &[_][]const u8{ |
| 4828 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4828 | "tmp.zig:4:47: error: expected ';' after statement", |
| 4829 | }); | 4829 | }); |
| 4830 | 4830 | ||
| 4831 | ctx.objErrStage1("implicit semicolon - if-else-if-else expression", | 4831 | ctx.objErrStage1("implicit semicolon - if-else-if-else expression", |
| ... | @@ -4836,7 +4836,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4836,7 +4836,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4836 | \\ var bad = {}; | 4836 | \\ var bad = {}; |
| 4837 | \\} | 4837 | \\} |
| 4838 | , &[_][]const u8{ | 4838 | , &[_][]const u8{ |
| 4839 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4839 | "tmp.zig:4:45: error: expected ';' after statement", |
| 4840 | }); | 4840 | }); |
| 4841 | 4841 | ||
| 4842 | ctx.objErrStage1("implicit semicolon - test statement", | 4842 | ctx.objErrStage1("implicit semicolon - test statement", |
| ... | @@ -4847,7 +4847,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4847,7 +4847,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4847 | \\ var bad = {}; | 4847 | \\ var bad = {}; |
| 4848 | \\} | 4848 | \\} |
| 4849 | , &[_][]const u8{ | 4849 | , &[_][]const u8{ |
| 4850 | "tmp.zig:5:5: error: expected ';' or 'else', found 'var'", | 4850 | "tmp.zig:4:24: error: expected ';' or 'else' after statement", |
| 4851 | }); | 4851 | }); |
| 4852 | 4852 | ||
| 4853 | ctx.objErrStage1("implicit semicolon - test expression", | 4853 | ctx.objErrStage1("implicit semicolon - test expression", |
| ... | @@ -4858,7 +4858,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4858,7 +4858,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4858 | \\ var bad = {}; | 4858 | \\ var bad = {}; |
| 4859 | \\} | 4859 | \\} |
| 4860 | , &[_][]const u8{ | 4860 | , &[_][]const u8{ |
| 4861 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4861 | "tmp.zig:4:26: error: expected ';' after statement", |
| 4862 | }); | 4862 | }); |
| 4863 | 4863 | ||
| 4864 | ctx.objErrStage1("implicit semicolon - while statement", | 4864 | ctx.objErrStage1("implicit semicolon - while statement", |
| ... | @@ -4869,7 +4869,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4869,7 +4869,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4869 | \\ var bad = {}; | 4869 | \\ var bad = {}; |
| 4870 | \\} | 4870 | \\} |
| 4871 | , &[_][]const u8{ | 4871 | , &[_][]const u8{ |
| 4872 | "tmp.zig:5:5: error: expected ';' or 'else', found 'var'", | 4872 | "tmp.zig:4:21: error: expected ';' or 'else' after statement", |
| 4873 | }); | 4873 | }); |
| 4874 | 4874 | ||
| 4875 | ctx.objErrStage1("implicit semicolon - while expression", | 4875 | ctx.objErrStage1("implicit semicolon - while expression", |
| ... | @@ -4880,7 +4880,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4880,7 +4880,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4880 | \\ var bad = {}; | 4880 | \\ var bad = {}; |
| 4881 | \\} | 4881 | \\} |
| 4882 | , &[_][]const u8{ | 4882 | , &[_][]const u8{ |
| 4883 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4883 | "tmp.zig:4:23: error: expected ';' after statement", |
| 4884 | }); | 4884 | }); |
| 4885 | 4885 | ||
| 4886 | ctx.objErrStage1("implicit semicolon - while-continue statement", | 4886 | ctx.objErrStage1("implicit semicolon - while-continue statement", |
| ... | @@ -4891,7 +4891,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4891,7 +4891,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4891 | \\ var bad = {}; | 4891 | \\ var bad = {}; |
| 4892 | \\} | 4892 | \\} |
| 4893 | , &[_][]const u8{ | 4893 | , &[_][]const u8{ |
| 4894 | "tmp.zig:5:5: error: expected ';' or 'else', found 'var'", | 4894 | "tmp.zig:4:26: error: expected ';' or 'else' after statement", |
| 4895 | }); | 4895 | }); |
| 4896 | 4896 | ||
| 4897 | ctx.objErrStage1("implicit semicolon - while-continue expression", | 4897 | ctx.objErrStage1("implicit semicolon - while-continue expression", |
| ... | @@ -4902,7 +4902,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4902,7 +4902,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4902 | \\ var bad = {}; | 4902 | \\ var bad = {}; |
| 4903 | \\} | 4903 | \\} |
| 4904 | , &[_][]const u8{ | 4904 | , &[_][]const u8{ |
| 4905 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4905 | "tmp.zig:4:28: error: expected ';' after statement", |
| 4906 | }); | 4906 | }); |
| 4907 | 4907 | ||
| 4908 | ctx.objErrStage1("implicit semicolon - for statement", | 4908 | ctx.objErrStage1("implicit semicolon - for statement", |
| ... | @@ -4913,7 +4913,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4913,7 +4913,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4913 | \\ var bad = {}; | 4913 | \\ var bad = {}; |
| 4914 | \\} | 4914 | \\} |
| 4915 | , &[_][]const u8{ | 4915 | , &[_][]const u8{ |
| 4916 | "tmp.zig:5:5: error: expected ';' or 'else', found 'var'", | 4916 | "tmp.zig:4:24: error: expected ';' or 'else' after statement", |
| 4917 | }); | 4917 | }); |
| 4918 | 4918 | ||
| 4919 | ctx.objErrStage1("implicit semicolon - for expression", | 4919 | ctx.objErrStage1("implicit semicolon - for expression", |
| ... | @@ -4924,7 +4924,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -4924,7 +4924,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 4924 | \\ var bad = {}; | 4924 | \\ var bad = {}; |
| 4925 | \\} | 4925 | \\} |
| 4926 | , &[_][]const u8{ | 4926 | , &[_][]const u8{ |
| 4927 | "tmp.zig:5:5: error: expected ';', found 'var'", | 4927 | "tmp.zig:4:26: error: expected ';' after statement", |
| 4928 | }); | 4928 | }); |
| 4929 | 4929 | ||
| 4930 | ctx.objErrStage1("multiple function definitions", | 4930 | ctx.objErrStage1("multiple function definitions", |
test/stage2/cbe.zig+1-1| ... | @@ -693,7 +693,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -693,7 +693,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 693 | \\ _ = E1.a; | 693 | \\ _ = E1.a; |
| 694 | \\} | 694 | \\} |
| 695 | , &.{ | 695 | , &.{ |
| 696 | ":3:7: error: expected ',', found 'align'", | 696 | ":3:6: error: expected ',' after field", |
| 697 | }); | 697 | }); |
| 698 | 698 | ||
| 699 | // Redundant non-exhaustive enum mark. | 699 | // Redundant non-exhaustive enum mark. |