authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-04-28 13:06:32+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-04-29 23:27:58+01:00
loge67c344fc0ec62748cbfb645e14b9f99ad3655cd
tree40e26446bfd6a2fa4d2b8e8d2730347472378fc0
parent7b44e8986fa0a8121993ab328b129789127a13bd
signaturelock-open Commit is signed but in an unrecognized format.

compiler,tests,tools: remove uses of capturing errdefer

In preparation for its removal, as accepted in https://github.com/ziglang/zig/issues/23734.

5 files changed, 15 insertions(+), 113 deletions(-)

src/codegen/aarch64/Select.zig+5-3
...@@ -11222,14 +11222,16 @@ fn initValueAdvanced(...@@ -11222,14 +11222,16 @@ fn initValueAdvanced(
11222 };11222 };
11223 return @enumFromInt(isel.values.items.len);11223 return @enumFromInt(isel.values.items.len);
11224}11224}
11225pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {11225const WhichValues = enum { only_referenced, all };
11226pub fn dumpValues(isel: *Select, which: WhichValues) void {
11227 dumpValuesInner(isel, which) catch |err| @panic(@errorName(err));
11228}
11229fn dumpValuesInner(isel: *Select, which: WhichValues) !void {
11226 const zcu = isel.pt.zcu;11230 const zcu = isel.pt.zcu;
11227 const gpa = zcu.gpa;11231 const gpa = zcu.gpa;
11228 const ip = &zcu.intern_pool;11232 const ip = &zcu.intern_pool;
11229 const nav = ip.getNav(isel.nav_index);11233 const nav = ip.getNav(isel.nav_index);
1123011234
11231 errdefer |err| @panic(@errorName(err));
11232
11233 const locked_stderr = std.debug.lockStderr(&.{});11235 const locked_stderr = std.debug.lockStderr(&.{});
11234 defer std.debug.unlockStderr();11236 defer std.debug.unlockStderr();
11235 const stderr = &locked_stderr.file_writer.interface;11237 const stderr = &locked_stderr.file_writer.interface;
test/behavior/defer.zig+1-85
...@@ -106,51 +106,6 @@ test "mixing normal and error defers" {...@@ -106,51 +106,6 @@ test "mixing normal and error defers" {
106 try expect(result[2] == 'a');106 try expect(result[2] == 'a');
107}107}
108108
109test "errdefer with payload" {
110 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
113 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
114
115 const S = struct {
116 fn foo() !i32 {
117 errdefer |a| {
118 expectEqual(error.One, a) catch @panic("test failure");
119 }
120 return error.One;
121 }
122 fn doTheTest() !void {
123 try expectError(error.One, foo());
124 }
125 };
126 try S.doTheTest();
127 try comptime S.doTheTest();
128}
129
130test "reference to errdefer payload" {
131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
132 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
133 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
134 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
135
136 const S = struct {
137 fn foo() !i32 {
138 errdefer |a| {
139 const ptr = &a;
140 const ptr2 = &ptr;
141 expectEqual(error.One, ptr2.*.*) catch @panic("test failure");
142 expectEqual(error.One, ptr.*) catch @panic("test failure");
143 }
144 return error.One;
145 }
146 fn doTheTest() !void {
147 try expectError(error.One, foo());
148 }
149 };
150 try S.doTheTest();
151 try comptime S.doTheTest();
152}
153
154test "simple else prong doesn't emit an error for unreachable else prong" {109test "simple else prong doesn't emit an error for unreachable else prong" {
155 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO110 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
156 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;111 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -192,47 +147,8 @@ comptime {...@@ -192,47 +147,8 @@ comptime {
192 if (defer_assign != 0) @compileError("defer_assign failed!");147 if (defer_assign != 0) @compileError("defer_assign failed!");
193}148}
194149
195test "errdefer capture" {
196 const S = struct {
197 fail: bool = undefined,
198 fn bar0(self: *@This()) error{a}!void {
199 self.fail = false;
200 errdefer |err| if (@TypeOf(err) != error{a}) {
201 self.fail = true;
202 };
203 return error.a;
204 }
205 fn bar1(self: *@This()) error{a}!void {
206 self.fail = false;
207 errdefer |err| if (@TypeOf(err) != error{a}) {
208 self.fail = true;
209 };
210 const rv: error{a}!void = @errorCast(@as(error{a}!void, error.a));
211 return rv;
212 }
213 // https://github.com/ziglang/zig/issues/20371
214 fn bar2(self: *@This()) error{a}!void {
215 self.fail = false;
216 errdefer |err| if (@TypeOf(err) != error{a}) {
217 self.fail = true;
218 };
219 return @errorCast(@as(error{a}!void, error.a));
220 }
221 };
222
223 var s: S = .{};
224 s.bar0() catch {};
225 if (s.fail) return error.TestExpectedError;
226 s.bar1() catch {};
227 if (s.fail) return error.TestExpectedError;
228 s.bar2() catch {};
229 if (s.fail) return error.TestExpectedError;
230}
231
232test "errdefer in test block" {150test "errdefer in test block" {
233 errdefer |err| {151 errdefer {}
234 _ = &err;
235 }
236 var x: bool = false;152 var x: bool = false;
237 _ = &x;153 _ = &x;
238 if (x) return error.Something;154 if (x) return error.Something;
test/cases/compile_errors/invalid_error_capture_discard.zig+6-13
...@@ -1,28 +1,21 @@...@@ -1,28 +1,21 @@
1export fn a() void {1export fn a() void {
2 errdefer |_| {
3 @"_";
4 }
5}
6export fn b() void {
7 const x: error{}!void = {};2 const x: error{}!void = {};
8 x catch |_| {3 x catch |_| {
9 @"_";4 @"_";
10 };5 };
11}6}
12export fn c() void {7export fn b() void {
13 const x: error{}!void = {};8 const x: error{}!void = {};
14 x catch |_| switch (_) {};9 x catch |_| switch (_) {};
15}10}
16export fn d() void {11export fn c() void {
17 const x: error{}!u32 = 0;12 const x: error{}!u32 = 0;
18 if (x) |v| v else |_| switch (_) {}13 if (x) |v| v else |_| switch (_) {}
19}14}
2015
21// error16// error
22//17//
23// :2:15: error: discard of error capture; omit it instead18// :3:14: error: discard of error capture; omit it instead
24// :3:9: error: use of undeclared identifier '_'19// :4:9: error: use of undeclared identifier '_'
25// :8:14: error: discard of error capture; omit it instead20// :9:14: error: discard of error capture; omit it instead
26// :9:9: error: use of undeclared identifier '_'21// :13:24: error: discard of error capture; omit it instead
27// :14:14: error: discard of error capture; omit it instead
28// :18:24: error: discard of error capture; omit it instead
test/cases/compile_errors/unused_variable_error_on_errdefer.zig deleted-11
...@@ -1,11 +0,0 @@
1fn foo() !void {
2 errdefer |a| unreachable;
3 return error.A;
4}
5export fn entry() void {
6 foo() catch unreachable;
7}
8
9// error
10//
11// :2:15: error: unused capture
tools/update_cpu_features.zig+3-1
...@@ -2010,7 +2010,9 @@ const Job = struct {...@@ -2010,7 +2010,9 @@ const Job = struct {
2010};2010};
20112011
2012fn processOneTarget(io: Io, job: Job) void {2012fn processOneTarget(io: Io, job: Job) void {
2013 errdefer |err| std.debug.panic("panic: {s}", .{@errorName(err)});2013 processOneTargetInner(io, job) catch |err| std.debug.panic("panic: {s}", .{@errorName(err)});
2014}
2015fn processOneTargetInner(io: Io, job: Job) !void {
2014 const target = job.target;2016 const target = job.target;
20152017
2016 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);2018 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);