Commit c7dc03fcb1

Andrew Kelley <andrew@ziglang.org>
2019-06-19 23:07:05
fix `try` not setting error code on result location
1 parent 9693122
Changed files (3)
src
test
stage1
src/ir.cpp
@@ -3657,10 +3657,17 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
                 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {
                     IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);
                     IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
+
+                    ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
+                    result_loc_ret->base.id = ResultLocIdReturn;
+                    ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
+                    ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base);
+
                     if (irb->codegen->have_err_ret_tracing && !should_inline) {
                         ir_build_save_err_ret_addr(irb, scope, node);
                     }
-                    ir_gen_async_return(irb, scope, node, err_val, false);
+                    IrInstruction *ret_inst = ir_gen_async_return(irb, scope, node, err_val, false);
+                    result_loc_ret->base.source_instruction = ret_inst;
                 }
 
                 ir_set_cursor_at_end_and_append_block(irb, continue_block);
test/stage1/behavior/error.zig
@@ -249,48 +249,48 @@ fn intLiteral(str: []const u8) !?i64 {
     return error.T;
 }
 
-//test "nested error union function call in optional unwrap" {
-//    const S = struct {
-//        const Foo = struct {
-//            a: i32,
-//        };
-//
-//        fn errorable() !i32 {
-//            var x: Foo = (try getFoo()) orelse return error.Other;
-//            return x.a;
-//        }
-//
-//        fn errorable2() !i32 {
-//            var x: Foo = (try getFoo2()) orelse return error.Other;
-//            return x.a;
-//        }
-//
-//        fn errorable3() !i32 {
-//            var x: Foo = (try getFoo3()) orelse return error.Other;
-//            return x.a;
-//        }
-//
-//        fn getFoo() anyerror!?Foo {
-//            return Foo{ .a = 1234 };
-//        }
-//
-//        fn getFoo2() anyerror!?Foo {
-//            return error.Failure;
-//        }
-//
-//        fn getFoo3() anyerror!?Foo {
-//            return null;
-//        }
-//    };
-//    expect((try S.errorable()) == 1234);
-//    expectError(error.Failure, S.errorable2());
-//    expectError(error.Other, S.errorable3());
-//    comptime {
-//        expect((try S.errorable()) == 1234);
-//        expectError(error.Failure, S.errorable2());
-//        expectError(error.Other, S.errorable3());
-//    }
-//}
+test "nested error union function call in optional unwrap" {
+    const S = struct {
+        const Foo = struct {
+            a: i32,
+        };
+
+        fn errorable() !i32 {
+            var x: Foo = (try getFoo()) orelse return error.Other;
+            return x.a;
+        }
+
+        fn errorable2() !i32 {
+            var x: Foo = (try getFoo2()) orelse return error.Other;
+            return x.a;
+        }
+
+        fn errorable3() !i32 {
+            var x: Foo = (try getFoo3()) orelse return error.Other;
+            return x.a;
+        }
+
+        fn getFoo() anyerror!?Foo {
+            return Foo{ .a = 1234 };
+        }
+
+        fn getFoo2() anyerror!?Foo {
+            return error.Failure;
+        }
+
+        fn getFoo3() anyerror!?Foo {
+            return null;
+        }
+    };
+    expect((try S.errorable()) == 1234);
+    expectError(error.Failure, S.errorable2());
+    expectError(error.Other, S.errorable3());
+    comptime {
+        expect((try S.errorable()) == 1234);
+        expectError(error.Failure, S.errorable2());
+        expectError(error.Other, S.errorable3());
+    }
+}
 
 test "widen cast integer payload of error union function call" {
     const S = struct {
test/stage1/behavior.zig
@@ -47,7 +47,7 @@ comptime {
     _ = @import("behavior/defer.zig");
     _ = @import("behavior/enum.zig");
     _ = @import("behavior/enum_with_members.zig");
-    _ = @import("behavior/error.zig"); // TODO
+    _ = @import("behavior/error.zig");
     _ = @import("behavior/eval.zig");
     _ = @import("behavior/field_parent_ptr.zig");
     _ = @import("behavior/fn.zig");