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.
This commit is contained in:
Veikka Tuominen 2022-02-17 14:22:34 +02:00
parent c9dde10f86
commit 92f2767814
4 changed files with 32 additions and 5 deletions

View file

@ -300,6 +300,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
.varargs_nonfinal => {
return stream.writeAll("function prototype has parameter after varargs");
},
.expected_continue_expr => {
return stream.writeAll("expected ':' before while continue expression");
},
.expected_semi_after_decl => {
return stream.writeAll("expected ';' after declaration");
@ -2467,6 +2470,7 @@ pub const full = struct {
pub const Error = struct {
tag: Tag,
/// True if `token` points to the token before the token causing an issue.
token_is_prev: bool = false,
token: TokenIndex,
extra: union {
@ -2513,8 +2517,7 @@ pub const Error = struct {
same_line_doc_comment,
unattached_doc_comment,
varargs_nonfinal,
// these have `token` set to token after which a semicolon was expected
expected_continue_expr,
expected_semi_after_decl,
expected_semi_after_stmt,
expected_comma_after_field,

View file

@ -2943,7 +2943,12 @@ const Parser = struct {
/// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
fn parseWhileContinueExpr(p: *Parser) !Node.Index {
_ = p.eatToken(.colon) orelse return null_node;
_ = p.eatToken(.colon) orelse {
if (p.token_tags[p.tok_i] == .l_paren and
p.tokensOnSameLine(p.tok_i - 1, p.tok_i))
return p.fail(.expected_continue_expr);
return null_node;
};
_ = try p.expectToken(.l_paren);
const node = try p.parseAssignExpr();
if (node == 0) return p.fail(.expected_expr_or_assignment);

View file

@ -5018,6 +5018,25 @@ test "zig fmt: make single-line if no trailing comma" {
);
}
test "zig fmt: while continue expr" {
try testCanonical(
\\test {
\\ while (i > 0)
\\ (i * 2);
\\}
\\
);
try testError(
\\test {
\\ while (i > 0) (i -= 1) {
\\ print("test123", .{});
\\ }
\\}
, &[_]Error{
.expected_continue_expr,
});
}
test "zig fmt: error for invalid bit range" {
try testError(
\\var x: []align(0:0:0)u8 = bar;

View file

@ -4869,11 +4869,11 @@ pub fn addCases(ctx: *TestContext) !void {
\\export fn entry() void {
\\ while(true) {}
\\ var good = {};
\\ while(true) ({})
\\ while(true) 1
\\ var bad = {};
\\}
, &[_][]const u8{
"tmp.zig:4:21: error: expected ';' or 'else' after statement",
"tmp.zig:4:18: error: expected ';' or 'else' after statement",
});
ctx.objErrStage1("implicit semicolon - while expression",