Commit cb3a818699
Changed files (5)
lib
test
stage1
behavior
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,
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;
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 };
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);
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();
+}