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; +}