| author | |
| committer | |
| log | 1afbb53661e655906980668f0224804118a9862e |
| tree | b75f4327c961c0a7fe62e1601621f936eb55e3c5 |
| parent | 966c9ea63c635a12c923d3ab155a9070affb18c5 |
| signature |
5 files changed, 122 insertions(+), 91 deletions(-)
BRANCH_TODO+1-2| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | * error return tracing - handle `await` and function calls | 1 | * go over the commented out tests in cancel.zig |
| 2 | * go over the commented out tests | ||
| 3 | * compile error for error: expected anyframe->T, found 'anyframe' | 2 | * compile error for error: expected anyframe->T, found 'anyframe' |
| 4 | * compile error for error: expected anyframe->T, found 'i32' | 3 | * compile error for error: expected anyframe->T, found 'i32' |
| 5 | * await of a non async function | 4 | * await of a non async function |
src/codegen.cpp+2-3| ... | @@ -2300,9 +2300,8 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable, | ... | @@ -2300,9 +2300,8 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable, |
| 2300 | static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) { | 2300 | static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) { |
| 2301 | if (fn_is_async(g->cur_fn)) { | 2301 | if (fn_is_async(g->cur_fn)) { |
| 2302 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; | 2302 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 2303 | bool ret_type_has_bits = instruction->operand != nullptr && | 2303 | ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; |
| 2304 | type_has_bits(instruction->operand->value.type); | 2304 | bool ret_type_has_bits = type_has_bits(ret_type); |
| 2305 | ZigType *ret_type = ret_type_has_bits ? instruction->operand->value.type : nullptr; | ||
| 2306 | 2305 | ||
| 2307 | if (ir_want_runtime_safety(g, &instruction->base)) { | 2306 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| 2308 | LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref); | 2307 | LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref); |
test/stage1/behavior.zig+2-2| ... | @@ -39,10 +39,10 @@ comptime { | ... | @@ -39,10 +39,10 @@ comptime { |
| 39 | _ = @import("behavior/bugs/828.zig"); | 39 | _ = @import("behavior/bugs/828.zig"); |
| 40 | _ = @import("behavior/bugs/920.zig"); | 40 | _ = @import("behavior/bugs/920.zig"); |
| 41 | _ = @import("behavior/byval_arg_var.zig"); | 41 | _ = @import("behavior/byval_arg_var.zig"); |
| 42 | //_ = @import("behavior/cancel.zig"); | 42 | _ = @import("behavior/cancel.zig"); |
| 43 | _ = @import("behavior/cast.zig"); | 43 | _ = @import("behavior/cast.zig"); |
| 44 | _ = @import("behavior/const_slice_child.zig"); | 44 | _ = @import("behavior/const_slice_child.zig"); |
| 45 | //_ = @import("behavior/coroutine_await_struct.zig"); | 45 | _ = @import("behavior/coroutine_await_struct.zig"); |
| 46 | _ = @import("behavior/coroutines.zig"); | 46 | _ = @import("behavior/coroutines.zig"); |
| 47 | _ = @import("behavior/defer.zig"); | 47 | _ = @import("behavior/defer.zig"); |
| 48 | _ = @import("behavior/enum.zig"); | 48 | _ = @import("behavior/enum.zig"); |
test/stage1/behavior/cancel.zig+84-84| ... | @@ -1,86 +1,86 @@ | ... | @@ -1,86 +1,86 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | var defer_f1: bool = false; | 3 | //var defer_f1: bool = false; |
| 4 | var defer_f2: bool = false; | 4 | //var defer_f2: bool = false; |
| 5 | var defer_f3: bool = false; | 5 | //var defer_f3: bool = false; |
| 6 | 6 | // | |
| 7 | test "cancel forwards" { | 7 | //test "cancel forwards" { |
| 8 | const p = async<std.heap.direct_allocator> f1() catch unreachable; | 8 | // const p = async<std.heap.direct_allocator> f1() catch unreachable; |
| 9 | cancel p; | 9 | // cancel p; |
| 10 | std.testing.expect(defer_f1); | 10 | // std.testing.expect(defer_f1); |
| 11 | std.testing.expect(defer_f2); | 11 | // std.testing.expect(defer_f2); |
| 12 | std.testing.expect(defer_f3); | 12 | // std.testing.expect(defer_f3); |
| 13 | } | 13 | //} |
| 14 | 14 | // | |
| 15 | async fn f1() void { | 15 | //async fn f1() void { |
| 16 | defer { | 16 | // defer { |
| 17 | defer_f1 = true; | 17 | // defer_f1 = true; |
| 18 | } | 18 | // } |
| 19 | await (async f2() catch unreachable); | 19 | // await (async f2() catch unreachable); |
| 20 | } | 20 | //} |
| 21 | 21 | // | |
| 22 | async fn f2() void { | 22 | //async fn f2() void { |
| 23 | defer { | 23 | // defer { |
| 24 | defer_f2 = true; | 24 | // defer_f2 = true; |
| 25 | } | 25 | // } |
| 26 | await (async f3() catch unreachable); | 26 | // await (async f3() catch unreachable); |
| 27 | } | 27 | //} |
| 28 | 28 | // | |
| 29 | async fn f3() void { | 29 | //async fn f3() void { |
| 30 | defer { | 30 | // defer { |
| 31 | defer_f3 = true; | 31 | // defer_f3 = true; |
| 32 | } | 32 | // } |
| 33 | suspend; | 33 | // suspend; |
| 34 | } | 34 | //} |
| 35 | 35 | // | |
| 36 | var defer_b1: bool = false; | 36 | //var defer_b1: bool = false; |
| 37 | var defer_b2: bool = false; | 37 | //var defer_b2: bool = false; |
| 38 | var defer_b3: bool = false; | 38 | //var defer_b3: bool = false; |
| 39 | var defer_b4: bool = false; | 39 | //var defer_b4: bool = false; |
| 40 | 40 | // | |
| 41 | test "cancel backwards" { | 41 | //test "cancel backwards" { |
| 42 | const p = async<std.heap.direct_allocator> b1() catch unreachable; | 42 | // const p = async<std.heap.direct_allocator> b1() catch unreachable; |
| 43 | cancel p; | 43 | // cancel p; |
| 44 | std.testing.expect(defer_b1); | 44 | // std.testing.expect(defer_b1); |
| 45 | std.testing.expect(defer_b2); | 45 | // std.testing.expect(defer_b2); |
| 46 | std.testing.expect(defer_b3); | 46 | // std.testing.expect(defer_b3); |
| 47 | std.testing.expect(defer_b4); | 47 | // std.testing.expect(defer_b4); |
| 48 | } | 48 | //} |
| 49 | 49 | // | |
| 50 | async fn b1() void { | 50 | //async fn b1() void { |
| 51 | defer { | 51 | // defer { |
| 52 | defer_b1 = true; | 52 | // defer_b1 = true; |
| 53 | } | 53 | // } |
| 54 | await (async b2() catch unreachable); | 54 | // await (async b2() catch unreachable); |
| 55 | } | 55 | //} |
| 56 | 56 | // | |
| 57 | var b4_handle: promise = undefined; | 57 | //var b4_handle: promise = undefined; |
| 58 | 58 | // | |
| 59 | async fn b2() void { | 59 | //async fn b2() void { |
| 60 | const b3_handle = async b3() catch unreachable; | 60 | // const b3_handle = async b3() catch unreachable; |
| 61 | resume b4_handle; | 61 | // resume b4_handle; |
| 62 | cancel b4_handle; | 62 | // cancel b4_handle; |
| 63 | defer { | 63 | // defer { |
| 64 | defer_b2 = true; | 64 | // defer_b2 = true; |
| 65 | } | 65 | // } |
| 66 | const value = await b3_handle; | 66 | // const value = await b3_handle; |
| 67 | @panic("unreachable"); | 67 | // @panic("unreachable"); |
| 68 | } | 68 | //} |
| 69 | 69 | // | |
| 70 | async fn b3() i32 { | 70 | //async fn b3() i32 { |
| 71 | defer { | 71 | // defer { |
| 72 | defer_b3 = true; | 72 | // defer_b3 = true; |
| 73 | } | 73 | // } |
| 74 | await (async b4() catch unreachable); | 74 | // await (async b4() catch unreachable); |
| 75 | return 1234; | 75 | // return 1234; |
| 76 | } | 76 | //} |
| 77 | 77 | // | |
| 78 | async fn b4() void { | 78 | //async fn b4() void { |
| 79 | defer { | 79 | // defer { |
| 80 | defer_b4 = true; | 80 | // defer_b4 = true; |
| 81 | } | 81 | // } |
| 82 | suspend { | 82 | // suspend { |
| 83 | b4_handle = @handle(); | 83 | // b4_handle = @handle(); |
| 84 | } | 84 | // } |
| 85 | suspend; | 85 | // suspend; |
| 86 | } | 86 | //} |
test/stage1/behavior/coroutines.zig+33| ... | @@ -474,3 +474,36 @@ test "suspension points inside branching control flow" { | ... | @@ -474,3 +474,36 @@ test "suspension points inside branching control flow" { |
| 474 | }; | 474 | }; |
| 475 | S.doTheTest(); | 475 | S.doTheTest(); |
| 476 | } | 476 | } |
| 477 | |||
| 478 | test "call async function which has struct return type" { | ||
| 479 | const S = struct { | ||
| 480 | var frame: anyframe = undefined; | ||
| 481 | |||
| 482 | fn doTheTest() void { | ||
| 483 | _ = async atest(); | ||
| 484 | resume frame; | ||
| 485 | } | ||
| 486 | |||
| 487 | fn atest() void { | ||
| 488 | const result = func(); | ||
| 489 | expect(result.x == 5); | ||
| 490 | expect(result.y == 6); | ||
| 491 | } | ||
| 492 | |||
| 493 | const Point = struct { | ||
| 494 | x: usize, | ||
| 495 | y: usize, | ||
| 496 | }; | ||
| 497 | |||
| 498 | fn func() Point { | ||
| 499 | suspend { | ||
| 500 | frame = @frame(); | ||
| 501 | } | ||
| 502 | return Point{ | ||
| 503 | .x = 5, | ||
| 504 | .y = 6, | ||
| 505 | }; | ||
| 506 | } | ||
| 507 | }; | ||
| 508 | S.doTheTest(); | ||
| 509 | } |