| ... | @@ -197,6 +197,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -197,6 +197,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 197 | static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, | 197 | static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 198 | IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, | 198 | IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, |
| 199 | LVal lval, ResultLoc *parent_result_loc); | 199 | LVal lval, ResultLoc *parent_result_loc); |
| | 200 | static void ir_reset_result(ResultLoc *result_loc); |
| 200 | | 201 | |
| 201 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 202 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 202 | assert(get_src_ptr_type(const_val->type) != nullptr); | 203 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -3085,10 +3086,11 @@ static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, A | ... | @@ -3085,10 +3086,11 @@ static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, A |
| 3085 | } | 3086 | } |
| 3086 | | 3087 | |
| 3087 | static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, | 3088 | static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3088 | IrInstruction *value) | 3089 | IrInstruction *value, ResultLocReturn *result_loc_ret) |
| 3089 | { | 3090 | { |
| 3090 | IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); | 3091 | IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); |
| 3091 | instruction->value = value; | 3092 | instruction->value = value; |
| | 3093 | instruction->result_loc_ret = result_loc_ret; |
| 3092 | | 3094 | |
| 3093 | ir_ref_instruction(value, irb->current_basic_block); | 3095 | ir_ref_instruction(value, irb->current_basic_block); |
| 3094 | | 3096 | |
| ... | @@ -3505,7 +3507,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3505,7 +3507,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3505 | return_value = ir_build_const_void(irb, scope, node); | 3507 | return_value = ir_build_const_void(irb, scope, node); |
| 3506 | } | 3508 | } |
| 3507 | | 3509 | |
| 3508 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value)); | 3510 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret)); |
| 3509 | | 3511 | |
| 3510 | size_t defer_counts[2]; | 3512 | size_t defer_counts[2]; |
| 3511 | ir_count_defers(irb, scope, outer_scope, defer_counts); | 3513 | ir_count_defers(irb, scope, outer_scope, defer_counts); |
| ... | @@ -3580,7 +3582,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3580,7 +3582,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3580 | ir_set_cursor_at_end_and_append_block(irb, return_block); | 3582 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 3581 | IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); | 3583 | IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3582 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); | 3584 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 3583 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val)); | 3585 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); |
| 3584 | IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val, | 3586 | IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val, |
| 3585 | SpillIdRetErrCode); | 3587 | SpillIdRetErrCode); |
| 3586 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); | 3588 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| ... | @@ -3690,6 +3692,7 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { | ... | @@ -3690,6 +3692,7 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { |
| 3690 | result->base.id = ResultLocIdPeer; | 3692 | result->base.id = ResultLocIdPeer; |
| 3691 | result->base.source_instruction = peer_parent->base.source_instruction; | 3693 | result->base.source_instruction = peer_parent->base.source_instruction; |
| 3692 | result->parent = peer_parent; | 3694 | result->parent = peer_parent; |
| | 3695 | result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const; |
| 3693 | return result; | 3696 | return result; |
| 3694 | } | 3697 | } |
| 3695 | | 3698 | |
| ... | @@ -3812,7 +3815,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -3812,7 +3815,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3812 | // no need for save_err_ret_addr because this cannot return error | 3815 | // no need for save_err_ret_addr because this cannot return error |
| 3813 | // only generate unconditional defers | 3816 | // only generate unconditional defers |
| 3814 | | 3817 | |
| 3815 | ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result)); | 3818 | ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); |
| 3816 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); | 3819 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3817 | return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result)); | 3820 | return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result)); |
| 3818 | } | 3821 | } |
| ... | @@ -8207,7 +8210,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec | ... | @@ -8207,7 +8210,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8207 | } | 8210 | } |
| 8208 | | 8211 | |
| 8209 | if (!instr_is_unreachable(result)) { | 8212 | if (!instr_is_unreachable(result)) { |
| 8210 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result)); | 8213 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result, nullptr)); |
| 8211 | // no need for save_err_ret_addr because this cannot return error | 8214 | // no need for save_err_ret_addr because this cannot return error |
| 8212 | ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); | 8215 | ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); |
| 8213 | } | 8216 | } |
| ... | @@ -12939,7 +12942,9 @@ static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze | ... | @@ -12939,7 +12942,9 @@ static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze |
| 12939 | if (type_is_invalid(value->value.type)) | 12942 | if (type_is_invalid(value->value.type)) |
| 12940 | return ir_unreach_error(ira); | 12943 | return ir_unreach_error(ira); |
| 12941 | | 12944 | |
| 12942 | ira->src_implicit_return_type_list.append(value); | 12945 | if (instruction->result_loc_ret == nullptr || !instruction->result_loc_ret->implicit_return_type_done) { |
| | 12946 | ira->src_implicit_return_type_list.append(value); |
| | 12947 | } |
| 12943 | | 12948 | |
| 12944 | return ir_const_void(ira, &instruction->base); | 12949 | return ir_const_void(ira, &instruction->base); |
| 12945 | } | 12950 | } |
| ... | @@ -14976,6 +14981,24 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { | ... | @@ -14976,6 +14981,24 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| 14976 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; | 14981 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| 14977 | } | 14982 | } |
| 14978 | | 14983 | |
| | 14984 | static bool ir_result_has_type(ResultLoc *result_loc) { |
| | 14985 | switch (result_loc->id) { |
| | 14986 | case ResultLocIdInvalid: |
| | 14987 | case ResultLocIdPeerParent: |
| | 14988 | zig_unreachable(); |
| | 14989 | case ResultLocIdNone: |
| | 14990 | case ResultLocIdPeer: |
| | 14991 | return false; |
| | 14992 | case ResultLocIdReturn: |
| | 14993 | case ResultLocIdInstruction: |
| | 14994 | case ResultLocIdBitCast: |
| | 14995 | return true; |
| | 14996 | case ResultLocIdVar: |
| | 14997 | return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; |
| | 14998 | } |
| | 14999 | zig_unreachable(); |
| | 15000 | } |
| | 15001 | |
| 14979 | // when calling this function, at the callsite must check for result type noreturn and propagate it up | 15002 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 14980 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, | 15003 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 14981 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) | 15004 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) |
| ... | @@ -15105,14 +15128,23 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe | ... | @@ -15105,14 +15128,23 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15105 | bool is_comptime; | 15128 | bool is_comptime; |
| 15106 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) | 15129 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) |
| 15107 | return ira->codegen->invalid_instruction; | 15130 | return ira->codegen->invalid_instruction; |
| 15108 | peer_parent->skipped = is_comptime; | 15131 | if (is_comptime) { |
| 15109 | if (peer_parent->skipped) { | 15132 | peer_parent->skipped = true; |
| 15110 | if (non_null_comptime) { | 15133 | if (non_null_comptime) { |
| 15111 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, | 15134 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 15112 | value_type, value, force_runtime, non_null_comptime, true); | 15135 | value_type, value, force_runtime, non_null_comptime, true); |
| 15113 | } | 15136 | } |
| 15114 | return nullptr; | 15137 | return nullptr; |
| 15115 | } | 15138 | } |
| | 15139 | if (ir_result_has_type(peer_parent->parent)) { |
| | 15140 | if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { |
| | 15141 | reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true; |
| | 15142 | ira->src_implicit_return_type_list.append(value); |
| | 15143 | } |
| | 15144 | peer_parent->skipped = true; |
| | 15145 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| | 15146 | value_type, value, force_runtime, true, true); |
| | 15147 | } |
| 15116 | | 15148 | |
| 15117 | if (peer_parent->resolved_type == nullptr) { | 15149 | if (peer_parent->resolved_type == nullptr) { |
| 15118 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { | 15150 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { |
| ... | @@ -15322,9 +15354,11 @@ static void ir_reset_result(ResultLoc *result_loc) { | ... | @@ -15322,9 +15354,11 @@ static void ir_reset_result(ResultLoc *result_loc) { |
| 15322 | alloca_src->base.child = nullptr; | 15354 | alloca_src->base.child = nullptr; |
| 15323 | break; | 15355 | break; |
| 15324 | } | 15356 | } |
| | 15357 | case ResultLocIdReturn: |
| | 15358 | reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = false; |
| | 15359 | break; |
| 15325 | case ResultLocIdPeer: | 15360 | case ResultLocIdPeer: |
| 15326 | case ResultLocIdNone: | 15361 | case ResultLocIdNone: |
| 15327 | case ResultLocIdReturn: | | |
| 15328 | case ResultLocIdInstruction: | 15362 | case ResultLocIdInstruction: |
| 15329 | case ResultLocIdBitCast: | 15363 | case ResultLocIdBitCast: |
| 15330 | break; | 15364 | break; |
| ... | @@ -16880,10 +16914,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16880,10 +16914,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16880 | return new_incoming_values.at(0); | 16914 | return new_incoming_values.at(0); |
| 16881 | } | 16915 | } |
| 16882 | | 16916 | |
| 16883 | ZigType *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, | 16917 | ZigType *resolved_type; |
| 16884 | new_incoming_values.items, new_incoming_values.length); | 16918 | if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) { |
| 16885 | if (type_is_invalid(resolved_type)) | 16919 | if (peer_parent->parent->id == ResultLocIdReturn) { |
| 16886 | return ira->codegen->invalid_instruction; | 16920 | resolved_type = ira->explicit_return_type; |
| | 16921 | } else { |
| | 16922 | ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; |
| | 16923 | ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); |
| | 16924 | resolved_type = resolved_loc_ptr_type->data.pointer.child_type; |
| | 16925 | } |
| | 16926 | } else { |
| | 16927 | resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, |
| | 16928 | new_incoming_values.items, new_incoming_values.length); |
| | 16929 | if (type_is_invalid(resolved_type)) |
| | 16930 | return ira->codegen->invalid_instruction; |
| | 16931 | } |
| 16887 | | 16932 | |
| 16888 | switch (type_has_one_possible_value(ira->codegen, resolved_type)) { | 16933 | switch (type_has_one_possible_value(ira->codegen, resolved_type)) { |
| 16889 | case OnePossibleValueInvalid: | 16934 | case OnePossibleValueInvalid: |
| ... | @@ -25055,7 +25100,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct | ... | @@ -25055,7 +25100,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 25055 | if (result_loc->value.type->id == ZigTypeIdUnreachable) | 25100 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 25056 | return result_loc; | 25101 | return result_loc; |
| 25057 | | 25102 | |
| 25058 | if (!was_written) { | 25103 | if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { |
| 25059 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, | 25104 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, |
| 25060 | instruction->result_loc->allow_write_through_const); | 25105 | instruction->result_loc->allow_write_through_const); |
| 25061 | if (type_is_invalid(store_ptr->value.type)) { | 25106 | if (type_is_invalid(store_ptr->value.type)) { |
| ... | @@ -25063,7 +25108,9 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct | ... | @@ -25063,7 +25108,9 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 25063 | } | 25108 | } |
| 25064 | } | 25109 | } |
| 25065 | | 25110 | |
| 25066 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { | 25111 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer && |
| | 25112 | instruction->result_loc->id != ResultLocIdPeer) |
| | 25113 | { |
| 25067 | if (instr_is_comptime(value)) { | 25114 | if (instr_is_comptime(value)) { |
| 25068 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; | 25115 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 25069 | } else { | 25116 | } else { |