Commit 4d9318cee0

Vexu <15308111+Vexu@users.noreply.github.com>
2019-11-19 16:29:43
fix missing implicit cast in return instruction
1 parent 0b63573
Changed files (2)
src/ir.cpp
@@ -13535,16 +13535,6 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
     if (type_is_invalid(operand->value.type))
         return ir_unreach_error(ira);
 
-    if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr &&
-            handle_is_ptr(ira->explicit_return_type))
-    {
-        // result location mechanism took care of it.
-        IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
-                instruction->base.source_node, nullptr);
-        result->value.type = ira->codegen->builtin_types.entry_unreachable;
-        return ir_finish_anal(ira, result);
-    }
-
     IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
     if (type_is_invalid(casted_operand->value.type)) {
         AstNode *source_node = ira->explicit_return_type_source_node;
@@ -13556,6 +13546,16 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
         return ir_unreach_error(ira);
     }
 
+    if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr &&
+            handle_is_ptr(ira->explicit_return_type))
+    {
+        // result location mechanism took care of it.
+        IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
+                instruction->base.source_node, nullptr);
+        result->value.type = ira->codegen->builtin_types.entry_unreachable;
+        return ir_finish_anal(ira, result);
+    }
+
     if (casted_operand->value.special == ConstValSpecialRuntime &&
         casted_operand->value.type->id == ZigTypeIdPointer &&
         casted_operand->value.data.rh_ptr == RuntimeHintPtrStack)
test/compile_errors.zig
@@ -12,6 +12,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "tmp.zig:3:5: error: switch must handle all possibilities",
     );
 
+    cases.add(
+        "incorrect return type",
+        \\ pub export fn entry() void{
+        \\     _ = foo();
+        \\ }
+        \\ const A = struct {
+        \\     a: u32,
+        \\ };
+        \\ fn foo() A {
+        \\     return bar();
+        \\ }
+        \\ const B = struct {
+        \\     a: u32,
+        \\ };
+        \\ fn bar() B {
+        \\     unreachable;
+        \\ }
+    ,
+        "tmp.zig:8:16: error: expected type 'A', found 'B'",
+    );
+
     cases.add(
         "regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
         \\const Foo = struct {