From 7a4d69983a6ac7ab91f71910cec5886ed5bec745 Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Tue, 3 Sep 2024 14:37:15 -0400 Subject: [PATCH] AstGen: update @errorCast to maybe eval to err Consequently, `AstGen.ret()` now passes the error code to `.defer_error_code`. Previously, the error union value was passed. closes #20371 --- lib/std/zig/BuiltinFn.zig | 2 +- test/behavior/defer.zig | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/std/zig/BuiltinFn.zig b/lib/std/zig/BuiltinFn.zig index 1da3ffb5a7..95c6c7be12 100644 --- a/lib/std/zig/BuiltinFn.zig +++ b/lib/std/zig/BuiltinFn.zig @@ -482,7 +482,7 @@ pub const list = list: { "@errorCast", .{ .tag = .error_cast, - .eval_to_error = .always, + .eval_to_error = .maybe, .param_count = 1, }, }, diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index 64bd1a5e0d..07519f16b5 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -197,3 +197,40 @@ const defer_assign = switch (block: { comptime { if (defer_assign != 0) @compileError("defer_assign failed!"); } + +test "errdefer capture" { + const S = struct { + fail: bool = undefined, + fn bar0(self: *@This()) error{a}!void { + self.fail = false; + errdefer |err| if (@TypeOf(err) != error{a}) { + self.fail = true; + }; + return error.a; + } + fn bar1(self: *@This()) error{a}!void { + self.fail = false; + errdefer |err| if (@TypeOf(err) != error{a}) { + self.fail = true; + }; + const rv: error{a}!void = @errorCast(@as(error{a}!void, error.a)); + return rv; + } + // https://github.com/ziglang/zig/issues/20371 + fn bar2(self: *@This()) error{a}!void { + self.fail = false; + errdefer |err| if (@TypeOf(err) != error{a}) { + self.fail = true; + }; + return @errorCast(@as(error{a}!void, error.a)); + } + }; + + var s: S = .{}; + s.bar0() catch {}; + if (s.fail) return error.TestExpectedError; + s.bar1() catch {}; + if (s.fail) return error.TestExpectedError; + s.bar2() catch {}; + if (s.fail) return error.TestExpectedError; +}