| author | |
| committer | |
| log | cb3a818699649a985d5879151936b3b88ffddfa4 |
| tree | f2f6f383314fa90d329c79c90991dd26428c176b |
| parent | 72805fd66e732e29637872f540371c30cb9f8b27 |
| signature |
5 files changed, 50 insertions(+), 4 deletions(-)
lib/std/zig/ast.zig+3-1| ... | @@ -1564,7 +1564,9 @@ pub const Node = struct { | ... | @@ -1564,7 +1564,9 @@ pub const Node = struct { |
| 1564 | pub const Op = union(enum) { | 1564 | pub const Op = union(enum) { |
| 1565 | AddressOf, | 1565 | AddressOf, |
| 1566 | ArrayType: ArrayInfo, | 1566 | ArrayType: ArrayInfo, |
| 1567 | Await, | 1567 | Await: struct { |
| 1568 | noasync_token: ?TokenIndex = null, | ||
| 1569 | }, | ||
| 1568 | BitNot, | 1570 | BitNot, |
| 1569 | BoolNot, | 1571 | BoolNot, |
| 1570 | Cancel, | 1572 | Cancel, |
lib/std/zig/parse.zig+14-2| ... | @@ -1129,7 +1129,7 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No | ... | @@ -1129,7 +1129,7 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No |
| 1129 | /// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments | 1129 | /// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments |
| 1130 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* | 1130 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 1131 | fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 1131 | fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1132 | var maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync); | 1132 | const maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync); |
| 1133 | if (maybe_async) |async_token| { | 1133 | if (maybe_async) |async_token| { |
| 1134 | const token_fn = eatToken(it, .Keyword_fn); | 1134 | const token_fn = eatToken(it, .Keyword_fn); |
| 1135 | if (async_token.ptr.id == .Keyword_async and token_fn != null) { | 1135 | if (async_token.ptr.id == .Keyword_async and token_fn != null) { |
| ... | @@ -2179,7 +2179,19 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -2179,7 +2179,19 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 2179 | .MinusPercent => ops{ .NegationWrap = {} }, | 2179 | .MinusPercent => ops{ .NegationWrap = {} }, |
| 2180 | .Ampersand => ops{ .AddressOf = {} }, | 2180 | .Ampersand => ops{ .AddressOf = {} }, |
| 2181 | .Keyword_try => ops{ .Try = {} }, | 2181 | .Keyword_try => ops{ .Try = {} }, |
| 2182 | .Keyword_await => ops{ .Await = {} }, | 2182 | .Keyword_await => ops{ .Await = .{} }, |
| 2183 | .Keyword_noasync => if (eatToken(it, .Keyword_await)) |await_tok| { | ||
| 2184 | const node = try arena.create(Node.PrefixOp); | ||
| 2185 | node.* = Node.PrefixOp{ | ||
| 2186 | .op_token = await_tok, | ||
| 2187 | .op = .{ .Await = .{ .noasync_token = token.index } }, | ||
| 2188 | .rhs = undefined, // set by caller | ||
| 2189 | }; | ||
| 2190 | return &node.base; | ||
| 2191 | } else { | ||
| 2192 | putBackToken(it, token.index); | ||
| 2193 | return null; | ||
| 2194 | }, | ||
| 2183 | else => { | 2195 | else => { |
| 2184 | putBackToken(it, token.index); | 2196 | putBackToken(it, token.index); |
| 2185 | return null; | 2197 | return null; |
lib/std/zig/parser_test.zig+9| ... | @@ -1,3 +1,12 @@ | ... | @@ -1,3 +1,12 @@ |
| 1 | test "zig fmt: noasync await" { | ||
| 2 | try testCanonical( | ||
| 3 | \\fn foo() void { | ||
| 4 | \\ x = noasync await y; | ||
| 5 | \\} | ||
| 6 | \\ | ||
| 7 | ); | ||
| 8 | } | ||
| 9 | |||
| 1 | test "zig fmt: trailing comma in container declaration" { | 10 | test "zig fmt: trailing comma in container declaration" { |
| 2 | try testCanonical( | 11 | try testCanonical( |
| 3 | \\const X = struct { foo: i32 }; | 12 | \\const X = struct { foo: i32 }; |
lib/std/zig/render.zig+7-1| ... | @@ -584,12 +584,18 @@ fn renderExpression( | ... | @@ -584,12 +584,18 @@ fn renderExpression( |
| 584 | }, | 584 | }, |
| 585 | 585 | ||
| 586 | .Try, | 586 | .Try, |
| 587 | .Await, | ||
| 588 | .Cancel, | 587 | .Cancel, |
| 589 | .Resume, | 588 | .Resume, |
| 590 | => { | 589 | => { |
| 591 | try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space); | 590 | try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space); |
| 592 | }, | 591 | }, |
| 592 | |||
| 593 | .Await => |await_info| { | ||
| 594 | if (await_info.noasync_token) |tok| { | ||
| 595 | try renderToken(tree, stream, tok, indent, start_col, Space.Space); | ||
| 596 | } | ||
| 597 | try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space); | ||
| 598 | }, | ||
| 593 | } | 599 | } |
| 594 | 600 | ||
| 595 | return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space); | 601 | return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space); |
test/stage1/behavior/async_fn.zig+17| ... | @@ -1510,3 +1510,20 @@ test "take address of temporary async frame" { | ... | @@ -1510,3 +1510,20 @@ test "take address of temporary async frame" { |
| 1510 | }; | 1510 | }; |
| 1511 | S.doTheTest(); | 1511 | S.doTheTest(); |
| 1512 | } | 1512 | } |
| 1513 | |||
| 1514 | test "noasync await" { | ||
| 1515 | const S = struct { | ||
| 1516 | fn doTheTest() void { | ||
| 1517 | var frame = async foo(false); | ||
| 1518 | expect(noasync await frame == 42); | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | fn foo(want_suspend: bool) i32 { | ||
| 1522 | if (want_suspend) { | ||
| 1523 | suspend; | ||
| 1524 | } | ||
| 1525 | return 42; | ||
| 1526 | } | ||
| 1527 | }; | ||
| 1528 | S.doTheTest(); | ||
| 1529 | } |