| ... | @@ -189,6 +189,8 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s | ... | @@ -189,6 +189,8 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 189 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); | 189 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value); |
| 190 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, | 190 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 191 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); | 191 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| | 192 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| | 193 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| 192 | | 194 | |
| 193 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 195 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 194 | assert(get_src_ptr_type(const_val->type) != nullptr); | 196 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -2424,11 +2426,12 @@ static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, Ast | ... | @@ -2424,11 +2426,12 @@ static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, Ast |
| 2424 | } | 2426 | } |
| 2425 | | 2427 | |
| 2426 | static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2428 | static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2427 | IrInstruction *value, bool safety_check_on) | 2429 | IrInstruction *value, bool safety_check_on, bool initializing) |
| 2428 | { | 2430 | { |
| 2429 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); | 2431 | IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); |
| 2430 | instruction->value = value; | 2432 | instruction->value = value; |
| 2431 | instruction->safety_check_on = safety_check_on; | 2433 | instruction->safety_check_on = safety_check_on; |
| | 2434 | instruction->initializing = initializing; |
| 2432 | | 2435 | |
| 2433 | ir_ref_instruction(value, irb->current_basic_block); | 2436 | ir_ref_instruction(value, irb->current_basic_block); |
| 2434 | | 2437 | |
| ... | @@ -3572,7 +3575,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, | ... | @@ -3572,7 +3575,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3572 | } | 3575 | } |
| 3573 | | 3576 | |
| 3574 | ir_set_cursor_at_end_and_append_block(irb, continue_block); | 3577 | ir_set_cursor_at_end_and_append_block(irb, continue_block); |
| 3575 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); | 3578 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); |
| 3576 | if (lval == LValPtr) | 3579 | if (lval == LValPtr) |
| 3577 | return unwrapped_ptr; | 3580 | return unwrapped_ptr; |
| 3578 | else | 3581 | else |
| ... | @@ -5578,7 +5581,7 @@ static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, Ast | ... | @@ -5578,7 +5581,7 @@ static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, Ast |
| 5578 | if (err_union_ptr == irb->codegen->invalid_instruction) | 5581 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5579 | return irb->codegen->invalid_instruction; | 5582 | return irb->codegen->invalid_instruction; |
| 5580 | | 5583 | |
| 5581 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); | 5584 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); |
| 5582 | if (payload_ptr == irb->codegen->invalid_instruction) | 5585 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 5583 | return irb->codegen->invalid_instruction; | 5586 | return irb->codegen->invalid_instruction; |
| 5584 | | 5587 | |
| ... | @@ -5915,7 +5918,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -5915,7 +5918,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5915 | ir_set_cursor_at_end_and_append_block(irb, body_block); | 5918 | ir_set_cursor_at_end_and_append_block(irb, body_block); |
| 5916 | if (var_symbol) { | 5919 | if (var_symbol) { |
| 5917 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, | 5920 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, |
| 5918 | err_val_ptr, false); | 5921 | err_val_ptr, false, false); |
| 5919 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? | 5922 | IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? |
| 5920 | ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; | 5923 | ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; |
| 5921 | ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); | 5924 | ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); |
| ... | @@ -6694,7 +6697,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -6694,7 +6697,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6694 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, | 6697 | ZigVar *var = ir_create_var(irb, node, subexpr_scope, |
| 6695 | var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); | 6698 | var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); |
| 6696 | | 6699 | |
| 6697 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); | 6700 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false); |
| 6698 | IrInstruction *var_ptr = var_is_ptr ? | 6701 | IrInstruction *var_ptr = var_is_ptr ? |
| 6699 | ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; | 6702 | ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; |
| 6700 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); | 6703 | ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); |
| ... | @@ -7316,7 +7319,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode | ... | @@ -7316,7 +7319,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode |
| 7316 | ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); | 7319 | ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); |
| 7317 | | 7320 | |
| 7318 | ir_set_cursor_at_end_and_append_block(irb, ok_block); | 7321 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 7319 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); | 7322 | IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); |
| 7320 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); | 7323 | IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); |
| 7321 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); | 7324 | ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); |
| 7322 | IrBasicBlock *after_ok_block = irb->current_basic_block; | 7325 | IrBasicBlock *after_ok_block = irb->current_basic_block; |
| ... | @@ -14947,6 +14950,8 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn | ... | @@ -14947,6 +14950,8 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn |
| 14947 | ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type; | 14950 | ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type; |
| 14948 | if (actual_elem_type->id == ZigTypeIdOptional && implicit_elem_type->id != ZigTypeIdOptional) { | 14951 | if (actual_elem_type->id == ZigTypeIdOptional && implicit_elem_type->id != ZigTypeIdOptional) { |
| 14949 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, result_loc, false, true); | 14952 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, result_loc, false, true); |
| | 14953 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && implicit_elem_type->id != ZigTypeIdErrorUnion) { |
| | 14954 | return ir_analyze_unwrap_error_payload(ira, &instruction->base, result_loc, false, true); |
| 14950 | } | 14955 | } |
| 14951 | return result_loc; | 14956 | return result_loc; |
| 14952 | } | 14957 | } |
| ... | @@ -22136,14 +22141,10 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI | ... | @@ -22136,14 +22141,10 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 22136 | return result; | 22141 | return result; |
| 22137 | } | 22142 | } |
| 22138 | | 22143 | |
| 22139 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | 22144 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 22140 | IrInstructionUnwrapErrPayload *instruction) | 22145 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 22141 | { | 22146 | { |
| 22142 | assert(instruction->value->child); | 22147 | ZigType *ptr_type = base_ptr->value.type; |
| 22143 | IrInstruction *value = instruction->value->child; | | |
| 22144 | if (type_is_invalid(value->value.type)) | | |
| 22145 | return ira->codegen->invalid_instruction; | | |
| 22146 | ZigType *ptr_type = value->value.type; | | |
| 22147 | | 22148 | |
| 22148 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. | 22149 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 22149 | assert(ptr_type->id == ZigTypeIdPointer); | 22150 | assert(ptr_type->id == ZigTypeIdPointer); |
| ... | @@ -22153,7 +22154,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -22153,7 +22154,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 22153 | return ira->codegen->invalid_instruction; | 22154 | return ira->codegen->invalid_instruction; |
| 22154 | | 22155 | |
| 22155 | if (type_entry->id != ZigTypeIdErrorUnion) { | 22156 | if (type_entry->id != ZigTypeIdErrorUnion) { |
| 22156 | ir_add_error(ira, value, | 22157 | ir_add_error(ira, base_ptr, |
| 22157 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); | 22158 | buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); |
| 22158 | return ira->codegen->invalid_instruction; | 22159 | return ira->codegen->invalid_instruction; |
| 22159 | } | 22160 | } |
| ... | @@ -22165,23 +22166,23 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -22165,23 +22166,23 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 22165 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, | 22166 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, |
| 22166 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, | 22167 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 22167 | PtrLenSingle, 0, 0, 0, false); | 22168 | PtrLenSingle, 0, 0, 0, false); |
| 22168 | if (instr_is_comptime(value)) { | 22169 | if (instr_is_comptime(base_ptr)) { |
| 22169 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); | 22170 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 22170 | if (!ptr_val) | 22171 | if (!ptr_val) |
| 22171 | return ira->codegen->invalid_instruction; | 22172 | return ira->codegen->invalid_instruction; |
| 22172 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 22173 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 22173 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); | 22174 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 22174 | if (err_union_val == nullptr) | 22175 | if (err_union_val == nullptr) |
| 22175 | return ira->codegen->invalid_instruction; | 22176 | return ira->codegen->invalid_instruction; |
| 22176 | if (err_union_val->special != ConstValSpecialRuntime) { | 22177 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 22177 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; | 22178 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 22178 | if (err != nullptr) { | 22179 | if (err != nullptr) { |
| 22179 | ir_add_error(ira, &instruction->base, | 22180 | ir_add_error(ira, source_instr, |
| 22180 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); | 22181 | buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); |
| 22181 | return ira->codegen->invalid_instruction; | 22182 | return ira->codegen->invalid_instruction; |
| 22182 | } | 22183 | } |
| 22183 | | 22184 | |
| 22184 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); | 22185 | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 22185 | result->value.data.x_ptr.special = ConstPtrSpecialRef; | 22186 | result->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 22186 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; | 22187 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| 22187 | return result; | 22188 | return result; |
| ... | @@ -22189,12 +22190,23 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -22189,12 +22190,23 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 22189 | } | 22190 | } |
| 22190 | } | 22191 | } |
| 22191 | | 22192 | |
| 22192 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, | 22193 | IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 22193 | instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); | 22194 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 22194 | result->value.type = result_type; | 22195 | result->value.type = result_type; |
| 22195 | return result; | 22196 | return result; |
| 22196 | } | 22197 | } |
| 22197 | | 22198 | |
| | 22199 | static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| | 22200 | IrInstructionUnwrapErrPayload *instruction) |
| | 22201 | { |
| | 22202 | assert(instruction->value->child); |
| | 22203 | IrInstruction *value = instruction->value->child; |
| | 22204 | if (type_is_invalid(value->value.type)) |
| | 22205 | return ira->codegen->invalid_instruction; |
| | 22206 | |
| | 22207 | return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); |
| | 22208 | } |
| | 22209 | |
| 22198 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { | 22210 | static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 22199 | AstNode *proto_node = instruction->base.source_node; | 22211 | AstNode *proto_node = instruction->base.source_node; |
| 22200 | assert(proto_node->type == NodeTypeFnProto); | 22212 | assert(proto_node->type == NodeTypeFnProto); |