diff --git a/src/ir.cpp b/src/ir.cpp index 6de4202c5..356a1a8cc 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(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 0e93290cc..5824f9380 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 861c50075..babefba6f 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 {