aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-06-19 17:07:05 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-06-19 17:07:05 -0400
commitc7dc03fcb16abfac2d914002a609b8144f7cdab2 (patch)
treea1af2d48810cbdcd34b0904271e19d2248d62a27
parent96931228af745b8e69c138b3b83893dafa166cfe (diff)
downloadzig-c7dc03fcb16abfac2d914002a609b8144f7cdab2.tar.gz
zig-c7dc03fcb16abfac2d914002a609b8144f7cdab2.zip
fix `try` not setting error code on result location
-rw-r--r--src/ir.cpp9
-rw-r--r--test/stage1/behavior.zig2
-rw-r--r--test/stage1/behavior/error.zig84
3 files changed, 51 insertions, 44 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 6de4202c5f..356a1a8cc8 100644
--- a/src/ir.cpp
+++ b/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);
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index 0e93290cc4..5824f9380f 100644
--- a/test/stage1/behavior.zig
+++ b/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");
diff --git a/test/stage1/behavior/error.zig b/test/stage1/behavior/error.zig
index 861c500751..babefba6f5 100644
--- a/test/stage1/behavior/error.zig
+++ b/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 {