From e67c344fc0ec62748cbfb645e14b9f99ad3655cd Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Tue, 28 Apr 2026 13:06:32 +0100 Subject: [PATCH] compiler,tests,tools: remove uses of capturing errdefer In preparation for its removal, as accepted in https://github.com/ziglang/zig/issues/23734. --- src/codegen/aarch64/Select.zig | 8 +- test/behavior/defer.zig | 86 +------------------ .../invalid_error_capture_discard.zig | 19 ++-- .../unused_variable_error_on_errdefer.zig | 11 --- tools/update_cpu_features.zig | 4 +- 5 files changed, 15 insertions(+), 113 deletions(-) delete mode 100644 test/cases/compile_errors/unused_variable_error_on_errdefer.zig diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index 47bd499d5c..6eb0fe12d3 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11222,14 +11222,16 @@ fn initValueAdvanced( }; return @enumFromInt(isel.values.items.len); } -pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { +const WhichValues = enum { only_referenced, all }; +pub fn dumpValues(isel: *Select, which: WhichValues) void { + dumpValuesInner(isel, which) catch |err| @panic(@errorName(err)); +} +fn dumpValuesInner(isel: *Select, which: WhichValues) !void { const zcu = isel.pt.zcu; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const nav = ip.getNav(isel.nav_index); - errdefer |err| @panic(@errorName(err)); - const locked_stderr = std.debug.lockStderr(&.{}); defer std.debug.unlockStderr(); const stderr = &locked_stderr.file_writer.interface; diff --git a/test/behavior/defer.zig b/test/behavior/defer.zig index 05f74eff32..c90df21fbc 100644 --- a/test/behavior/defer.zig +++ b/test/behavior/defer.zig @@ -106,51 +106,6 @@ test "mixing normal and error defers" { try expect(result[2] == 'a'); } -test "errdefer with payload" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - - const S = struct { - fn foo() !i32 { - errdefer |a| { - expectEqual(error.One, a) catch @panic("test failure"); - } - return error.One; - } - fn doTheTest() !void { - try expectError(error.One, foo()); - } - }; - try S.doTheTest(); - try comptime S.doTheTest(); -} - -test "reference to errdefer payload" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - - const S = struct { - fn foo() !i32 { - errdefer |a| { - const ptr = &a; - const ptr2 = &ptr; - expectEqual(error.One, ptr2.*.*) catch @panic("test failure"); - expectEqual(error.One, ptr.*) catch @panic("test failure"); - } - return error.One; - } - fn doTheTest() !void { - try expectError(error.One, foo()); - } - }; - try S.doTheTest(); - try comptime S.doTheTest(); -} - test "simple else prong doesn't emit an error for unreachable else prong" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; @@ -192,47 +147,8 @@ 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; -} - test "errdefer in test block" { - errdefer |err| { - _ = &err; - } + errdefer {} var x: bool = false; _ = &x; if (x) return error.Something; diff --git a/test/cases/compile_errors/invalid_error_capture_discard.zig b/test/cases/compile_errors/invalid_error_capture_discard.zig index 1669c5d371..94f12d2a7d 100644 --- a/test/cases/compile_errors/invalid_error_capture_discard.zig +++ b/test/cases/compile_errors/invalid_error_capture_discard.zig @@ -1,28 +1,21 @@ export fn a() void { - errdefer |_| { - @"_"; - } -} -export fn b() void { const x: error{}!void = {}; x catch |_| { @"_"; }; } -export fn c() void { +export fn b() void { const x: error{}!void = {}; x catch |_| switch (_) {}; } -export fn d() void { +export fn c() void { const x: error{}!u32 = 0; if (x) |v| v else |_| switch (_) {} } // error // -// :2:15: error: discard of error capture; omit it instead -// :3:9: error: use of undeclared identifier '_' -// :8:14: error: discard of error capture; omit it instead -// :9:9: error: use of undeclared identifier '_' -// :14:14: error: discard of error capture; omit it instead -// :18:24: error: discard of error capture; omit it instead +// :3:14: error: discard of error capture; omit it instead +// :4:9: error: use of undeclared identifier '_' +// :9:14: error: discard of error capture; omit it instead +// :13:24: error: discard of error capture; omit it instead diff --git a/test/cases/compile_errors/unused_variable_error_on_errdefer.zig b/test/cases/compile_errors/unused_variable_error_on_errdefer.zig deleted file mode 100644 index afa55830a6..0000000000 --- a/test/cases/compile_errors/unused_variable_error_on_errdefer.zig +++ /dev/null @@ -1,11 +0,0 @@ -fn foo() !void { - errdefer |a| unreachable; - return error.A; -} -export fn entry() void { - foo() catch unreachable; -} - -// error -// -// :2:15: error: unused capture diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig index 5eb2386181..762458eee6 100644 --- a/tools/update_cpu_features.zig +++ b/tools/update_cpu_features.zig @@ -2010,7 +2010,9 @@ const Job = struct { }; fn processOneTarget(io: Io, job: Job) void { - errdefer |err| std.debug.panic("panic: {s}", .{@errorName(err)}); + processOneTargetInner(io, job) catch |err| std.debug.panic("panic: {s}", .{@errorName(err)}); +} +fn processOneTargetInner(io: Io, job: Job) !void { const target = job.target; var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);