diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index f34a6b3626..e01d406530 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -1564,7 +1564,9 @@ pub const Node = struct { pub const Op = union(enum) { AddressOf, ArrayType: ArrayInfo, - Await, + Await: struct { + noasync_token: ?TokenIndex = null, + }, BitNot, BoolNot, Cancel, diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 1b6afc1c1a..cadf25eef6 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -1129,7 +1129,7 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No /// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { - var maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync); + const maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync); if (maybe_async) |async_token| { const token_fn = eatToken(it, .Keyword_fn); if (async_token.ptr.id == .Keyword_async and token_fn != null) { @@ -2179,7 +2179,19 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { .MinusPercent => ops{ .NegationWrap = {} }, .Ampersand => ops{ .AddressOf = {} }, .Keyword_try => ops{ .Try = {} }, - .Keyword_await => ops{ .Await = {} }, + .Keyword_await => ops{ .Await = .{} }, + .Keyword_noasync => if (eatToken(it, .Keyword_await)) |await_tok| { + const node = try arena.create(Node.PrefixOp); + node.* = Node.PrefixOp{ + .op_token = await_tok, + .op = .{ .Await = .{ .noasync_token = token.index } }, + .rhs = undefined, // set by caller + }; + return &node.base; + } else { + putBackToken(it, token.index); + return null; + }, else => { putBackToken(it, token.index); return null; diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 03bb8d4222..28bf0c9ed5 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -1,3 +1,12 @@ +test "zig fmt: noasync await" { + try testCanonical( + \\fn foo() void { + \\ x = noasync await y; + \\} + \\ + ); +} + test "zig fmt: trailing comma in container declaration" { try testCanonical( \\const X = struct { foo: i32 }; diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 7dd3d63b0d..e322a91dc4 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -584,12 +584,18 @@ fn renderExpression( }, .Try, - .Await, .Cancel, .Resume, => { try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space); }, + + .Await => |await_info| { + if (await_info.noasync_token) |tok| { + try renderToken(tree, stream, tok, indent, start_col, Space.Space); + } + try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space); + }, } return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space); diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig index cfe82ff5a0..029a4edb7c 100644 --- a/test/stage1/behavior/async_fn.zig +++ b/test/stage1/behavior/async_fn.zig @@ -1510,3 +1510,20 @@ test "take address of temporary async frame" { }; S.doTheTest(); } + +test "noasync await" { + const S = struct { + fn doTheTest() void { + var frame = async foo(false); + expect(noasync await frame == 42); + } + + fn foo(want_suspend: bool) i32 { + if (want_suspend) { + suspend; + } + return 42; + } + }; + S.doTheTest(); +}