authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-29 18:21:21-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-29 18:21:21-05:00
log815b4cfd9d77e5cf3330cc74caf0987f353a8935
tree2e1b7b0f27df4fcc5b495bd1afc9c131005e3393
parentbcdb3a90066148dc5a91d176a8fc7f5d9c7487b1
signaturelock-open Commit is signed but in an unrecognized format.

fix return result loc as peer result loc in inferred error set function


2 files changed, 35 insertions(+), 6 deletions(-)

src/ir.cpp+8-6
...@@ -10373,10 +10373,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -10373,10 +10373,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
10373 continue;10373 continue;
10374 }10374 }
10375 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;10375 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
10376 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {10376 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
10377 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
10378 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) {
10377 return ira->codegen->builtin_types.entry_invalid;10379 return ira->codegen->builtin_types.entry_invalid;
10378 }10380 }
10379 if (type_is_global_error_set(cur_err_set_type)) {10381 if (!allow_infer && type_is_global_error_set(cur_err_set_type)) {
10380 err_set_type = ira->codegen->builtin_types.entry_global_error_set;10382 err_set_type = ira->codegen->builtin_types.entry_global_error_set;
10381 prev_inst = cur_inst;10383 prev_inst = cur_inst;
10382 continue;10384 continue;
...@@ -16079,6 +16081,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -16079,6 +16081,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
16079 } else {16081 } else {
16080 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,16082 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,
16081 alloca_src->name_hint, force_comptime);16083 alloca_src->name_hint, force_comptime);
16084 if (force_runtime) {
16085 alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar;
16086 alloca_gen->value->special = ConstValSpecialRuntime;
16087 }
16082 }16088 }
16083 if (alloca_src->base.child != nullptr && !result_loc->written) {16089 if (alloca_src->base.child != nullptr && !result_loc->written) {
16084 alloca_src->base.child->ref_count = 0;16090 alloca_src->base.child->ref_count = 0;
...@@ -26993,10 +26999,6 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns...@@ -26993,10 +26999,6 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
26993 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)))26999 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)))
26994 return result_loc;27000 return result_loc;
2699527001
26996 if (instruction->result_loc_cast->parent->gen_instruction != nullptr) {
26997 return instruction->result_loc_cast->parent->gen_instruction;
26998 }
26999
27000 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child);27002 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child);
27001 if (type_is_invalid(dest_type))27003 if (type_is_invalid(dest_type))
27002 return ira->codegen->invalid_instruction;27004 return ira->codegen->invalid_instruction;
test/stage1/behavior/error.zig+27
...@@ -400,3 +400,30 @@ test "function pointer with return type that is error union with payload which i...@@ -400,3 +400,30 @@ test "function pointer with return type that is error union with payload which i
400 };400 };
401 S.doTheTest();401 S.doTheTest();
402}402}
403
404test "return result loc as peer result loc in inferred error set function" {
405 const S = struct {
406 fn doTheTest() void {
407 if (foo(2)) |x| {
408 expect(x.Two);
409 } else |e| switch (e) {
410 error.Whatever => @panic("fail"),
411 }
412 expectError(error.Whatever, foo(99));
413 }
414 const FormValue = union(enum) {
415 One: void,
416 Two: bool,
417 };
418
419 fn foo(id: u64) !FormValue {
420 return switch (id) {
421 2 => FormValue{ .Two = true },
422 1 => FormValue{ .One = {} },
423 else => return error.Whatever,
424 };
425 }
426 };
427 S.doTheTest();
428 comptime S.doTheTest();
429}