fix recursive call of await @asyncCall with struct return type
This commit is contained in:
parent
d291d3c8c0
commit
ab4cba14c8
22
src/ir.cpp
22
src/ir.cpp
|
@ -330,6 +330,8 @@ static bool ir_should_inline(IrExecutable *exec, Scope *scope) {
|
|||
while (scope != nullptr) {
|
||||
if (scope->id == ScopeIdCompTime)
|
||||
return true;
|
||||
if (scope->id == ScopeIdTypeOf)
|
||||
return false;
|
||||
if (scope->id == ScopeIdFnDef)
|
||||
break;
|
||||
scope = scope->parent;
|
||||
|
@ -16075,11 +16077,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
}
|
||||
|
||||
IrInstruction *result_loc;
|
||||
if (call_instruction->is_async_call_builtin) {
|
||||
result_loc = get_async_call_result_loc(ira, call_instruction, impl_fn_type_id->return_type);
|
||||
if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else if (handle_is_ptr(impl_fn_type_id->return_type)) {
|
||||
if (handle_is_ptr(impl_fn_type_id->return_type)) {
|
||||
result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
|
||||
impl_fn_type_id->return_type, nullptr, true, true, false);
|
||||
if (result_loc != nullptr) {
|
||||
|
@ -16091,6 +16089,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
result_loc = nullptr;
|
||||
}
|
||||
}
|
||||
} else if (call_instruction->is_async_call_builtin) {
|
||||
result_loc = get_async_call_result_loc(ira, call_instruction, impl_fn_type_id->return_type);
|
||||
if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
result_loc = nullptr;
|
||||
}
|
||||
|
@ -16231,11 +16233,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
}
|
||||
|
||||
IrInstruction *result_loc;
|
||||
if (call_instruction->is_async_call_builtin) {
|
||||
result_loc = get_async_call_result_loc(ira, call_instruction, return_type);
|
||||
if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else if (handle_is_ptr(return_type)) {
|
||||
if (handle_is_ptr(return_type)) {
|
||||
result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
|
||||
return_type, nullptr, true, true, false);
|
||||
if (result_loc != nullptr) {
|
||||
|
@ -16247,6 +16245,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
result_loc = nullptr;
|
||||
}
|
||||
}
|
||||
} else if (call_instruction->is_async_call_builtin) {
|
||||
result_loc = get_async_call_result_loc(ira, call_instruction, return_type);
|
||||
if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
result_loc = nullptr;
|
||||
}
|
||||
|
|
|
@ -1056,3 +1056,39 @@ test "using @typeOf on a generic function call" {
|
|||
resume S.global_frame;
|
||||
expect(S.global_ok);
|
||||
}
|
||||
|
||||
test "recursive call of await @asyncCall with struct return type" {
|
||||
const S = struct {
|
||||
var global_frame: anyframe = undefined;
|
||||
var global_ok = false;
|
||||
|
||||
var buf: [100]u8 align(16) = undefined;
|
||||
|
||||
fn amain(x: var) Foo {
|
||||
if (x == 0) {
|
||||
global_ok = true;
|
||||
return Foo{ .x = 1, .y = 2, .z = 3 };
|
||||
}
|
||||
suspend {
|
||||
global_frame = @frame();
|
||||
}
|
||||
const F = @typeOf(async amain(x - 1));
|
||||
const frame = @intToPtr(*F, @ptrToInt(&buf));
|
||||
return await @asyncCall(frame, {}, amain, x - 1);
|
||||
}
|
||||
|
||||
const Foo = struct {
|
||||
x: u64,
|
||||
y: u64,
|
||||
z: u64,
|
||||
};
|
||||
};
|
||||
var res: S.Foo = undefined;
|
||||
var frame: @typeOf(async S.amain(u32(1))) = undefined;
|
||||
_ = @asyncCall(&frame, &res, S.amain, u32(1));
|
||||
resume S.global_frame;
|
||||
expect(S.global_ok);
|
||||
expect(res.x == 1);
|
||||
expect(res.y == 2);
|
||||
expect(res.z == 3);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user