Commit e07b467c7c
Changed files (3)
lib
lib/std/zig/ast.zig
@@ -13,7 +13,6 @@ pub const Tree = struct {
token_ids: []const Token.Id,
token_locs: []const Token.Loc,
errors: []const Error,
- /// undefined on parse error (when errors field is not empty)
root_node: *Node.Root,
arena: std.heap.ArenaAllocator.State,
lib/std/zig/parse.zig
@@ -878,34 +878,32 @@ const Parser = struct {
return node;
}
- if (try p.parseAssignExpr()) |assign_expr| {
- for_prefix.body = assign_expr;
-
- if (p.eatToken(.Semicolon) != null) return node;
-
- if (p.eatToken(.Keyword_else)) |else_token| {
- const statement_node = try p.expectNode(parseStatement, .{
- .ExpectedStatement = .{ .token = p.tok_i },
- });
+ for_prefix.body = try p.expectNode(parseAssignExpr, .{
+ .ExpectedBlockOrAssignment = .{ .token = p.tok_i },
+ });
- const else_node = try p.arena.allocator.create(Node.Else);
- else_node.* = .{
- .else_token = else_token,
- .payload = null,
- .body = statement_node,
- };
- for_prefix.@"else" = else_node;
- return node;
- }
+ if (p.eatToken(.Semicolon) != null) return node;
- try p.errors.append(p.gpa, .{
- .ExpectedSemiOrElse = .{ .token = p.tok_i },
+ if (p.eatToken(.Keyword_else)) |else_token| {
+ const statement_node = try p.expectNode(parseStatement, .{
+ .ExpectedStatement = .{ .token = p.tok_i },
});
+ const else_node = try p.arena.allocator.create(Node.Else);
+ else_node.* = .{
+ .else_token = else_token,
+ .payload = null,
+ .body = statement_node,
+ };
+ for_prefix.@"else" = else_node;
return node;
}
- return null;
+ try p.errors.append(p.gpa, .{
+ .ExpectedSemiOrElse = .{ .token = p.tok_i },
+ });
+
+ return node;
}
/// WhileStatement
@@ -939,36 +937,35 @@ const Parser = struct {
return node;
}
- if (try p.parseAssignExpr()) |assign_expr_node| {
- while_prefix.body = assign_expr_node;
-
- if (p.eatToken(.Semicolon) != null) return node;
- if (p.eatToken(.Keyword_else)) |else_token| {
- const payload = try p.parsePayload();
+ while_prefix.body = try p.expectNode(parseAssignExpr, .{
+ .ExpectedBlockOrAssignment = .{ .token = p.tok_i },
+ });
- const statement_node = try p.expectNode(parseStatement, .{
- .ExpectedStatement = .{ .token = p.tok_i },
- });
+ if (p.eatToken(.Semicolon) != null) return node;
- const else_node = try p.arena.allocator.create(Node.Else);
- else_node.* = .{
- .else_token = else_token,
- .payload = payload,
- .body = statement_node,
- };
- while_prefix.@"else" = else_node;
- return node;
- }
+ if (p.eatToken(.Keyword_else)) |else_token| {
+ const payload = try p.parsePayload();
- try p.errors.append(p.gpa, .{
- .ExpectedSemiOrElse = .{ .token = p.tok_i },
+ const statement_node = try p.expectNode(parseStatement, .{
+ .ExpectedStatement = .{ .token = p.tok_i },
});
+ const else_node = try p.arena.allocator.create(Node.Else);
+ else_node.* = .{
+ .else_token = else_token,
+ .payload = payload,
+ .body = statement_node,
+ };
+ while_prefix.@"else" = else_node;
return node;
}
- return null;
+ try p.errors.append(p.gpa, .{
+ .ExpectedSemiOrElse = .{ .token = p.tok_i },
+ });
+
+ return node;
}
/// BlockExprStatement
lib/std/zig/parser_test.zig
@@ -210,6 +210,19 @@ test "recovery: invalid comptime" {
});
}
+test "recovery: missing block after for/while loops" {
+ try testError(
+ \\test "" { while (foo) }
+ , &[_]Error{
+ .ExpectedBlockOrAssignment,
+ });
+ try testError(
+ \\test "" { for (foo) |bar| }
+ , &[_]Error{
+ .ExpectedBlockOrAssignment,
+ });
+}
+
test "zig fmt: if statment" {
try testCanonical(
\\test "" {