authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 14:22:34+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 20:51:26+02:00
log92f276781417d7e710081470d97606e26cf764d6
treecc5a4864a9e1fca1c177d1b8f3f83877d2c9ae29
parentc9dde10f8629c3ad2234f6220990b1dd70bac807

parser: add error for missing colon before continue expr

If a '(' is found where the continue expression was expected and it is on the same line as the previous token issue an error about missing colon before the continue expression.

4 files changed, 32 insertions(+), 5 deletions(-)

lib/std/zig/Ast.zig+5-2
......@@ -300,6 +300,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
300300 .varargs_nonfinal => {
301301 return stream.writeAll("function prototype has parameter after varargs");
302302 },
303 .expected_continue_expr => {
304 return stream.writeAll("expected ':' before while continue expression");
305 },
303306
304307 .expected_semi_after_decl => {
305308 return stream.writeAll("expected ';' after declaration");
......@@ -2467,6 +2470,7 @@ pub const full = struct {
24672470
24682471pub const Error = struct {
24692472 tag: Tag,
2473 /// True if `token` points to the token before the token causing an issue.
24702474 token_is_prev: bool = false,
24712475 token: TokenIndex,
24722476 extra: union {
......@@ -2513,8 +2517,7 @@ pub const Error = struct {
25132517 same_line_doc_comment,
25142518 unattached_doc_comment,
25152519 varargs_nonfinal,
2516
2517 // these have `token` set to token after which a semicolon was expected
2520 expected_continue_expr,
25182521 expected_semi_after_decl,
25192522 expected_semi_after_stmt,
25202523 expected_comma_after_field,
lib/std/zig/parse.zig+6-1
......@@ -2943,7 +2943,12 @@ const Parser = struct {
29432943
29442944 /// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
29452945 fn parseWhileContinueExpr(p: *Parser) !Node.Index {
2946 _ = p.eatToken(.colon) orelse return null_node;
2946 _ = p.eatToken(.colon) orelse {
2947 if (p.token_tags[p.tok_i] == .l_paren and
2948 p.tokensOnSameLine(p.tok_i - 1, p.tok_i))
2949 return p.fail(.expected_continue_expr);
2950 return null_node;
2951 };
29472952 _ = try p.expectToken(.l_paren);
29482953 const node = try p.parseAssignExpr();
29492954 if (node == 0) return p.fail(.expected_expr_or_assignment);
lib/std/zig/parser_test.zig+19
......@@ -5018,6 +5018,25 @@ test "zig fmt: make single-line if no trailing comma" {
50185018 );
50195019}
50205020
5021test "zig fmt: while continue expr" {
5022 try testCanonical(
5023 \\test {
5024 \\ while (i > 0)
5025 \\ (i * 2);
5026 \\}
5027 \\
5028 );
5029 try testError(
5030 \\test {
5031 \\ while (i > 0) (i -= 1) {
5032 \\ print("test123", .{});
5033 \\ }
5034 \\}
5035 , &[_]Error{
5036 .expected_continue_expr,
5037 });
5038}
5039
50215040test "zig fmt: error for invalid bit range" {
50225041 try testError(
50235042 \\var x: []align(0:0:0)u8 = bar;
test/compile_errors.zig+2-2
......@@ -4869,11 +4869,11 @@ pub fn addCases(ctx: *TestContext) !void {
48694869 \\export fn entry() void {
48704870 \\ while(true) {}
48714871 \\ var good = {};
4872 \\ while(true) ({})
4872 \\ while(true) 1
48734873 \\ var bad = {};
48744874 \\}
48754875 , &[_][]const u8{
4876 "tmp.zig:4:21: error: expected ';' or 'else' after statement",
4876 "tmp.zig:4:18: error: expected ';' or 'else' after statement",
48774877 });
48784878
48794879 ctx.objErrStage1("implicit semicolon - while expression",