Commit 7a4d69983a

Michael Dusan <michael.dusan@gmail.com>
2024-09-03 20:37:15
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
1 parent 242d268
Changed files (2)
lib
test
behavior
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,
             },
         },
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;
+}