authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-16 12:29:01+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-16 12:29:01+03:00
loged62081d38736b2fabb3949fa821af2cf03dbe6e
tree99e63615c23af7d09a2403109c93c887c2d197d3
parent6ca0def499a610c638c38cd79d8df91035493083
signature Commit is signed but in an unrecognized format.

recover from missing semicolon after if stmt


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

lib/std/zig/parse.zig+10-13
...@@ -724,16 +724,12 @@ fn parseIfStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -724,16 +724,12 @@ fn parseIfStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
724 const if_prefix = if_node.cast(Node.If).?;724 const if_prefix = if_node.cast(Node.If).?;
725725
726 const block_expr = (try parseBlockExpr(arena, it, tree));726 const block_expr = (try parseBlockExpr(arena, it, tree));
727 const assign_expr = if (block_expr == null) blk: {727 const assign_expr = if (block_expr == null)
728 break :blk (try parseAssignExpr(arena, it, tree)) orelse null;728 try expectNode(arena, it, tree, parseAdditionExpr, .{
729 } else null;
730
731 if (block_expr == null and assign_expr == null) {
732 try tree.errors.push(.{
733 .ExpectedBlockOrAssignment = .{ .token = it.index },729 .ExpectedBlockOrAssignment = .{ .token = it.index },
734 });730 })
735 return error.ParseError;731 else
736 }732 null;
737733
738 const semicolon = if (assign_expr != null) eatToken(it, .Semicolon) else null;734 const semicolon = if (assign_expr != null) eatToken(it, .Semicolon) else null;
739735
...@@ -770,10 +766,9 @@ fn parseIfStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -770,10 +766,9 @@ fn parseIfStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
770 try tree.errors.push(.{766 try tree.errors.push(.{
771 .ExpectedSemiOrElse = .{ .token = it.index },767 .ExpectedSemiOrElse = .{ .token = it.index },
772 });768 });
773 return error.ParseError;
774 }769 }
775770
776 unreachable;771 return if_node;
777}772}
778773
779/// LabeledStatement <- BlockLabel? (Block / LoopStatement)774/// LabeledStatement <- BlockLabel? (Block / LoopStatement)
...@@ -879,7 +874,8 @@ fn parseForStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -879,7 +874,8 @@ fn parseForStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
879 try tree.errors.push(.{874 try tree.errors.push(.{
880 .ExpectedSemiOrElse = .{ .token = it.index },875 .ExpectedSemiOrElse = .{ .token = it.index },
881 });876 });
882 return null;877
878 return node;
883 }879 }
884880
885 return null;881 return null;
...@@ -941,7 +937,8 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -941,7 +937,8 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
941 try tree.errors.push(.{937 try tree.errors.push(.{
942 .ExpectedSemiOrElse = .{ .token = it.index },938 .ExpectedSemiOrElse = .{ .token = it.index },
943 });939 });
944 return null;940
941 return node;
945 }942 }
946943
947 return null;944 return null;
lib/std/zig/parser_test.zig+16
...@@ -184,6 +184,22 @@ test "recovery: invalid global error set access" {...@@ -184,6 +184,22 @@ test "recovery: invalid global error set access" {
184 });184 });
185}185}
186186
187test "recovery: missing semicolon after if, for, while stmt" {
188 try testError(
189 \\test "" {
190 \\ if (foo) bar
191 \\ for (foo) |a| bar
192 \\ while (foo) bar
193 \\ a && b;
194 \\}
195 , &[_]Error{
196 .ExpectedSemiOrElse,
197 .ExpectedSemiOrElse,
198 .ExpectedSemiOrElse,
199 .InvalidAnd,
200 });
201}
202
187test "zig fmt: top-level fields" {203test "zig fmt: top-level fields" {
188 try testCanonical(204 try testCanonical(
189 \\a: did_you_know,205 \\a: did_you_know,