aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-03-21 14:19:52 -0400
committerGitHub <noreply@github.com>2020-03-21 14:19:52 -0400
commitbeea478acc2491289ec3e3bbdcec3b68f65d6e62 (patch)
tree558ee509260855bbc521a11fec469220e185a2ae /lib
parent153c6cf92e3459038c4ab8251a463163ac89b116 (diff)
parent28dbc5883763fb2b87ef8d186a57c3971d3414bc (diff)
downloadzig-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.zig7
-rw-r--r--lib/std/zig/parse.zig7
-rw-r--r--lib/std/zig/parser_test.zig13
-rw-r--r--lib/std/zig/render.zig3
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 => {