fix awaiting when result type is a struct
This commit is contained in:
parent
966c9ea63c
commit
1afbb53661
|
@ -1,5 +1,4 @@
|
|||
* error return tracing - handle `await` and function calls
|
||||
* go over the commented out tests
|
||||
* go over the commented out tests in cancel.zig
|
||||
* compile error for error: expected anyframe->T, found 'anyframe'
|
||||
* compile error for error: expected anyframe->T, found 'i32'
|
||||
* await of a non async function
|
||||
|
|
|
@ -2300,9 +2300,8 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
|
|||
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {
|
||||
if (fn_is_async(g->cur_fn)) {
|
||||
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
|
||||
bool ret_type_has_bits = instruction->operand != nullptr &&
|
||||
type_has_bits(instruction->operand->value.type);
|
||||
ZigType *ret_type = ret_type_has_bits ? instruction->operand->value.type : nullptr;
|
||||
ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
|
||||
bool ret_type_has_bits = type_has_bits(ret_type);
|
||||
|
||||
if (ir_want_runtime_safety(g, &instruction->base)) {
|
||||
LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref);
|
||||
|
|
|
@ -39,10 +39,10 @@ comptime {
|
|||
_ = @import("behavior/bugs/828.zig");
|
||||
_ = @import("behavior/bugs/920.zig");
|
||||
_ = @import("behavior/byval_arg_var.zig");
|
||||
//_ = @import("behavior/cancel.zig");
|
||||
_ = @import("behavior/cancel.zig");
|
||||
_ = @import("behavior/cast.zig");
|
||||
_ = @import("behavior/const_slice_child.zig");
|
||||
//_ = @import("behavior/coroutine_await_struct.zig");
|
||||
_ = @import("behavior/coroutine_await_struct.zig");
|
||||
_ = @import("behavior/coroutines.zig");
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
|
|
|
@ -1,86 +1,86 @@
|
|||
const std = @import("std");
|
||||
|
||||
var defer_f1: bool = false;
|
||||
var defer_f2: bool = false;
|
||||
var defer_f3: bool = false;
|
||||
|
||||
test "cancel forwards" {
|
||||
const p = async<std.heap.direct_allocator> f1() catch unreachable;
|
||||
cancel p;
|
||||
std.testing.expect(defer_f1);
|
||||
std.testing.expect(defer_f2);
|
||||
std.testing.expect(defer_f3);
|
||||
}
|
||||
|
||||
async fn f1() void {
|
||||
defer {
|
||||
defer_f1 = true;
|
||||
}
|
||||
await (async f2() catch unreachable);
|
||||
}
|
||||
|
||||
async fn f2() void {
|
||||
defer {
|
||||
defer_f2 = true;
|
||||
}
|
||||
await (async f3() catch unreachable);
|
||||
}
|
||||
|
||||
async fn f3() void {
|
||||
defer {
|
||||
defer_f3 = true;
|
||||
}
|
||||
suspend;
|
||||
}
|
||||
|
||||
var defer_b1: bool = false;
|
||||
var defer_b2: bool = false;
|
||||
var defer_b3: bool = false;
|
||||
var defer_b4: bool = false;
|
||||
|
||||
test "cancel backwards" {
|
||||
const p = async<std.heap.direct_allocator> b1() catch unreachable;
|
||||
cancel p;
|
||||
std.testing.expect(defer_b1);
|
||||
std.testing.expect(defer_b2);
|
||||
std.testing.expect(defer_b3);
|
||||
std.testing.expect(defer_b4);
|
||||
}
|
||||
|
||||
async fn b1() void {
|
||||
defer {
|
||||
defer_b1 = true;
|
||||
}
|
||||
await (async b2() catch unreachable);
|
||||
}
|
||||
|
||||
var b4_handle: promise = undefined;
|
||||
|
||||
async fn b2() void {
|
||||
const b3_handle = async b3() catch unreachable;
|
||||
resume b4_handle;
|
||||
cancel b4_handle;
|
||||
defer {
|
||||
defer_b2 = true;
|
||||
}
|
||||
const value = await b3_handle;
|
||||
@panic("unreachable");
|
||||
}
|
||||
|
||||
async fn b3() i32 {
|
||||
defer {
|
||||
defer_b3 = true;
|
||||
}
|
||||
await (async b4() catch unreachable);
|
||||
return 1234;
|
||||
}
|
||||
|
||||
async fn b4() void {
|
||||
defer {
|
||||
defer_b4 = true;
|
||||
}
|
||||
suspend {
|
||||
b4_handle = @handle();
|
||||
}
|
||||
suspend;
|
||||
}
|
||||
//var defer_f1: bool = false;
|
||||
//var defer_f2: bool = false;
|
||||
//var defer_f3: bool = false;
|
||||
//
|
||||
//test "cancel forwards" {
|
||||
// const p = async<std.heap.direct_allocator> f1() catch unreachable;
|
||||
// cancel p;
|
||||
// std.testing.expect(defer_f1);
|
||||
// std.testing.expect(defer_f2);
|
||||
// std.testing.expect(defer_f3);
|
||||
//}
|
||||
//
|
||||
//async fn f1() void {
|
||||
// defer {
|
||||
// defer_f1 = true;
|
||||
// }
|
||||
// await (async f2() catch unreachable);
|
||||
//}
|
||||
//
|
||||
//async fn f2() void {
|
||||
// defer {
|
||||
// defer_f2 = true;
|
||||
// }
|
||||
// await (async f3() catch unreachable);
|
||||
//}
|
||||
//
|
||||
//async fn f3() void {
|
||||
// defer {
|
||||
// defer_f3 = true;
|
||||
// }
|
||||
// suspend;
|
||||
//}
|
||||
//
|
||||
//var defer_b1: bool = false;
|
||||
//var defer_b2: bool = false;
|
||||
//var defer_b3: bool = false;
|
||||
//var defer_b4: bool = false;
|
||||
//
|
||||
//test "cancel backwards" {
|
||||
// const p = async<std.heap.direct_allocator> b1() catch unreachable;
|
||||
// cancel p;
|
||||
// std.testing.expect(defer_b1);
|
||||
// std.testing.expect(defer_b2);
|
||||
// std.testing.expect(defer_b3);
|
||||
// std.testing.expect(defer_b4);
|
||||
//}
|
||||
//
|
||||
//async fn b1() void {
|
||||
// defer {
|
||||
// defer_b1 = true;
|
||||
// }
|
||||
// await (async b2() catch unreachable);
|
||||
//}
|
||||
//
|
||||
//var b4_handle: promise = undefined;
|
||||
//
|
||||
//async fn b2() void {
|
||||
// const b3_handle = async b3() catch unreachable;
|
||||
// resume b4_handle;
|
||||
// cancel b4_handle;
|
||||
// defer {
|
||||
// defer_b2 = true;
|
||||
// }
|
||||
// const value = await b3_handle;
|
||||
// @panic("unreachable");
|
||||
//}
|
||||
//
|
||||
//async fn b3() i32 {
|
||||
// defer {
|
||||
// defer_b3 = true;
|
||||
// }
|
||||
// await (async b4() catch unreachable);
|
||||
// return 1234;
|
||||
//}
|
||||
//
|
||||
//async fn b4() void {
|
||||
// defer {
|
||||
// defer_b4 = true;
|
||||
// }
|
||||
// suspend {
|
||||
// b4_handle = @handle();
|
||||
// }
|
||||
// suspend;
|
||||
//}
|
||||
|
|
|
@ -474,3 +474,36 @@ test "suspension points inside branching control flow" {
|
|||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
test "call async function which has struct return type" {
|
||||
const S = struct {
|
||||
var frame: anyframe = undefined;
|
||||
|
||||
fn doTheTest() void {
|
||||
_ = async atest();
|
||||
resume frame;
|
||||
}
|
||||
|
||||
fn atest() void {
|
||||
const result = func();
|
||||
expect(result.x == 5);
|
||||
expect(result.y == 6);
|
||||
}
|
||||
|
||||
const Point = struct {
|
||||
x: usize,
|
||||
y: usize,
|
||||
};
|
||||
|
||||
fn func() Point {
|
||||
suspend {
|
||||
frame = @frame();
|
||||
}
|
||||
return Point{
|
||||
.x = 5,
|
||||
.y = 6,
|
||||
};
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user