diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-03-21 14:19:52 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-21 14:19:52 -0400 |
| commit | beea478acc2491289ec3e3bbdcec3b68f65d6e62 (patch) | |
| tree | 558ee509260855bbc521a11fec469220e185a2ae /lib | |
| parent | 153c6cf92e3459038c4ab8251a463163ac89b116 (diff) | |
| parent | 28dbc5883763fb2b87ef8d186a57c3971d3414bc (diff) | |
| download | zig-beea478acc2491289ec3e3bbdcec3b68f65d6e62.tar.gz zig-beea478acc2491289ec3e3bbdcec3b68f65d6e62.zip | |
Merge pull request #4764 from LemonBoy/fix-1265
ir: Allow errdefer with payload
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/zig/ast.zig | 7 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 7 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 13 | ||||
| -rw-r--r-- | lib/std/zig/render.zig | 3 |
4 files changed, 25 insertions, 5 deletions
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 8caaad2d4f..5445d3435f 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -1032,6 +1032,7 @@ pub const Node = struct { pub const Defer = struct { base: Node = Node{ .id = .Defer }, defer_token: TokenIndex, + payload: ?*Node, expr: *Node, pub fn iterate(self: *Defer, index: usize) ?*Node { @@ -1833,8 +1834,7 @@ pub const Node = struct { var i = index; switch (self.kind) { - .Break, - .Continue => |maybe_label| { + .Break, .Continue => |maybe_label| { if (maybe_label) |label| { if (i < 1) return label; i -= 1; @@ -1861,8 +1861,7 @@ pub const Node = struct { } switch (self.kind) { - .Break, - .Continue => |maybe_label| { + .Break, .Continue => |maybe_label| { if (maybe_label) |label| { return label.lastToken(); } diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index b0c3e6d759..2fcaaaab2d 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -465,7 +465,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No /// / KEYWORD_noasync BlockExprStatement /// / KEYWORD_suspend (SEMICOLON / BlockExprStatement) /// / KEYWORD_defer BlockExprStatement -/// / KEYWORD_errdefer BlockExprStatement +/// / KEYWORD_errdefer Payload? BlockExprStatement /// / IfStatement /// / LabeledStatement /// / SwitchExpr @@ -526,6 +526,10 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No const defer_token = eatToken(it, .Keyword_defer) orelse eatToken(it, .Keyword_errdefer); if (defer_token) |token| { + const payload = if (tree.tokens.at(token).id == .Keyword_errdefer) + try parsePayload(arena, it, tree) + else + null; const expr_node = try expectNode(arena, it, tree, parseBlockExprStatement, .{ .ExpectedBlockOrExpression = .{ .token = it.index }, }); @@ -533,6 +537,7 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No node.* = .{ .defer_token = token, .expr = expr_node, + .payload = payload, }; return &node.base; } diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index e1fe07a57c..894f726fb1 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -1,3 +1,16 @@ +test "zig fmt: errdefer with payload" { + try testCanonical( + \\pub fn main() anyerror!void { + \\ errdefer |a| x += 1; + \\ errdefer |a| {} + \\ errdefer |a| { + \\ x += 1; + \\ } + \\} + \\ + ); +} + test "zig fmt: noasync block" { try testCanonical( \\pub fn main() anyerror!void { diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 23dc9e02ac..37d058bebf 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -376,6 +376,9 @@ fn renderExpression( const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base); try renderToken(tree, stream, defer_node.defer_token, indent, start_col, Space.Space); + if (defer_node.payload) |payload| { + try renderExpression(allocator, stream, tree, indent, start_col, payload, Space.Space); + } return renderExpression(allocator, stream, tree, indent, start_col, defer_node.expr, space); }, .Comptime => { |
