fix returning a const error from async function
This commit is contained in:
parent
22428a7546
commit
77d098e92d
|
@ -2280,13 +2280,16 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
|
|||
return operand_has_bits ? ir_llvm_value(g, instruction->operand) : 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);
|
||||
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
|
||||
|
||||
if (ret_type_has_bits && !handle_is_ptr(ret_type)) {
|
||||
// It's a scalar, so it didn't get written to the result ptr. Do that before the atomic rmw.
|
||||
LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), g->cur_ret_ptr);
|
||||
if (operand_has_bits && instruction->operand != nullptr) {
|
||||
ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
|
||||
bool need_store = instruction->operand->value.special != ConstValSpecialRuntime || !handle_is_ptr(ret_type);
|
||||
if (need_store) {
|
||||
// It didn't get written to the result ptr. We do that now so that we do not have to spill
|
||||
// the return operand.
|
||||
ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true);
|
||||
gen_assign_raw(g, g->cur_ret_ptr, ret_ptr_type, ir_llvm_value(g, instruction->operand));
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare to be suspended. We might end up not having to suspend though.
|
||||
|
@ -2387,6 +2390,8 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
|
|||
LLVMSetTailCall(call_inst, true);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
|
||||
g->cur_is_after_return = false;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
|
||||
|
@ -7117,7 +7122,6 @@ static void do_code_gen(CodeGen *g) {
|
|||
}
|
||||
|
||||
if (is_async) {
|
||||
g->cur_is_after_return = false;
|
||||
g->cur_resume_block_count = 0;
|
||||
|
||||
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
|
||||
|
|
|
@ -672,3 +672,31 @@ test "try in an async function with error union and non-zero-bit payload" {
|
|||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
test "returning a const error from async function" {
|
||||
const S = struct {
|
||||
var frame: anyframe = undefined;
|
||||
var ok = false;
|
||||
|
||||
fn doTheTest() void {
|
||||
_ = async amain();
|
||||
resume frame;
|
||||
expect(ok);
|
||||
}
|
||||
|
||||
fn amain() !void {
|
||||
var download_frame = async fetchUrl(10, "a string");
|
||||
const download_text = try await download_frame;
|
||||
|
||||
@panic("should not get here");
|
||||
}
|
||||
|
||||
fn fetchUrl(unused: i32, url: []const u8) ![]u8 {
|
||||
frame = @frame();
|
||||
suspend;
|
||||
ok = true;
|
||||
return error.OutOfMemory;
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user