| author | |
| committer | |
| log | 29e5e98eed2161c37edbce41b96c2999eb1f3177 |
| tree | af80f2749253cc4f5c61c14c9f37519dc9146ab8 |
| parent | 4ec6d174adc038741f1274d157f5253752eb8d51 |
| parent | eabf378a56e0cd9720f43c36b85025228c4406d8 |
| signature |
stage1: Require a block after suspend10 files changed, 122 insertions(+), 91 deletions(-)
doc/langref.html.in+5-5| ... | ... | @@ -6528,7 +6528,7 @@ test "suspend with no resume" { |
| 6528 | 6528 | |
| 6529 | 6529 | fn func() void { |
| 6530 | 6530 | x += 1; |
| 6531 | suspend; | |
| 6531 | suspend {} | |
| 6532 | 6532 | // This line is never reached because the suspend has no matching resume. |
| 6533 | 6533 | x += 1; |
| 6534 | 6534 | } |
| ... | ... | @@ -6593,7 +6593,7 @@ fn testResumeFromSuspend(my_result: *i32) void { |
| 6593 | 6593 | resume @frame(); |
| 6594 | 6594 | } |
| 6595 | 6595 | my_result.* += 1; |
| 6596 | suspend; | |
| 6596 | suspend {} | |
| 6597 | 6597 | my_result.* += 1; |
| 6598 | 6598 | } |
| 6599 | 6599 | {#code_end#} |
| ... | ... | @@ -6632,7 +6632,7 @@ fn amain() void { |
| 6632 | 6632 | } |
| 6633 | 6633 | |
| 6634 | 6634 | fn func() void { |
| 6635 | suspend; | |
| 6635 | suspend {} | |
| 6636 | 6636 | } |
| 6637 | 6637 | {#code_end#} |
| 6638 | 6638 | <p> |
| ... | ... | @@ -6934,7 +6934,7 @@ test "async fn pointer in a struct field" { |
| 6934 | 6934 | fn func(y: *i32) void { |
| 6935 | 6935 | defer y.* += 2; |
| 6936 | 6936 | y.* += 1; |
| 6937 | suspend; | |
| 6937 | suspend {} | |
| 6938 | 6938 | } |
| 6939 | 6939 | {#code_end#} |
| 6940 | 6940 | {#header_close#} |
| ... | ... | @@ -7667,7 +7667,7 @@ test "heap allocated frame" { |
| 7667 | 7667 | } |
| 7668 | 7668 | |
| 7669 | 7669 | fn func() void { |
| 7670 | suspend; | |
| 7670 | suspend {} | |
| 7671 | 7671 | } |
| 7672 | 7672 | {#code_end#} |
| 7673 | 7673 | {#header_close#} |
lib/std/event/rwlock.zig+2-2| ... | ... | @@ -264,7 +264,7 @@ var shared_test_data = [1]i32{0} ** 10; |
| 264 | 264 | var shared_test_index: usize = 0; |
| 265 | 265 | var shared_count: usize = 0; |
| 266 | 266 | fn writeRunner(lock: *RwLock) callconv(.Async) void { |
| 267 | suspend; // resumed by onNextTick | |
| 267 | suspend {} // resumed by onNextTick | |
| 268 | 268 | |
| 269 | 269 | var i: usize = 0; |
| 270 | 270 | while (i < shared_test_data.len) : (i += 1) { |
| ... | ... | @@ -281,7 +281,7 @@ fn writeRunner(lock: *RwLock) callconv(.Async) void { |
| 281 | 281 | } |
| 282 | 282 | } |
| 283 | 283 | fn readRunner(lock: *RwLock) callconv(.Async) void { |
| 284 | suspend; // resumed by onNextTick | |
| 284 | suspend {} // resumed by onNextTick | |
| 285 | 285 | std.time.sleep(1); |
| 286 | 286 | |
| 287 | 287 | var i: usize = 0; |
lib/std/zig/parse.zig+2-1| ... | ... | @@ -852,7 +852,7 @@ const Parser = struct { |
| 852 | 852 | /// <- KEYWORD_comptime? VarDecl |
| 853 | 853 | /// / KEYWORD_comptime BlockExprStatement |
| 854 | 854 | /// / KEYWORD_nosuspend BlockExprStatement |
| 855 | /// / KEYWORD_suspend (SEMICOLON / BlockExprStatement) | |
| 855 | /// / KEYWORD_suspend BlockExprStatement | |
| 856 | 856 | /// / KEYWORD_defer BlockExprStatement |
| 857 | 857 | /// / KEYWORD_errdefer Payload? BlockExprStatement |
| 858 | 858 | /// / IfStatement |
| ... | ... | @@ -892,6 +892,7 @@ const Parser = struct { |
| 892 | 892 | }, |
| 893 | 893 | .keyword_suspend => { |
| 894 | 894 | const token = p.nextToken(); |
| 895 | // TODO remove this special case when 0.9.0 is released. | |
| 895 | 896 | const block_expr: Node.Index = if (p.eatToken(.semicolon) != null) |
| 896 | 897 | 0 |
| 897 | 898 | else |
lib/std/zig/parser_test.zig+33-3| ... | ... | @@ -40,6 +40,21 @@ test "zig fmt: rewrite inline functions as callconv(.Inline)" { |
| 40 | 40 | ); |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | // TODO Remove this after zig 0.9.0 is released. | |
| 44 | test "zig fmt: rewrite suspend without block expression" { | |
| 45 | try testTransform( | |
| 46 | \\fn foo() void { | |
| 47 | \\ suspend; | |
| 48 | \\} | |
| 49 | \\ | |
| 50 | , | |
| 51 | \\fn foo() void { | |
| 52 | \\ suspend {} | |
| 53 | \\} | |
| 54 | \\ | |
| 55 | ); | |
| 56 | } | |
| 57 | ||
| 43 | 58 | test "zig fmt: simple top level comptime block" { |
| 44 | 59 | try testCanonical( |
| 45 | 60 | \\// line comment |
| ... | ... | @@ -3665,9 +3680,9 @@ test "zig fmt: async functions" { |
| 3665 | 3680 | \\fn simpleAsyncFn() void { |
| 3666 | 3681 | \\ const a = async a.b(); |
| 3667 | 3682 | \\ x += 1; |
| 3668 | \\ suspend; | |
| 3683 | \\ suspend {} | |
| 3669 | 3684 | \\ x += 1; |
| 3670 | \\ suspend; | |
| 3685 | \\ suspend {} | |
| 3671 | 3686 | \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable; |
| 3672 | 3687 | \\ await p; |
| 3673 | 3688 | \\} |
| ... | ... | @@ -5022,6 +5037,21 @@ test "recovery: invalid comptime" { |
| 5022 | 5037 | }); |
| 5023 | 5038 | } |
| 5024 | 5039 | |
| 5040 | test "recovery: missing block after suspend" { | |
| 5041 | // TODO Enable this after zig 0.9.0 is released. | |
| 5042 | if (true) return error.SkipZigTest; | |
| 5043 | ||
| 5044 | try testError( | |
| 5045 | \\fn foo() void { | |
| 5046 | \\ suspend; | |
| 5047 | \\ nosuspend; | |
| 5048 | \\} | |
| 5049 | , &[_]Error{ | |
| 5050 | .expected_block_or_expr, | |
| 5051 | .expected_block_or_expr, | |
| 5052 | }); | |
| 5053 | } | |
| 5054 | ||
| 5025 | 5055 | test "recovery: missing block after for/while loops" { |
| 5026 | 5056 | try testError( |
| 5027 | 5057 | \\test "" { while (foo) } |
| ... | ... | @@ -5165,7 +5195,7 @@ fn testError(source: []const u8, expected_errors: []const Error) !void { |
| 5165 | 5195 | var tree = try std.zig.parse(std.testing.allocator, source); |
| 5166 | 5196 | defer tree.deinit(std.testing.allocator); |
| 5167 | 5197 | |
| 5168 | std.testing.expect(tree.errors.len == expected_errors.len); | |
| 5198 | std.testing.expectEqual(expected_errors.len, tree.errors.len); | |
| 5169 | 5199 | for (expected_errors) |expected, i| { |
| 5170 | 5200 | std.testing.expectEqual(expected, tree.errors[i].tag); |
| 5171 | 5201 | } |
lib/std/zig/render.zig+6-1| ... | ... | @@ -269,7 +269,12 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I |
| 269 | 269 | try renderToken(ais, tree, suspend_token, .space); |
| 270 | 270 | return renderExpression(gpa, ais, tree, body, space); |
| 271 | 271 | } else { |
| 272 | return renderToken(ais, tree, suspend_token, space); | |
| 272 | // TODO remove this special case when 0.9.0 is released. | |
| 273 | assert(space == .semicolon); | |
| 274 | try renderToken(ais, tree, suspend_token, .space); | |
| 275 | try ais.writer().writeAll("{}"); | |
| 276 | try ais.insertNewline(); | |
| 277 | return; | |
| 273 | 278 | } |
| 274 | 279 | }, |
| 275 | 280 |
src/stage1/ir.cpp+7-9| ... | ... | @@ -9534,7 +9534,7 @@ static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNo |
| 9534 | 9534 | |
| 9535 | 9535 | Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope); |
| 9536 | 9536 | // purposefully pass null for result_loc and let EndExpr handle it |
| 9537 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); | |
| 9537 | return ir_gen_node_extra(irb, node->data.nosuspend_expr.expr, child_scope, lval, nullptr); | |
| 9538 | 9538 | } |
| 9539 | 9539 | |
| 9540 | 9540 | static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { |
| ... | ... | @@ -10199,14 +10199,12 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode |
| 10199 | 10199 | } |
| 10200 | 10200 | |
| 10201 | 10201 | IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(irb, parent_scope, node); |
| 10202 | if (node->data.suspend.block != nullptr) { | |
| 10203 | ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); | |
| 10204 | Scope *child_scope = &suspend_scope->base; | |
| 10205 | IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); | |
| 10206 | if (susp_res == irb->codegen->invalid_inst_src) | |
| 10207 | return irb->codegen->invalid_inst_src; | |
| 10208 | ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); | |
| 10209 | } | |
| 10202 | ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); | |
| 10203 | Scope *child_scope = &suspend_scope->base; | |
| 10204 | IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); | |
| 10205 | if (susp_res == irb->codegen->invalid_inst_src) | |
| 10206 | return irb->codegen->invalid_inst_src; | |
| 10207 | ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); | |
| 10210 | 10208 | |
| 10211 | 10209 | return ir_mark_gen(ir_build_suspend_finish_src(irb, parent_scope, node, begin)); |
| 10212 | 10210 | } |
src/stage1/parser.cpp+1-4| ... | ... | @@ -946,10 +946,7 @@ static AstNode *ast_parse_statement(ParseContext *pc) { |
| 946 | 946 | |
| 947 | 947 | Token *suspend = eat_token_if(pc, TokenIdKeywordSuspend); |
| 948 | 948 | if (suspend != nullptr) { |
| 949 | AstNode *statement = nullptr; | |
| 950 | if (eat_token_if(pc, TokenIdSemicolon) == nullptr) | |
| 951 | statement = ast_expect(pc, ast_parse_block_expr_statement); | |
| 952 | ||
| 949 | AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement); | |
| 953 | 950 | AstNode *res = ast_create_node(pc, NodeTypeSuspend, suspend); |
| 954 | 951 | res->data.suspend.block = statement; |
| 955 | 952 | return res; |
test/compile_errors.zig+7-7| ... | ... | @@ -1021,7 +1021,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1021 | 1021 | \\export fn entry() void { |
| 1022 | 1022 | \\ nosuspend { |
| 1023 | 1023 | \\ const bar = async foo(); |
| 1024 | \\ suspend; | |
| 1024 | \\ suspend {} | |
| 1025 | 1025 | \\ resume bar; |
| 1026 | 1026 | \\ } |
| 1027 | 1027 | \\} |
| ... | ... | @@ -2120,7 +2120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2120 | 2120 | \\ non_async_fn = func; |
| 2121 | 2121 | \\} |
| 2122 | 2122 | \\fn func() void { |
| 2123 | \\ suspend; | |
| 2123 | \\ suspend {} | |
| 2124 | 2124 | \\} |
| 2125 | 2125 | , &[_][]const u8{ |
| 2126 | 2126 | "tmp.zig:5:1: error: 'func' cannot be async", |
| ... | ... | @@ -2198,7 +2198,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2198 | 2198 | \\ var x: anyframe = &f; |
| 2199 | 2199 | \\} |
| 2200 | 2200 | \\fn func() void { |
| 2201 | \\ suspend; | |
| 2201 | \\ suspend {} | |
| 2202 | 2202 | \\} |
| 2203 | 2203 | , &[_][]const u8{ |
| 2204 | 2204 | "tmp.zig:3:12: error: expected type 'anyframe', found '*const @Frame(func)'", |
| ... | ... | @@ -2231,10 +2231,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2231 | 2231 | \\ frame = async bar(); |
| 2232 | 2232 | \\} |
| 2233 | 2233 | \\fn foo() void { |
| 2234 | \\ suspend; | |
| 2234 | \\ suspend {} | |
| 2235 | 2235 | \\} |
| 2236 | 2236 | \\fn bar() void { |
| 2237 | \\ suspend; | |
| 2237 | \\ suspend {} | |
| 2238 | 2238 | \\} |
| 2239 | 2239 | , &[_][]const u8{ |
| 2240 | 2240 | "tmp.zig:3:13: error: expected type '*@Frame(bar)', found '*@Frame(foo)'", |
| ... | ... | @@ -2269,7 +2269,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2269 | 2269 | \\ var result = await frame; |
| 2270 | 2270 | \\} |
| 2271 | 2271 | \\fn func() void { |
| 2272 | \\ suspend; | |
| 2272 | \\ suspend {} | |
| 2273 | 2273 | \\} |
| 2274 | 2274 | , &[_][]const u8{ |
| 2275 | 2275 | "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", |
| ... | ... | @@ -2347,7 +2347,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2347 | 2347 | \\ bar(); |
| 2348 | 2348 | \\} |
| 2349 | 2349 | \\fn bar() void { |
| 2350 | \\ suspend; | |
| 2350 | \\ suspend {} | |
| 2351 | 2351 | \\} |
| 2352 | 2352 | , &[_][]const u8{ |
| 2353 | 2353 | "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", |
test/runtime_safety.zig+17-17| ... | ... | @@ -13,7 +13,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 13 | 13 | |
| 14 | 14 | cases.addRuntimeSafety("switch on corrupted enum value", |
| 15 | 15 | \\const std = @import("std"); |
| 16 | ++ check_panic_msg ++ | |
| 16 | ++ check_panic_msg ++ | |
| 17 | 17 | \\const E = enum(u32) { |
| 18 | 18 | \\ X = 1, |
| 19 | 19 | \\}; |
| ... | ... | @@ -28,7 +28,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 28 | 28 | |
| 29 | 29 | cases.addRuntimeSafety("switch on corrupted union value", |
| 30 | 30 | \\const std = @import("std"); |
| 31 | ++ check_panic_msg ++ | |
| 31 | ++ check_panic_msg ++ | |
| 32 | 32 | \\const U = union(enum(u32)) { |
| 33 | 33 | \\ X: u8, |
| 34 | 34 | \\}; |
| ... | ... | @@ -54,7 +54,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 54 | 54 | |
| 55 | 55 | cases.addRuntimeSafety("@tagName on corrupted enum value", |
| 56 | 56 | \\const std = @import("std"); |
| 57 | ++ check_panic_msg ++ | |
| 57 | ++ check_panic_msg ++ | |
| 58 | 58 | \\const E = enum(u32) { |
| 59 | 59 | \\ X = 1, |
| 60 | 60 | \\}; |
| ... | ... | @@ -67,7 +67,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 67 | 67 | |
| 68 | 68 | cases.addRuntimeSafety("@tagName on corrupted union value", |
| 69 | 69 | \\const std = @import("std"); |
| 70 | ++ check_panic_msg ++ | |
| 70 | ++ check_panic_msg ++ | |
| 71 | 71 | \\const U = union(enum(u32)) { |
| 72 | 72 | \\ X: u8, |
| 73 | 73 | \\}; |
| ... | ... | @@ -92,7 +92,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 92 | 92 | |
| 93 | 93 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 94 | 94 | \\const std = @import("std"); |
| 95 | ++ check_panic_msg ++ | |
| 95 | ++ check_panic_msg ++ | |
| 96 | 96 | \\pub fn main() void { |
| 97 | 97 | \\ var buf = [4]u8{'a','b','c',0}; |
| 98 | 98 | \\ const slice = buf[0..4 :0]; |
| ... | ... | @@ -100,7 +100,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 100 | 100 | ); |
| 101 | 101 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 102 | 102 | \\const std = @import("std"); |
| 103 | ++ check_panic_msg ++ | |
| 103 | ++ check_panic_msg ++ | |
| 104 | 104 | \\pub fn main() void { |
| 105 | 105 | \\ var buf = [4]u8{'a','b','c',0}; |
| 106 | 106 | \\ const slice = buf[0..:0]; |
| ... | ... | @@ -108,7 +108,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 108 | 108 | ); |
| 109 | 109 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 110 | 110 | \\const std = @import("std"); |
| 111 | ++ check_panic_msg ++ | |
| 111 | ++ check_panic_msg ++ | |
| 112 | 112 | \\pub fn main() void { |
| 113 | 113 | \\ var buf_zero = [0]u8{}; |
| 114 | 114 | \\ const slice = buf_zero[0..0 :0]; |
| ... | ... | @@ -116,7 +116,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 116 | 116 | ); |
| 117 | 117 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 118 | 118 | \\const std = @import("std"); |
| 119 | ++ check_panic_msg ++ | |
| 119 | ++ check_panic_msg ++ | |
| 120 | 120 | \\pub fn main() void { |
| 121 | 121 | \\ var buf_zero = [0]u8{}; |
| 122 | 122 | \\ const slice = buf_zero[0..:0]; |
| ... | ... | @@ -124,7 +124,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 124 | 124 | ); |
| 125 | 125 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 126 | 126 | \\const std = @import("std"); |
| 127 | ++ check_panic_msg ++ | |
| 127 | ++ check_panic_msg ++ | |
| 128 | 128 | \\pub fn main() void { |
| 129 | 129 | \\ var buf_sentinel = [2:0]u8{'a','b'}; |
| 130 | 130 | \\ @ptrCast(*[3]u8, &buf_sentinel)[2] = 0; |
| ... | ... | @@ -133,7 +133,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 133 | 133 | ); |
| 134 | 134 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 135 | 135 | \\const std = @import("std"); |
| 136 | ++ check_panic_msg ++ | |
| 136 | ++ check_panic_msg ++ | |
| 137 | 137 | \\pub fn main() void { |
| 138 | 138 | \\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 }; |
| 139 | 139 | \\ const slice = buf_slice[0..3 :0]; |
| ... | ... | @@ -141,7 +141,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 141 | 141 | ); |
| 142 | 142 | cases.addRuntimeSafety("slicing operator with sentinel", |
| 143 | 143 | \\const std = @import("std"); |
| 144 | ++ check_panic_msg ++ | |
| 144 | ++ check_panic_msg ++ | |
| 145 | 145 | \\pub fn main() void { |
| 146 | 146 | \\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 }; |
| 147 | 147 | \\ const slice = buf_slice[0.. :0]; |
| ... | ... | @@ -367,7 +367,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 367 | 367 | \\} |
| 368 | 368 | \\fn add(a: i32, b: i32) i32 { |
| 369 | 369 | \\ if (a > 100) { |
| 370 | \\ suspend; | |
| 370 | \\ suspend {} | |
| 371 | 371 | \\ } |
| 372 | 372 | \\ return a + b; |
| 373 | 373 | \\} |
| ... | ... | @@ -407,7 +407,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 407 | 407 | \\ var frame = @asyncCall(&bytes, {}, ptr, .{}); |
| 408 | 408 | \\} |
| 409 | 409 | \\fn other() callconv(.Async) void { |
| 410 | \\ suspend; | |
| 410 | \\ suspend {} | |
| 411 | 411 | \\} |
| 412 | 412 | ); |
| 413 | 413 | |
| ... | ... | @@ -424,7 +424,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 424 | 424 | \\ await frame; |
| 425 | 425 | \\} |
| 426 | 426 | \\fn other() void { |
| 427 | \\ suspend; | |
| 427 | \\ suspend {} | |
| 428 | 428 | \\} |
| 429 | 429 | ); |
| 430 | 430 | |
| ... | ... | @@ -440,7 +440,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 440 | 440 | \\ other(); |
| 441 | 441 | \\} |
| 442 | 442 | \\fn other() void { |
| 443 | \\ suspend; | |
| 443 | \\ suspend {} | |
| 444 | 444 | \\} |
| 445 | 445 | ); |
| 446 | 446 | |
| ... | ... | @@ -454,7 +454,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 454 | 454 | \\ resume p; //bad |
| 455 | 455 | \\} |
| 456 | 456 | \\fn suspendOnce() void { |
| 457 | \\ suspend; | |
| 457 | \\ suspend {} | |
| 458 | 458 | \\} |
| 459 | 459 | ); |
| 460 | 460 | |
| ... | ... | @@ -1019,7 +1019,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 1019 | 1019 | \\} |
| 1020 | 1020 | \\ |
| 1021 | 1021 | \\fn failing() anyerror!void { |
| 1022 | \\ suspend; | |
| 1022 | \\ suspend {} | |
| 1023 | 1023 | \\ return second(); |
| 1024 | 1024 | \\} |
| 1025 | 1025 | \\ |
test/stage1/behavior/async_fn.zig+42-42| ... | ... | @@ -18,9 +18,9 @@ test "simple coroutine suspend and resume" { |
| 18 | 18 | } |
| 19 | 19 | fn simpleAsyncFn() void { |
| 20 | 20 | global_x += 1; |
| 21 | suspend; | |
| 21 | suspend {} | |
| 22 | 22 | global_x += 1; |
| 23 | suspend; | |
| 23 | suspend {} | |
| 24 | 24 | global_x += 1; |
| 25 | 25 | } |
| 26 | 26 | |
| ... | ... | @@ -34,7 +34,7 @@ test "pass parameter to coroutine" { |
| 34 | 34 | } |
| 35 | 35 | fn simpleAsyncFnWithArg(delta: i32) void { |
| 36 | 36 | global_y += delta; |
| 37 | suspend; | |
| 37 | suspend {} | |
| 38 | 38 | global_y += delta; |
| 39 | 39 | } |
| 40 | 40 | |
| ... | ... | @@ -50,7 +50,7 @@ test "suspend at end of function" { |
| 50 | 50 | |
| 51 | 51 | fn suspendAtEnd() void { |
| 52 | 52 | x += 1; |
| 53 | suspend; | |
| 53 | suspend {} | |
| 54 | 54 | } |
| 55 | 55 | }; |
| 56 | 56 | S.doTheTest(); |
| ... | ... | @@ -74,11 +74,11 @@ test "local variable in async function" { |
| 74 | 74 | |
| 75 | 75 | fn add(a: i32, b: i32) void { |
| 76 | 76 | var accum: i32 = 0; |
| 77 | suspend; | |
| 77 | suspend {} | |
| 78 | 78 | accum += a; |
| 79 | suspend; | |
| 79 | suspend {} | |
| 80 | 80 | accum += b; |
| 81 | suspend; | |
| 81 | suspend {} | |
| 82 | 82 | x = accum; |
| 83 | 83 | } |
| 84 | 84 | }; |
| ... | ... | @@ -102,7 +102,7 @@ test "calling an inferred async function" { |
| 102 | 102 | } |
| 103 | 103 | fn other() void { |
| 104 | 104 | other_frame = @frame(); |
| 105 | suspend; | |
| 105 | suspend {} | |
| 106 | 106 | x += 1; |
| 107 | 107 | } |
| 108 | 108 | }; |
| ... | ... | @@ -129,7 +129,7 @@ test "@frameSize" { |
| 129 | 129 | } |
| 130 | 130 | fn other(param: i32) void { |
| 131 | 131 | var local: i32 = undefined; |
| 132 | suspend; | |
| 132 | suspend {} | |
| 133 | 133 | } |
| 134 | 134 | }; |
| 135 | 135 | S.doTheTest(); |
| ... | ... | @@ -269,7 +269,7 @@ test "async function with dot syntax" { |
| 269 | 269 | var y: i32 = 1; |
| 270 | 270 | fn foo() callconv(.Async) void { |
| 271 | 271 | y += 1; |
| 272 | suspend; | |
| 272 | suspend {} | |
| 273 | 273 | } |
| 274 | 274 | }; |
| 275 | 275 | const p = async S.foo(); |
| ... | ... | @@ -298,7 +298,7 @@ fn doTheAwait(f: anyframe->void) void { |
| 298 | 298 | fn simpleAsyncFn2(y: *i32) callconv(.Async) void { |
| 299 | 299 | defer y.* += 2; |
| 300 | 300 | y.* += 1; |
| 301 | suspend; | |
| 301 | suspend {} | |
| 302 | 302 | } |
| 303 | 303 | |
| 304 | 304 | test "@asyncCall with return type" { |
| ... | ... | @@ -312,7 +312,7 @@ test "@asyncCall with return type" { |
| 312 | 312 | |
| 313 | 313 | fn afunc() i32 { |
| 314 | 314 | global_frame = @frame(); |
| 315 | suspend; | |
| 315 | suspend {} | |
| 316 | 316 | return 1234; |
| 317 | 317 | } |
| 318 | 318 | }; |
| ... | ... | @@ -348,7 +348,7 @@ test "async fn with inferred error set" { |
| 348 | 348 | |
| 349 | 349 | fn failing() !void { |
| 350 | 350 | global_frame = @frame(); |
| 351 | suspend; | |
| 351 | suspend {} | |
| 352 | 352 | return error.Fail; |
| 353 | 353 | } |
| 354 | 354 | }; |
| ... | ... | @@ -375,7 +375,7 @@ fn nonFailing() (anyframe->anyerror!void) { |
| 375 | 375 | return &Static.frame; |
| 376 | 376 | } |
| 377 | 377 | fn suspendThenFail() callconv(.Async) anyerror!void { |
| 378 | suspend; | |
| 378 | suspend {} | |
| 379 | 379 | return error.Fail; |
| 380 | 380 | } |
| 381 | 381 | fn printTrace(p: anyframe->(anyerror!void)) callconv(.Async) void { |
| ... | ... | @@ -400,7 +400,7 @@ fn testBreakFromSuspend(my_result: *i32) callconv(.Async) void { |
| 400 | 400 | resume @frame(); |
| 401 | 401 | } |
| 402 | 402 | my_result.* += 1; |
| 403 | suspend; | |
| 403 | suspend {} | |
| 404 | 404 | my_result.* += 1; |
| 405 | 405 | } |
| 406 | 406 | |
| ... | ... | @@ -421,7 +421,7 @@ test "heap allocated async function frame" { |
| 421 | 421 | |
| 422 | 422 | fn someFunc() void { |
| 423 | 423 | x += 1; |
| 424 | suspend; | |
| 424 | suspend {} | |
| 425 | 425 | x += 1; |
| 426 | 426 | } |
| 427 | 427 | }; |
| ... | ... | @@ -454,7 +454,7 @@ test "async function call return value" { |
| 454 | 454 | |
| 455 | 455 | fn other(x: i32, y: i32) Point { |
| 456 | 456 | frame = @frame(); |
| 457 | suspend; | |
| 457 | suspend {} | |
| 458 | 458 | return Point{ |
| 459 | 459 | .x = x, |
| 460 | 460 | .y = y, |
| ... | ... | @@ -487,7 +487,7 @@ test "suspension points inside branching control flow" { |
| 487 | 487 | |
| 488 | 488 | fn func(b: bool) void { |
| 489 | 489 | while (b) { |
| 490 | suspend; | |
| 490 | suspend {} | |
| 491 | 491 | result += 1; |
| 492 | 492 | } |
| 493 | 493 | } |
| ... | ... | @@ -541,7 +541,7 @@ test "pass string literal to async function" { |
| 541 | 541 | |
| 542 | 542 | fn hello(msg: []const u8) void { |
| 543 | 543 | frame = @frame(); |
| 544 | suspend; | |
| 544 | suspend {} | |
| 545 | 545 | expectEqualStrings("hello", msg); |
| 546 | 546 | ok = true; |
| 547 | 547 | } |
| ... | ... | @@ -566,7 +566,7 @@ test "await inside an errdefer" { |
| 566 | 566 | |
| 567 | 567 | fn func() void { |
| 568 | 568 | frame = @frame(); |
| 569 | suspend; | |
| 569 | suspend {} | |
| 570 | 570 | } |
| 571 | 571 | }; |
| 572 | 572 | S.doTheTest(); |
| ... | ... | @@ -590,7 +590,7 @@ test "try in an async function with error union and non-zero-bit payload" { |
| 590 | 590 | |
| 591 | 591 | fn theProblem() ![]u8 { |
| 592 | 592 | frame = @frame(); |
| 593 | suspend; | |
| 593 | suspend {} | |
| 594 | 594 | const result = try other(); |
| 595 | 595 | return result; |
| 596 | 596 | } |
| ... | ... | @@ -622,7 +622,7 @@ test "returning a const error from async function" { |
| 622 | 622 | |
| 623 | 623 | fn fetchUrl(unused: i32, url: []const u8) ![]u8 { |
| 624 | 624 | frame = @frame(); |
| 625 | suspend; | |
| 625 | suspend {} | |
| 626 | 626 | ok = true; |
| 627 | 627 | return error.OutOfMemory; |
| 628 | 628 | } |
| ... | ... | @@ -967,7 +967,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" { |
| 967 | 967 | |
| 968 | 968 | fn failing() !void { |
| 969 | 969 | global_frame = @frame(); |
| 970 | suspend; | |
| 970 | suspend {} | |
| 971 | 971 | return error.Fail; |
| 972 | 972 | } |
| 973 | 973 | }; |
| ... | ... | @@ -977,7 +977,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" { |
| 977 | 977 | test "@asyncCall with actual frame instead of byte buffer" { |
| 978 | 978 | const S = struct { |
| 979 | 979 | fn func() i32 { |
| 980 | suspend; | |
| 980 | suspend {} | |
| 981 | 981 | return 1234; |
| 982 | 982 | } |
| 983 | 983 | }; |
| ... | ... | @@ -993,7 +993,7 @@ test "@asyncCall using the result location inside the frame" { |
| 993 | 993 | fn simple2(y: *i32) callconv(.Async) i32 { |
| 994 | 994 | defer y.* += 2; |
| 995 | 995 | y.* += 1; |
| 996 | suspend; | |
| 996 | suspend {} | |
| 997 | 997 | return 1234; |
| 998 | 998 | } |
| 999 | 999 | fn getAnswer(f: anyframe->i32, out: *i32) void { |
| ... | ... | @@ -1095,7 +1095,7 @@ test "nosuspend function call" { |
| 1095 | 1095 | } |
| 1096 | 1096 | fn add(a: i32, b: i32) i32 { |
| 1097 | 1097 | if (a > 100) { |
| 1098 | suspend; | |
| 1098 | suspend {} | |
| 1099 | 1099 | } |
| 1100 | 1100 | return a + b; |
| 1101 | 1101 | } |
| ... | ... | @@ -1170,7 +1170,7 @@ test "suspend in for loop" { |
| 1170 | 1170 | global_frame = @frame(); |
| 1171 | 1171 | var sum: u32 = 0; |
| 1172 | 1172 | for (stuff) |x| { |
| 1173 | suspend; | |
| 1173 | suspend {} | |
| 1174 | 1174 | sum += x; |
| 1175 | 1175 | } |
| 1176 | 1176 | global_frame = null; |
| ... | ... | @@ -1197,7 +1197,7 @@ test "suspend in while loop" { |
| 1197 | 1197 | global_frame = @frame(); |
| 1198 | 1198 | defer global_frame = null; |
| 1199 | 1199 | while (stuff) |val| { |
| 1200 | suspend; | |
| 1200 | suspend {} | |
| 1201 | 1201 | return val; |
| 1202 | 1202 | } |
| 1203 | 1203 | return 0; |
| ... | ... | @@ -1206,7 +1206,7 @@ test "suspend in while loop" { |
| 1206 | 1206 | global_frame = @frame(); |
| 1207 | 1207 | defer global_frame = null; |
| 1208 | 1208 | while (stuff) |val| { |
| 1209 | suspend; | |
| 1209 | suspend {} | |
| 1210 | 1210 | return val; |
| 1211 | 1211 | } else |err| { |
| 1212 | 1212 | return 0; |
| ... | ... | @@ -1339,7 +1339,7 @@ test "async function passed 0-bit arg after non-0-bit arg" { |
| 1339 | 1339 | |
| 1340 | 1340 | fn bar(x: i32, args: anytype) anyerror!void { |
| 1341 | 1341 | global_frame = @frame(); |
| 1342 | suspend; | |
| 1342 | suspend {} | |
| 1343 | 1343 | global_int = x; |
| 1344 | 1344 | } |
| 1345 | 1345 | }; |
| ... | ... | @@ -1361,7 +1361,7 @@ test "async function passed align(16) arg after align(8) arg" { |
| 1361 | 1361 | fn bar(x: u64, args: anytype) anyerror!void { |
| 1362 | 1362 | expect(x == 10); |
| 1363 | 1363 | global_frame = @frame(); |
| 1364 | suspend; | |
| 1364 | suspend {} | |
| 1365 | 1365 | global_int = args[0]; |
| 1366 | 1366 | } |
| 1367 | 1367 | }; |
| ... | ... | @@ -1383,7 +1383,7 @@ test "async function call resolves target fn frame, comptime func" { |
| 1383 | 1383 | |
| 1384 | 1384 | fn bar() anyerror!void { |
| 1385 | 1385 | global_frame = @frame(); |
| 1386 | suspend; | |
| 1386 | suspend {} | |
| 1387 | 1387 | global_int += 1; |
| 1388 | 1388 | } |
| 1389 | 1389 | }; |
| ... | ... | @@ -1406,7 +1406,7 @@ test "async function call resolves target fn frame, runtime func" { |
| 1406 | 1406 | |
| 1407 | 1407 | fn bar() anyerror!void { |
| 1408 | 1408 | global_frame = @frame(); |
| 1409 | suspend; | |
| 1409 | suspend {} | |
| 1410 | 1410 | global_int += 1; |
| 1411 | 1411 | } |
| 1412 | 1412 | }; |
| ... | ... | @@ -1430,7 +1430,7 @@ test "properly spill optional payload capture value" { |
| 1430 | 1430 | |
| 1431 | 1431 | fn bar() void { |
| 1432 | 1432 | global_frame = @frame(); |
| 1433 | suspend; | |
| 1433 | suspend {} | |
| 1434 | 1434 | global_int += 1; |
| 1435 | 1435 | } |
| 1436 | 1436 | }; |
| ... | ... | @@ -1466,13 +1466,13 @@ test "handle defer interfering with return value spill" { |
| 1466 | 1466 | |
| 1467 | 1467 | fn bar() anyerror!void { |
| 1468 | 1468 | global_frame1 = @frame(); |
| 1469 | suspend; | |
| 1469 | suspend {} | |
| 1470 | 1470 | return error.Bad; |
| 1471 | 1471 | } |
| 1472 | 1472 | |
| 1473 | 1473 | fn baz() void { |
| 1474 | 1474 | global_frame2 = @frame(); |
| 1475 | suspend; | |
| 1475 | suspend {} | |
| 1476 | 1476 | baz_happened = true; |
| 1477 | 1477 | } |
| 1478 | 1478 | }; |
| ... | ... | @@ -1497,7 +1497,7 @@ test "take address of temporary async frame" { |
| 1497 | 1497 | |
| 1498 | 1498 | fn foo(arg: i32) i32 { |
| 1499 | 1499 | global_frame = @frame(); |
| 1500 | suspend; | |
| 1500 | suspend {} | |
| 1501 | 1501 | return arg + 1234; |
| 1502 | 1502 | } |
| 1503 | 1503 | |
| ... | ... | @@ -1520,7 +1520,7 @@ test "nosuspend await" { |
| 1520 | 1520 | |
| 1521 | 1521 | fn foo(want_suspend: bool) i32 { |
| 1522 | 1522 | if (want_suspend) { |
| 1523 | suspend; | |
| 1523 | suspend {} | |
| 1524 | 1524 | } |
| 1525 | 1525 | return 42; |
| 1526 | 1526 | } |
| ... | ... | @@ -1569,11 +1569,11 @@ test "nosuspend on async function calls" { |
| 1569 | 1569 | // }; |
| 1570 | 1570 | // const S1 = struct { |
| 1571 | 1571 | // fn c() S0 { |
| 1572 | // suspend; | |
| 1572 | // suspend {} | |
| 1573 | 1573 | // return S0{}; |
| 1574 | 1574 | // } |
| 1575 | 1575 | // fn d() !S0 { |
| 1576 | // suspend; | |
| 1576 | // suspend {} | |
| 1577 | 1577 | // return S0{}; |
| 1578 | 1578 | // } |
| 1579 | 1579 | // }; |
| ... | ... | @@ -1591,11 +1591,11 @@ test "nosuspend resume async function calls" { |
| 1591 | 1591 | }; |
| 1592 | 1592 | const S1 = struct { |
| 1593 | 1593 | fn c() S0 { |
| 1594 | suspend; | |
| 1594 | suspend {} | |
| 1595 | 1595 | return S0{}; |
| 1596 | 1596 | } |
| 1597 | 1597 | fn d() !S0 { |
| 1598 | suspend; | |
| 1598 | suspend {} | |
| 1599 | 1599 | return S0{}; |
| 1600 | 1600 | } |
| 1601 | 1601 | }; |