diff --git a/BRANCH_TODO b/BRANCH_TODO index 4e128b78a..f5db81a08 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -6,7 +6,10 @@ * cancel * defer and errdefer * safety for resuming when it is awaiting + * safety for double await * implicit cast of normal function to async function should be allowed when it is inferred to be async * go over the commented out tests * revive std.event.Loop * @typeInfo for @Frame(func) + * peer type resolution of *@Frame(func) and anyframe + * peer type resolution of *@Frame(func) and anyframe->T when the return type matches diff --git a/src/ir.cpp b/src/ir.cpp index 3d376270f..3a6853b03 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -24380,7 +24380,6 @@ static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstr IrInstruction *frame; if (frame_ptr->value.type->id == ZigTypeIdPointer && frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle && - frame_ptr->value.type->data.pointer.is_const && frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdAnyFrame) { frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); diff --git a/test/stage1/behavior/coroutines.zig b/test/stage1/behavior/coroutines.zig index fddc912e7..01237ed1c 100644 --- a/test/stage1/behavior/coroutines.zig +++ b/test/stage1/behavior/coroutines.zig @@ -132,56 +132,55 @@ test "@frameSize" { S.doTheTest(); } -//test "coroutine suspend, resume" { -// seq('a'); -// const p = try async testAsyncSeq(); -// seq('c'); -// resume p; -// seq('f'); -// cancel p; -// seq('g'); -// -// expect(std.mem.eql(u8, points, "abcdefg")); -//} -//async fn testAsyncSeq() void { -// defer seq('e'); -// -// seq('b'); -// suspend; -// seq('d'); -//} -//var points = [_]u8{0} ** "abcdefg".len; -//var index: usize = 0; -// -//fn seq(c: u8) void { -// points[index] = c; -// index += 1; -//} -// -//test "coroutine suspend with block" { -// const p = try async testSuspendBlock(); -// std.testing.expect(!result); -// resume a_promise; -// std.testing.expect(result); -// cancel p; -//} -// -//var a_promise: promise = undefined; -//var result = false; -//async fn testSuspendBlock() void { -// suspend { -// comptime expect(@typeOf(@handle()) == promise->void); -// a_promise = @handle(); -// } -// -// //Test to make sure that @handle() works as advertised (issue #1296) -// //var our_handle: promise = @handle(); -// expect(a_promise == @handle()); -// -// result = true; -//} -// -//var await_a_promise: promise = undefined; +test "coroutine suspend, resume" { + seq('a'); + const p = async testAsyncSeq(); + seq('c'); + resume p; + seq('f'); + // `cancel` is now a suspend point so it cannot be done here + seq('g'); + + expect(std.mem.eql(u8, points, "abcdefg")); +} +async fn testAsyncSeq() void { + defer seq('e'); + + seq('b'); + suspend; + seq('d'); +} +var points = [_]u8{0} ** "abcdefg".len; +var index: usize = 0; + +fn seq(c: u8) void { + points[index] = c; + index += 1; +} + +test "coroutine suspend with block" { + const p = async testSuspendBlock(); + expect(!result); + resume a_promise; + expect(result); +} + +var a_promise: anyframe = undefined; +var result = false; +async fn testSuspendBlock() void { + suspend { + comptime expect(@typeOf(@frame()) == *@Frame(testSuspendBlock)); + a_promise = @frame(); + } + + // Test to make sure that @frame() works as advertised (issue #1296) + // var our_handle: anyframe = @frame(); + expect(a_promise == anyframe(@frame())); + + result = true; +} + +//var await_a_promise: anyframe = undefined; //var await_final_result: i32 = 0; // //test "coroutine await" { @@ -204,7 +203,7 @@ test "@frameSize" { // await_seq('c'); // suspend { // await_seq('d'); -// await_a_promise = @handle(); +// await_a_promise = @frame(); // } // await_seq('g'); // return 1234; @@ -314,14 +313,14 @@ test "@frameSize" { // cancel p2; //} // -//fn nonFailing() (promise->anyerror!void) { +//fn nonFailing() (anyframe->anyerror!void) { // return async suspendThenFail() catch unreachable; //} //async fn suspendThenFail() anyerror!void { // suspend; // return error.Fail; //} -//async fn printTrace(p: promise->(anyerror!void)) void { +//async fn printTrace(p: anyframe->(anyerror!void)) void { // (await p) catch |e| { // std.testing.expect(e == error.Fail); // if (@errorReturnTrace()) |trace| { @@ -343,7 +342,7 @@ test "@frameSize" { //} //async fn testBreakFromSuspend(my_result: *i32) void { // suspend { -// resume @handle(); +// resume @frame(); // } // my_result.* += 1; // suspend;