authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 00:16:56+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 00:16:56+03:00
logc3b76d091337ba60d2ccb3632b525e5a42d1f2c5
treedd57941c68786237721c2422c1a4a20680c21a73
parent1f81887a7863545d8b89bff6cc7d31941da0abf0
signature Commit is signed but in an unrecognized format.

recover from invalid builtin/async call


3 files changed, 20 insertions(+), 8 deletions(-)

lib/std/zig/ast.zig+1
......@@ -926,6 +926,7 @@ pub const Node = struct {
926926 if (i < 1) return node;
927927 i -= 1;
928928 },
929 .Invalid => unreachable,
929930 }
930931
931932 if (self.body_node) |body_node| {
lib/std/zig/parse.zig+13-5
......@@ -172,6 +172,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
172172 .ExpectedPubItem = .{ .token = it.index },
173173 });
174174 // ignore this pub
175 continue;
175176 }
176177
177178 if (parseContainerField(arena, it, tree) catch |err| switch (err) {
......@@ -1017,7 +1018,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
10171018 const node = try arena.create(Node.ControlFlowExpression);
10181019 node.* = .{
10191020 .ltoken = token,
1020 .kind = Node.ControlFlowExpression.Kind{ .Break = label },
1021 .kind = .{ .Break = label },
10211022 .rhs = expr_node,
10221023 };
10231024 return &node.base;
......@@ -1053,7 +1054,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
10531054 const node = try arena.create(Node.ControlFlowExpression);
10541055 node.* = .{
10551056 .ltoken = token,
1056 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },
1057 .kind = .{ .Continue = label },
10571058 .rhs = null,
10581059 };
10591060 return &node.base;
......@@ -1077,7 +1078,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
10771078 const node = try arena.create(Node.ControlFlowExpression);
10781079 node.* = .{
10791080 .ltoken = token,
1080 .kind = Node.ControlFlowExpression.Kind.Return,
1081 .kind = .Return,
10811082 .rhs = expr_node,
10821083 };
10831084 return &node.base;
......@@ -1322,7 +1323,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
13221323 try tree.errors.push(.{
13231324 .ExpectedParamList = .{ .token = it.index },
13241325 });
1325 return null;
1326 // ignore this, continue parsing
1327 return res;
13261328 };
13271329 const node = try arena.create(Node.SuffixOp);
13281330 node.* = .{
......@@ -2908,7 +2910,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
29082910 try tree.errors.push(.{
29092911 .ExpectedParamList = .{ .token = it.index },
29102912 });
2911 return error.ParseError;
2913
2914 // lets pretend this was an identifier so we can continue parsing
2915 const node = try arena.create(Node.Identifier);
2916 node.* = .{
2917 .token = token,
2918 };
2919 return &node.base;
29122920 };
29132921 const node = try arena.create(Node.BuiltinCall);
29142922 node.* = .{
lib/std/zig/parser_test.zig+6-3
......@@ -67,19 +67,22 @@ test "recovery: continue after invalid decl" {
6767 \\fn foo {
6868 \\ inline;
6969 \\}
70 \\test "" {
71 \\ a && b;
70 \\pub test "" {
71 \\ async a && b;
7272 \\}
7373 , &[_]Error{
7474 .ExpectedToken,
75 .ExpectedPubItem,
76 .ExpectedParamList,
7577 .InvalidAnd,
7678 });
7779 try testError(
7880 \\threadlocal test "" {
79 \\ a && b;
81 \\ @a && b;
8082 \\}
8183 , &[_]Error{
8284 .ExpectedVarDecl,
85 .ExpectedParamList,
8386 .InvalidAnd,
8487 });
8588}