diff options
| -rw-r--r-- | src/ir.cpp | 14 | ||||
| -rw-r--r-- | test/stage1/behavior/error.zig | 27 |
2 files changed, 35 insertions, 6 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 4cedaf95e3..78df2287eb 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10373,10 +10373,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT continue; } ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; - if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { + bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && + cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { return ira->codegen->builtin_types.entry_invalid; } - if (type_is_global_error_set(cur_err_set_type)) { + if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { err_set_type = ira->codegen->builtin_types.entry_global_error_set; prev_inst = cur_inst; continue; @@ -16079,6 +16081,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } else { alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, alloca_src->name_hint, force_comptime); + if (force_runtime) { + alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; + alloca_gen->value->special = ConstValSpecialRuntime; + } } if (alloca_src->base.child != nullptr && !result_loc->written) { alloca_src->base.child->ref_count = 0; @@ -26993,10 +26999,6 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) return result_loc; - if (instruction->result_loc_cast->parent->gen_instruction != nullptr) { - return instruction->result_loc_cast->parent->gen_instruction; - } - ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) return ira->codegen->invalid_instruction; diff --git a/test/stage1/behavior/error.zig b/test/stage1/behavior/error.zig index 9b7904e9cf..f9b331caaf 100644 --- a/test/stage1/behavior/error.zig +++ b/test/stage1/behavior/error.zig @@ -400,3 +400,30 @@ test "function pointer with return type that is error union with payload which i }; S.doTheTest(); } + +test "return result loc as peer result loc in inferred error set function" { + const S = struct { + fn doTheTest() void { + if (foo(2)) |x| { + expect(x.Two); + } else |e| switch (e) { + error.Whatever => @panic("fail"), + } + expectError(error.Whatever, foo(99)); + } + const FormValue = union(enum) { + One: void, + Two: bool, + }; + + fn foo(id: u64) !FormValue { + return switch (id) { + 2 => FormValue{ .Two = true }, + 1 => FormValue{ .One = {} }, + else => return error.Whatever, + }; + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} |
