mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
parser: disallow defer and variable declaration as else branch
Closes #13658
This commit is contained in:
parent
1829b6eab8
commit
34be5784a3
@ -950,13 +950,15 @@ const Parser = struct {
|
||||
/// / LabeledStatement
|
||||
/// / SwitchExpr
|
||||
/// / AssignExpr SEMICOLON
|
||||
fn parseStatement(p: *Parser) Error!Node.Index {
|
||||
fn parseStatement(p: *Parser, allow_defer_var: bool) Error!Node.Index {
|
||||
const comptime_token = p.eatToken(.keyword_comptime);
|
||||
|
||||
const var_decl = try p.parseVarDecl();
|
||||
if (var_decl != 0) {
|
||||
try p.expectSemicolon(.expected_semi_after_decl, true);
|
||||
return var_decl;
|
||||
if (allow_defer_var) {
|
||||
const var_decl = try p.parseVarDecl();
|
||||
if (var_decl != 0) {
|
||||
try p.expectSemicolon(.expected_semi_after_decl, true);
|
||||
return var_decl;
|
||||
}
|
||||
}
|
||||
|
||||
if (comptime_token) |token| {
|
||||
@ -993,7 +995,7 @@ const Parser = struct {
|
||||
},
|
||||
});
|
||||
},
|
||||
.keyword_defer => return p.addNode(.{
|
||||
.keyword_defer => if (allow_defer_var) return p.addNode(.{
|
||||
.tag = .@"defer",
|
||||
.main_token = p.nextToken(),
|
||||
.data = .{
|
||||
@ -1001,7 +1003,7 @@ const Parser = struct {
|
||||
.rhs = try p.expectBlockExprStatement(),
|
||||
},
|
||||
}),
|
||||
.keyword_errdefer => return p.addNode(.{
|
||||
.keyword_errdefer => if (allow_defer_var) return p.addNode(.{
|
||||
.tag = .@"errdefer",
|
||||
.main_token = p.nextToken(),
|
||||
.data = .{
|
||||
@ -1040,8 +1042,8 @@ const Parser = struct {
|
||||
return null_node;
|
||||
}
|
||||
|
||||
fn expectStatement(p: *Parser) !Node.Index {
|
||||
const statement = try p.parseStatement();
|
||||
fn expectStatement(p: *Parser, allow_defer_var: bool) !Node.Index {
|
||||
const statement = try p.parseStatement(allow_defer_var);
|
||||
if (statement == 0) {
|
||||
return p.fail(.expected_statement);
|
||||
}
|
||||
@ -1053,7 +1055,7 @@ const Parser = struct {
|
||||
/// statement, returns 0.
|
||||
fn expectStatementRecoverable(p: *Parser) Error!Node.Index {
|
||||
while (true) {
|
||||
return p.expectStatement() catch |err| switch (err) {
|
||||
return p.expectStatement(true) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.ParseError => {
|
||||
p.findNextStmt(); // Try to skip to the next statement.
|
||||
@ -1114,7 +1116,7 @@ const Parser = struct {
|
||||
});
|
||||
};
|
||||
_ = try p.parsePayload();
|
||||
const else_expr = try p.expectStatement();
|
||||
const else_expr = try p.expectStatement(false);
|
||||
return p.addNode(.{
|
||||
.tag = .@"if",
|
||||
.main_token = if_token,
|
||||
@ -1226,7 +1228,7 @@ const Parser = struct {
|
||||
.lhs = array_expr,
|
||||
.rhs = try p.addExtra(Node.If{
|
||||
.then_expr = then_expr,
|
||||
.else_expr = try p.expectStatement(),
|
||||
.else_expr = try p.expectStatement(false),
|
||||
}),
|
||||
},
|
||||
});
|
||||
@ -1309,7 +1311,7 @@ const Parser = struct {
|
||||
}
|
||||
};
|
||||
_ = try p.parsePayload();
|
||||
const else_expr = try p.expectStatement();
|
||||
const else_expr = try p.expectStatement(false);
|
||||
return p.addNode(.{
|
||||
.tag = .@"while",
|
||||
.main_token = while_token,
|
||||
|
||||
@ -4233,6 +4233,30 @@ test "zig fmt: remove newlines surrounding doc comment within container decl" {
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: invalid else branch statement" {
|
||||
try testError(
|
||||
\\comptime {
|
||||
\\ if (true) {} else var a = 0;
|
||||
\\ if (true) {} else defer {}
|
||||
\\}
|
||||
\\comptime {
|
||||
\\ while (true) {} else var a = 0;
|
||||
\\ while (true) {} else defer {}
|
||||
\\}
|
||||
\\comptime {
|
||||
\\ for ("") |_| {} else var a = 0;
|
||||
\\ for ("") |_| {} else defer {}
|
||||
\\}
|
||||
, &[_]Error{
|
||||
.expected_statement,
|
||||
.expected_statement,
|
||||
.expected_statement,
|
||||
.expected_statement,
|
||||
.expected_statement,
|
||||
.expected_statement,
|
||||
});
|
||||
}
|
||||
|
||||
test "zig fmt: anytype struct field" {
|
||||
try testError(
|
||||
\\pub const Pointer = struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user