authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-26 22:40:43+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-29 15:47:02+02:00
log34be5784a3f19658d15d1fb24bb07800cdb025c4
treeab1808cfc8fdadcb682d2d5f490162f7cb15d519
parent1829b6eab8dc52ad2961467e23bfb36055cc8583

parser: disallow defer and variable declaration as else branch

Closes #13658

2 files changed, 39 insertions(+), 13 deletions(-)

lib/std/zig/parse.zig+15-13
......@@ -950,13 +950,15 @@ const Parser = struct {
950950 /// / LabeledStatement
951951 /// / SwitchExpr
952952 /// / AssignExpr SEMICOLON
953 fn parseStatement(p: *Parser) Error!Node.Index {
953 fn parseStatement(p: *Parser, allow_defer_var: bool) Error!Node.Index {
954954 const comptime_token = p.eatToken(.keyword_comptime);
955955
956 const var_decl = try p.parseVarDecl();
957 if (var_decl != 0) {
958 try p.expectSemicolon(.expected_semi_after_decl, true);
959 return var_decl;
956 if (allow_defer_var) {
957 const var_decl = try p.parseVarDecl();
958 if (var_decl != 0) {
959 try p.expectSemicolon(.expected_semi_after_decl, true);
960 return var_decl;
961 }
960962 }
961963
962964 if (comptime_token) |token| {
......@@ -993,7 +995,7 @@ const Parser = struct {
993995 },
994996 });
995997 },
996 .keyword_defer => return p.addNode(.{
998 .keyword_defer => if (allow_defer_var) return p.addNode(.{
997999 .tag = .@"defer",
9981000 .main_token = p.nextToken(),
9991001 .data = .{
......@@ -1001,7 +1003,7 @@ const Parser = struct {
10011003 .rhs = try p.expectBlockExprStatement(),
10021004 },
10031005 }),
1004 .keyword_errdefer => return p.addNode(.{
1006 .keyword_errdefer => if (allow_defer_var) return p.addNode(.{
10051007 .tag = .@"errdefer",
10061008 .main_token = p.nextToken(),
10071009 .data = .{
......@@ -1040,8 +1042,8 @@ const Parser = struct {
10401042 return null_node;
10411043 }
10421044
1043 fn expectStatement(p: *Parser) !Node.Index {
1044 const statement = try p.parseStatement();
1045 fn expectStatement(p: *Parser, allow_defer_var: bool) !Node.Index {
1046 const statement = try p.parseStatement(allow_defer_var);
10451047 if (statement == 0) {
10461048 return p.fail(.expected_statement);
10471049 }
......@@ -1053,7 +1055,7 @@ const Parser = struct {
10531055 /// statement, returns 0.
10541056 fn expectStatementRecoverable(p: *Parser) Error!Node.Index {
10551057 while (true) {
1056 return p.expectStatement() catch |err| switch (err) {
1058 return p.expectStatement(true) catch |err| switch (err) {
10571059 error.OutOfMemory => return error.OutOfMemory,
10581060 error.ParseError => {
10591061 p.findNextStmt(); // Try to skip to the next statement.
......@@ -1114,7 +1116,7 @@ const Parser = struct {
11141116 });
11151117 };
11161118 _ = try p.parsePayload();
1117 const else_expr = try p.expectStatement();
1119 const else_expr = try p.expectStatement(false);
11181120 return p.addNode(.{
11191121 .tag = .@"if",
11201122 .main_token = if_token,
......@@ -1226,7 +1228,7 @@ const Parser = struct {
12261228 .lhs = array_expr,
12271229 .rhs = try p.addExtra(Node.If{
12281230 .then_expr = then_expr,
1229 .else_expr = try p.expectStatement(),
1231 .else_expr = try p.expectStatement(false),
12301232 }),
12311233 },
12321234 });
......@@ -1309,7 +1311,7 @@ const Parser = struct {
13091311 }
13101312 };
13111313 _ = try p.parsePayload();
1312 const else_expr = try p.expectStatement();
1314 const else_expr = try p.expectStatement(false);
13131315 return p.addNode(.{
13141316 .tag = .@"while",
13151317 .main_token = while_token,
lib/std/zig/parser_test.zig+24
......@@ -4233,6 +4233,30 @@ test "zig fmt: remove newlines surrounding doc comment within container decl" {
42334233 );
42344234}
42354235
4236test "zig fmt: invalid else branch statement" {
4237 try testError(
4238 \\comptime {
4239 \\ if (true) {} else var a = 0;
4240 \\ if (true) {} else defer {}
4241 \\}
4242 \\comptime {
4243 \\ while (true) {} else var a = 0;
4244 \\ while (true) {} else defer {}
4245 \\}
4246 \\comptime {
4247 \\ for ("") |_| {} else var a = 0;
4248 \\ for ("") |_| {} else defer {}
4249 \\}
4250 , &[_]Error{
4251 .expected_statement,
4252 .expected_statement,
4253 .expected_statement,
4254 .expected_statement,
4255 .expected_statement,
4256 .expected_statement,
4257 });
4258}
4259
42364260test "zig fmt: anytype struct field" {
42374261 try testError(
42384262 \\pub const Pointer = struct {