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 {...@@ -926,6 +926,7 @@ pub const Node = struct {
926 if (i < 1) return node;926 if (i < 1) return node;
927 i -= 1;927 i -= 1;
928 },928 },
929 .Invalid => unreachable,
929 }930 }
930931
931 if (self.body_node) |body_node| {932 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...@@ -172,6 +172,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
172 .ExpectedPubItem = .{ .token = it.index },172 .ExpectedPubItem = .{ .token = it.index },
173 });173 });
174 // ignore this pub174 // ignore this pub
175 continue;
175 }176 }
176177
177 if (parseContainerField(arena, it, tree) catch |err| switch (err) {178 if (parseContainerField(arena, it, tree) catch |err| switch (err) {
...@@ -1017,7 +1018,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -1017,7 +1018,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
1017 const node = try arena.create(Node.ControlFlowExpression);1018 const node = try arena.create(Node.ControlFlowExpression);
1018 node.* = .{1019 node.* = .{
1019 .ltoken = token,1020 .ltoken = token,
1020 .kind = Node.ControlFlowExpression.Kind{ .Break = label },1021 .kind = .{ .Break = label },
1021 .rhs = expr_node,1022 .rhs = expr_node,
1022 };1023 };
1023 return &node.base;1024 return &node.base;
...@@ -1053,7 +1054,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -1053,7 +1054,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
1053 const node = try arena.create(Node.ControlFlowExpression);1054 const node = try arena.create(Node.ControlFlowExpression);
1054 node.* = .{1055 node.* = .{
1055 .ltoken = token,1056 .ltoken = token,
1056 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },1057 .kind = .{ .Continue = label },
1057 .rhs = null,1058 .rhs = null,
1058 };1059 };
1059 return &node.base;1060 return &node.base;
...@@ -1077,7 +1078,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -1077,7 +1078,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
1077 const node = try arena.create(Node.ControlFlowExpression);1078 const node = try arena.create(Node.ControlFlowExpression);
1078 node.* = .{1079 node.* = .{
1079 .ltoken = token,1080 .ltoken = token,
1080 .kind = Node.ControlFlowExpression.Kind.Return,1081 .kind = .Return,
1081 .rhs = expr_node,1082 .rhs = expr_node,
1082 };1083 };
1083 return &node.base;1084 return &node.base;
...@@ -1322,7 +1323,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1322,7 +1323,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1322 try tree.errors.push(.{1323 try tree.errors.push(.{
1323 .ExpectedParamList = .{ .token = it.index },1324 .ExpectedParamList = .{ .token = it.index },
1324 });1325 });
1325 return null;1326 // ignore this, continue parsing
1327 return res;
1326 };1328 };
1327 const node = try arena.create(Node.SuffixOp);1329 const node = try arena.create(Node.SuffixOp);
1328 node.* = .{1330 node.* = .{
...@@ -2908,7 +2910,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2908,7 +2910,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2908 try tree.errors.push(.{2910 try tree.errors.push(.{
2909 .ExpectedParamList = .{ .token = it.index },2911 .ExpectedParamList = .{ .token = it.index },
2910 });2912 });
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;
2912 };2920 };
2913 const node = try arena.create(Node.BuiltinCall);2921 const node = try arena.create(Node.BuiltinCall);
2914 node.* = .{2922 node.* = .{
lib/std/zig/parser_test.zig+6-3
...@@ -67,19 +67,22 @@ test "recovery: continue after invalid decl" {...@@ -67,19 +67,22 @@ test "recovery: continue after invalid decl" {
67 \\fn foo {67 \\fn foo {
68 \\ inline;68 \\ inline;
69 \\}69 \\}
70 \\test "" {70 \\pub test "" {
71 \\ a && b;71 \\ async a && b;
72 \\}72 \\}
73 , &[_]Error{73 , &[_]Error{
74 .ExpectedToken,74 .ExpectedToken,
75 .ExpectedPubItem,
76 .ExpectedParamList,
75 .InvalidAnd,77 .InvalidAnd,
76 });78 });
77 try testError(79 try testError(
78 \\threadlocal test "" {80 \\threadlocal test "" {
79 \\ a && b;81 \\ @a && b;
80 \\}82 \\}
81 , &[_]Error{83 , &[_]Error{
82 .ExpectedVarDecl,84 .ExpectedVarDecl,
85 .ExpectedParamList,
83 .InvalidAnd,86 .InvalidAnd,
84 });87 });
85}88}