authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-05 03:10:14-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-05 03:10:14-04:00
log20f63e588e62c4a7250bc96c9e5b54c8106ad1af
treebc138766dfe7938b12891e3856e2cab3a4eece26
parentdfe8c5a2e9b1778c1911e987c9286d05db307fe7
signaturelock-open Commit is signed but in an unrecognized format.

async functions have error return traces where appropriate

however the traces are not merged on `await` or async function calls yet. When an async function has an error set or error union as its return type, it has a `StackTrace` before the args in the frame, so that it is accessible from `anyframe->T` awaiters. However when it does not have an errorable return type, but it does call or await an errorable, it has a stack trace just before the locals. This way when doing an `@asyncCall` on an async function pointer, it can populate the args (which are after the `StackTrace`) because it knows the offset of the args based only on the return type. This sort of matches normal functions, where a stack trace pointer could be supplied by a parameter, or it could be supplied by the stack of the function, depending on whether the function itself is errorable.

6 files changed, 91 insertions(+), 70 deletions(-)

BRANCH_TODO+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1 * error return tracing - handle `await` and function calls
1 * go over the commented out tests2 * go over the commented out tests
2 * error return tracing
3 * compile error for error: expected anyframe->T, found 'anyframe'3 * compile error for error: expected anyframe->T, found 'anyframe'
4 * compile error for error: expected anyframe->T, found 'i32'4 * compile error for error: expected anyframe->T, found 'i32'
5 * await of a non async function5 * await of a non async function
src/analyze.cpp+14-14
...@@ -5230,9 +5230,8 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5230,9 +5230,8 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5230 field_names.append("@result");5230 field_names.append("@result");
5231 field_types.append(fn_type_id->return_type);5231 field_types.append(fn_type_id->return_type);
52325232
5233 if (codegen_fn_has_err_ret_tracing(g, fn_type_id->return_type)) {5233 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
5234 field_names.append("@ptr_stack_trace");5234 (void)get_ptr_to_stack_trace_type(g); // populate g->stack_trace_type
5235 field_types.append(get_ptr_to_stack_trace_type(g));
52365235
5237 field_names.append("@stack_trace");5236 field_names.append("@stack_trace");
5238 field_types.append(g->stack_trace_type);5237 field_types.append(g->stack_trace_type);
...@@ -5256,6 +5255,16 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5256,6 +5255,16 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5256 field_types.append(param_type);5255 field_types.append(param_type);
5257 }5256 }
52585257
5258 if (codegen_fn_has_err_ret_tracing_stack(g, fn)) {
5259 (void)get_ptr_to_stack_trace_type(g); // populate g->stack_trace_type
5260
5261 field_names.append("@stack_trace");
5262 field_types.append(g->stack_trace_type);
5263
5264 field_names.append("@instruction_addresses");
5265 field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count));
5266 }
5267
5259 for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {5268 for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {
5260 IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);5269 IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);
5261 ZigType *ptr_type = instruction->base.value.type;5270 ZigType *ptr_type = instruction->base.value.type;
...@@ -7563,8 +7572,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re...@@ -7563,8 +7572,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
7563 if (have_result_type) {7572 if (have_result_type) {
7564 field_types.append(get_llvm_type(g, ptr_result_type)); // ptr_result7573 field_types.append(get_llvm_type(g, ptr_result_type)); // ptr_result
7565 field_types.append(get_llvm_type(g, result_type)); // result7574 field_types.append(get_llvm_type(g, result_type)); // result
7566 if (codegen_fn_has_err_ret_tracing(g, result_type)) {7575 if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
7567 field_types.append(get_llvm_type(g, get_ptr_to_stack_trace_type(g))); // ptr_stack_trace
7568 field_types.append(get_llvm_type(g, g->stack_trace_type)); // stack_trace7576 field_types.append(get_llvm_type(g, g->stack_trace_type)); // stack_trace
7569 field_types.append(get_llvm_type(g, get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count))); // instruction_addresses7577 field_types.append(get_llvm_type(g, get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count))); // instruction_addresses
7570 }7578 }
...@@ -7614,15 +7622,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re...@@ -7614,15 +7622,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
7614 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),7622 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
7615 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, result_type)));7623 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, result_type)));
76167624
7617 if (codegen_fn_has_err_ret_tracing(g, result_type)) {7625 if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
7618 di_element_types.append(
7619 ZigLLVMCreateDebugMemberType(g->dbuilder,
7620 ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "ptr_stack_trace",
7621 di_file, line,
7622 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
7623 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
7624 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
7625 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, get_ptr_to_stack_trace_type(g))));
7626 di_element_types.append(7626 di_element_types.append(
7627 ZigLLVMCreateDebugMemberType(g->dbuilder,7627 ZigLLVMCreateDebugMemberType(g->dbuilder,
7628 ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "stack_trace",7628 ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "stack_trace",
src/codegen.cpp+61-44
...@@ -298,7 +298,7 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {...@@ -298,7 +298,7 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
298}298}
299299
300// label (grep this): [coro_frame_struct_layout]300// label (grep this): [coro_frame_struct_layout]
301static uint32_t frame_index_trace(CodeGen *g, FnTypeId *fn_type_id) {301static uint32_t frame_index_trace_arg(CodeGen *g, FnTypeId *fn_type_id) {
302 // [0] *ReturnType302 // [0] *ReturnType
303 // [1] ReturnType303 // [1] ReturnType
304 uint32_t return_field_count = type_has_bits(fn_type_id->return_type) ? 2 : 0;304 uint32_t return_field_count = type_has_bits(fn_type_id->return_type) ? 2 : 0;
...@@ -307,14 +307,25 @@ static uint32_t frame_index_trace(CodeGen *g, FnTypeId *fn_type_id) {...@@ -307,14 +307,25 @@ static uint32_t frame_index_trace(CodeGen *g, FnTypeId *fn_type_id) {
307307
308// label (grep this): [coro_frame_struct_layout]308// label (grep this): [coro_frame_struct_layout]
309static uint32_t frame_index_arg(CodeGen *g, FnTypeId *fn_type_id) {309static uint32_t frame_index_arg(CodeGen *g, FnTypeId *fn_type_id) {
310 bool have_stack_trace = g->have_err_ret_tracing && codegen_fn_has_err_ret_tracing(g, fn_type_id->return_type);310 bool have_stack_trace = codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type);
311 // [0] *StackTrace311 // [0] StackTrace
312 // [1] StackTrace312 // [1] [stack_trace_ptr_count]usize
313 // [2] [stack_trace_ptr_count]usize313 uint32_t trace_field_count = have_stack_trace ? 2 : 0;
314 uint32_t trace_field_count = have_stack_trace ? 3 : 0;314 return frame_index_trace_arg(g, fn_type_id) + trace_field_count;
315 return frame_index_trace(g, fn_type_id) + trace_field_count;
316}315}
317316
317// label (grep this): [coro_frame_struct_layout]
318static uint32_t frame_index_trace_stack(CodeGen *g, FnTypeId *fn_type_id) {
319 uint32_t result = frame_index_arg(g, fn_type_id);
320 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
321 if (type_has_bits(fn_type_id->param_info->type)) {
322 result += 1;
323 }
324 }
325 return result;
326}
327
328
318static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {329static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
319 if (!g->have_err_ret_tracing) {330 if (!g->have_err_ret_tracing) {
320 return UINT32_MAX;331 return UINT32_MAX;
...@@ -1287,9 +1298,6 @@ static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) {...@@ -1287,9 +1298,6 @@ static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) {
1287 if (!g->have_err_ret_tracing) {1298 if (!g->have_err_ret_tracing) {
1288 return nullptr;1299 return nullptr;
1289 }1300 }
1290 if (fn_is_async(g->cur_fn)) {
1291 return LLVMBuildLoad(g->builder, g->cur_err_ret_trace_val_arg, "");
1292 }
1293 if (g->cur_err_ret_trace_val_stack != nullptr) {1301 if (g->cur_err_ret_trace_val_stack != nullptr) {
1294 return g->cur_err_ret_trace_val_stack;1302 return g->cur_err_ret_trace_val_stack;
1295 }1303 }
...@@ -3441,6 +3449,10 @@ static void render_async_spills(CodeGen *g) {...@@ -3441,6 +3449,10 @@ static void render_async_spills(CodeGen *g) {
3441 gen_var_debug_decl(g, var);3449 gen_var_debug_decl(g, var);
3442 }3450 }
3443 }3451 }
3452 // label (grep this): [coro_frame_struct_layout]
3453 if (codegen_fn_has_err_ret_tracing_stack(g, g->cur_fn)) {
3454 async_var_index += 2;
3455 }
3444 for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) {3456 for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) {
3445 IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);3457 IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);
3446 ZigType *ptr_type = instruction->base.value.type;3458 ZigType *ptr_type = instruction->base.value.type;
...@@ -3525,7 +3537,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3525,7 +3537,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3525 CallingConvention cc = fn_type->data.fn.fn_type_id.cc;3537 CallingConvention cc = fn_type->data.fn.fn_type_id.cc;
35263538
3527 bool first_arg_ret = ret_has_bits && want_first_arg_sret(g, fn_type_id);3539 bool first_arg_ret = ret_has_bits && want_first_arg_sret(g, fn_type_id);
3528 bool prefix_arg_err_ret_stack = codegen_fn_has_err_ret_tracing(g, fn_type_id->return_type);3540 bool prefix_arg_err_ret_stack = codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type);
3529 bool is_var_args = fn_type_id->is_var_args;3541 bool is_var_args = fn_type_id->is_var_args;
3530 ZigList<LLVMValueRef> gen_param_values = {};3542 ZigList<LLVMValueRef> gen_param_values = {};
3531 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;3543 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;
...@@ -3572,28 +3584,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3572,28 +3584,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3572 }3584 }
3573 }3585 }
35743586
3575 if (prefix_arg_err_ret_stack) {3587 // even if prefix_arg_err_ret_stack is true, let the async function do its own
3576 uint32_t trace_field_index = frame_index_trace(g, fn_type_id);3588 // initialization.
3577 LLVMValueRef trace_field_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
3578 trace_field_index, "");
3579 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
3580 trace_field_index + 1, "");
3581 LLVMValueRef trace_field_addrs = LLVMBuildStructGEP(g->builder, frame_result_loc,
3582 trace_field_index + 2, "");
3583 LLVMBuildStore(g->builder, trace_field_ptr, trace_field_ptr_ptr);
3584
3585 LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, "");
3586 LLVMBuildStore(g->builder, zero, index_ptr);
3587
3588 LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 1, "");
3589 LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_ptr_index, "");
3590 LLVMValueRef indices[] = { LLVMConstNull(usize_type_ref), LLVMConstNull(usize_type_ref) };
3591 LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP(g->builder, trace_field_addrs, indices, 2, "");
3592 LLVMBuildStore(g->builder, trace_field_addrs_as_ptr, addrs_ptr_ptr);
3593
3594 LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_len_index, "");
3595 LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
3596 }
3597 } else if (callee_is_async) {3589 } else if (callee_is_async) {
3598 frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc);3590 frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc);
3599 awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_ret_ptr, usize_type_ref, ""); // caller's own frame pointer3591 awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_ret_ptr, usize_type_ref, ""); // caller's own frame pointer
...@@ -3607,13 +3599,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3607,13 +3599,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3607 }3599 }
3608 }3600 }
36093601
3610 if (prefix_arg_err_ret_stack) {3602 // even if prefix_arg_err_ret_stack is true, let the async function do its
3611 uint32_t trace_field_index = frame_index_trace(g, fn_type_id);3603 // error return tracing normally, and then we'll invoke merge_error_return_traces like normal.
3612 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, trace_field_index, "");
3613 LLVMValueRef err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope);
3614 LLVMBuildStore(g->builder, err_trace_val, trace_field_ptr);
3615 }
3616
3617 }3604 }
3618 if (instruction->is_async || callee_is_async) {3605 if (instruction->is_async || callee_is_async) {
3619 assert(frame_result_loc != nullptr);3606 assert(frame_result_loc != nullptr);
...@@ -6790,9 +6777,16 @@ static void do_code_gen(CodeGen *g) {...@@ -6790,9 +6777,16 @@ static void do_code_gen(CodeGen *g) {
6790 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_awaiter_index, "");6777 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_awaiter_index, "");
6791 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_resume_index, "");6778 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_resume_index, "");
6792 g->cur_async_resume_index_ptr = resume_index_ptr;6779 g->cur_async_resume_index_ptr = resume_index_ptr;
6793 if (codegen_fn_has_err_ret_tracing(g, fn_type_id->return_type)) {6780 LLVMValueRef err_ret_trace_val = nullptr;
6794 uint32_t field_index = frame_index_trace(g, fn_type_id);6781 uint32_t trace_field_index;
6795 g->cur_err_ret_trace_val_arg = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, field_index, "");6782 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
6783 trace_field_index = frame_index_trace_arg(g, fn_type_id);
6784 err_ret_trace_val = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, trace_field_index, "");
6785 g->cur_err_ret_trace_val_arg = err_ret_trace_val;
6786 } else if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry)) {
6787 trace_field_index = frame_index_trace_stack(g, fn_type_id);
6788 err_ret_trace_val = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, trace_field_index, "");
6789 g->cur_err_ret_trace_val_stack = err_ret_trace_val;
6796 }6790 }
67976791
6798 LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");6792 LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");
...@@ -6804,6 +6798,24 @@ static void do_code_gen(CodeGen *g) {...@@ -6804,6 +6798,24 @@ static void do_code_gen(CodeGen *g) {
6804 LLVMAddCase(switch_instr, zero, entry_block->llvm_block);6798 LLVMAddCase(switch_instr, zero, entry_block->llvm_block);
6805 g->cur_resume_block_count += 1;6799 g->cur_resume_block_count += 1;
6806 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);6800 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);
6801 if (err_ret_trace_val != nullptr) {
6802 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6803 trace_field_index, "");
6804 LLVMValueRef trace_field_addrs = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6805 trace_field_index + 1, "");
6806
6807 LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, "");
6808 LLVMBuildStore(g->builder, zero, index_ptr);
6809
6810 LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 1, "");
6811 LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_ptr_index, "");
6812 LLVMValueRef indices[] = { LLVMConstNull(usize_type_ref), LLVMConstNull(usize_type_ref) };
6813 LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP(g->builder, trace_field_addrs, indices, 2, "");
6814 LLVMBuildStore(g->builder, trace_field_addrs_as_ptr, addrs_ptr_ptr);
6815
6816 LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_len_index, "");
6817 LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
6818 }
6807 render_async_var_decls(g, entry_block->instruction_list.at(0)->scope);6819 render_async_var_decls(g, entry_block->instruction_list.at(0)->scope);
6808 } else {6820 } else {
6809 // create debug variable declarations for parameters6821 // create debug variable declarations for parameters
...@@ -9707,8 +9719,13 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget...@@ -9707,8 +9719,13 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
9707 return g;9719 return g;
9708}9720}
97099721
9710bool codegen_fn_has_err_ret_tracing(CodeGen *g, ZigType *return_type) {9722bool codegen_fn_has_err_ret_tracing_arg(CodeGen *g, ZigType *return_type) {
9711 return g->have_err_ret_tracing &&9723 return g->have_err_ret_tracing &&
9712 (return_type->id == ZigTypeIdErrorUnion ||9724 (return_type->id == ZigTypeIdErrorUnion ||
9713 return_type->id == ZigTypeIdErrorSet);9725 return_type->id == ZigTypeIdErrorSet);
9714}9726}
9727
9728bool codegen_fn_has_err_ret_tracing_stack(CodeGen *g, ZigFn *fn) {
9729 return g->have_err_ret_tracing && fn->calls_or_awaits_errorable_fn &&
9730 !codegen_fn_has_err_ret_tracing_arg(g, fn->type_entry->data.fn.fn_type_id.return_type);
9731}
src/codegen.hpp+2-1
...@@ -61,6 +61,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g);...@@ -61,6 +61,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g);
61TargetSubsystem detect_subsystem(CodeGen *g);61TargetSubsystem detect_subsystem(CodeGen *g);
6262
63void codegen_release_caches(CodeGen *codegen);63void codegen_release_caches(CodeGen *codegen);
64bool codegen_fn_has_err_ret_tracing(CodeGen *g, ZigType *return_type);64bool codegen_fn_has_err_ret_tracing_arg(CodeGen *g, ZigType *return_type);
65bool codegen_fn_has_err_ret_tracing_stack(CodeGen *g, ZigFn *fn);
6566
66#endif67#endif
src/ir.cpp+4-3
...@@ -15560,9 +15560,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15560,9 +15560,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15560 break;15560 break;
15561 }15561 }
15562 }15562 }
15563 if (call_instruction->is_async) {
15564 zig_panic("TODO async call");
15565 }
1556615563
15567 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn);15564 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn);
15568 if (existing_entry) {15565 if (existing_entry) {
...@@ -24483,6 +24480,10 @@ static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstruction...@@ -24483,6 +24480,10 @@ static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstruction
24483 fn_entry->inferred_async_node = instruction->base.source_node;24480 fn_entry->inferred_async_node = instruction->base.source_node;
24484 }24481 }
2448524482
24483 if (type_can_fail(result_type)) {
24484 fn_entry->calls_or_awaits_errorable_fn = true;
24485 }
24486
24486 IrInstruction *result = ir_build_await(&ira->new_irb,24487 IrInstruction *result = ir_build_await(&ira->new_irb,
24487 instruction->base.scope, instruction->base.source_node, frame);24488 instruction->base.scope, instruction->base.source_node, frame);
24488 result->value.type = result_type;24489 result->value.type = result_type;
test/stage1/behavior/coroutines.zig+9-7
...@@ -337,19 +337,21 @@ test "async fn with inferred error set" {...@@ -337,19 +337,21 @@ test "async fn with inferred error set" {
337//test "error return trace across suspend points - early return" {337//test "error return trace across suspend points - early return" {
338// const p = nonFailing();338// const p = nonFailing();
339// resume p;339// resume p;
340// const p2 = try async<allocator> printTrace(p);340// const p2 = async printTrace(p);
341// cancel p2;
342//}341//}
343//342//
344//test "error return trace across suspend points - async return" {343//test "error return trace across suspend points - async return" {
345// const p = nonFailing();344// const p = nonFailing();
346// const p2 = try async<std.debug.global_allocator> printTrace(p);345// const p2 = async printTrace(p);
347// resume p;346// resume p;
348// cancel p2;
349//}347//}
350//348//
351//fn nonFailing() (anyframe->anyerror!void) {349//fn nonFailing() (anyframe->anyerror!void) {
352// return async<std.debug.global_allocator> suspendThenFail() catch unreachable;350// const Static = struct {
351// var frame: @Frame(suspendThenFail) = undefined;
352// };
353// Static.frame = async suspendThenFail();
354// return &Static.frame;
353//}355//}
354//async fn suspendThenFail() anyerror!void {356//async fn suspendThenFail() anyerror!void {
355// suspend;357// suspend;
...@@ -361,8 +363,8 @@ test "async fn with inferred error set" {...@@ -361,8 +363,8 @@ test "async fn with inferred error set" {
361// if (@errorReturnTrace()) |trace| {363// if (@errorReturnTrace()) |trace| {
362// expect(trace.index == 1);364// expect(trace.index == 1);
363// } else switch (builtin.mode) {365// } else switch (builtin.mode) {
364// builtin.Mode.Debug, builtin.Mode.ReleaseSafe => @panic("expected return trace"),366// .Debug, .ReleaseSafe => @panic("expected return trace"),
365// builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => {},367// .ReleaseFast, .ReleaseSmall => {},
366// }368// }
367// };369// };
368//}370//}