authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2024-05-11 19:06:13+10:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-05-11 12:06:13+03:00
log1550b5b16d4899cb4f7184ee3d392b4a6197ed42
treea637f70a70a4420bdfcb43f753c82913d0819b8a
parentcc39ce28a167bf72560f1b4e1265ddc9914f30a4
signaturebadge-check Signed by PGP key B5690EEEBB952194

astgen: fix result info for catch switch_block_err_union


3 files changed, 87 insertions(+), 2 deletions(-)

lib/std/zig/AstGen.zig+4-2
......@@ -7071,8 +7071,10 @@ fn switchExprErrUnion(
70717071 .ctx = ri.ctx,
70727072 };
70737073
7074 const payload_is_ref = node_ty == .@"if" and
7075 if_full.payload_token != null and token_tags[if_full.payload_token.?] == .asterisk;
7074 const payload_is_ref = switch (node_ty) {
7075 .@"if" => if_full.payload_token != null and token_tags[if_full.payload_token.?] == .asterisk,
7076 .@"catch" => ri.rl == .ref or ri.rl == .ref_coerced_ty,
7077 };
70767078
70777079 // We need to call `rvalue` to write through to the pointer only if we had a
70787080 // result pointer and aren't forwarding it.
test/behavior.zig+1
......@@ -89,6 +89,7 @@ test {
8989 _ = @import("behavior/switch.zig");
9090 _ = @import("behavior/switch_prong_err_enum.zig");
9191 _ = @import("behavior/switch_prong_implicit_cast.zig");
92 _ = @import("behavior/switch_on_captured_error.zig");
9293 _ = @import("behavior/this.zig");
9394 _ = @import("behavior/threadlocal.zig");
9495 _ = @import("behavior/truncate.zig");
test/behavior/switch_on_captured_error.zig+82
......@@ -3,9 +3,11 @@ const assert = std.debug.assert;
33const expect = std.testing.expect;
44const expectError = std.testing.expectError;
55const expectEqual = std.testing.expectEqual;
6const builtin = @import("builtin");
67
78test "switch on error union catch capture" {
89 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
911
1012 const S = struct {
1113 const Error = error{ A, B, C };
......@@ -16,6 +18,7 @@ test "switch on error union catch capture" {
1618 try testCapture();
1719 try testInline();
1820 try testEmptyErrSet();
21 try testAddressOf();
1922 }
2023
2124 fn testScalar() !void {
......@@ -252,6 +255,44 @@ test "switch on error union catch capture" {
252255 try expectEqual(@as(u64, 0), b);
253256 }
254257 }
258
259 fn testAddressOf() !void {
260 {
261 const a: anyerror!usize = 0;
262 const ptr = &(a catch |e| switch (e) {
263 else => 3,
264 });
265 comptime assert(@TypeOf(ptr) == *const usize);
266 try expectEqual(ptr, &(a catch unreachable));
267 }
268 {
269 const a: anyerror!usize = error.A;
270 const ptr = &(a catch |e| switch (e) {
271 else => 3,
272 });
273 comptime assert(@TypeOf(ptr) == *const comptime_int);
274 try expectEqual(3, ptr.*);
275 }
276 {
277 var a: anyerror!usize = 0;
278 _ = &a;
279 const ptr = &(a catch |e| switch (e) {
280 else => return,
281 });
282 comptime assert(@TypeOf(ptr) == *usize);
283 ptr.* += 1;
284 try expectEqual(@as(usize, 1), a catch unreachable);
285 }
286 {
287 var a: anyerror!usize = error.A;
288 _ = &a;
289 const ptr = &(a catch |e| switch (e) {
290 else => return,
291 });
292 comptime assert(@TypeOf(ptr) == *usize);
293 unreachable;
294 }
295 }
255296 };
256297
257298 try comptime S.doTheTest();
......@@ -260,6 +301,7 @@ test "switch on error union catch capture" {
260301
261302test "switch on error union if else capture" {
262303 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
304 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
263305
264306 const S = struct {
265307 const Error = error{ A, B, C };
......@@ -276,6 +318,7 @@ test "switch on error union if else capture" {
276318 try testInlinePtr();
277319 try testEmptyErrSet();
278320 try testEmptyErrSetPtr();
321 try testAddressOf();
279322 }
280323
281324 fn testScalar() !void {
......@@ -747,6 +790,45 @@ test "switch on error union if else capture" {
747790 try expectEqual(@as(u64, 0), b);
748791 }
749792 }
793
794 fn testAddressOf() !void {
795 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
796 {
797 const a: anyerror!usize = 0;
798 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
799 else => 3,
800 });
801 comptime assert(@TypeOf(ptr) == *const usize);
802 try expectEqual(ptr, &(a catch unreachable));
803 }
804 {
805 const a: anyerror!usize = error.A;
806 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
807 else => 3,
808 });
809 comptime assert(@TypeOf(ptr) == *const comptime_int);
810 try expectEqual(3, ptr.*);
811 }
812 {
813 var a: anyerror!usize = 0;
814 _ = &a;
815 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
816 else => return,
817 });
818 comptime assert(@TypeOf(ptr) == *usize);
819 ptr.* += 1;
820 try expectEqual(@as(usize, 1), a catch unreachable);
821 }
822 {
823 var a: anyerror!usize = error.A;
824 _ = &a;
825 const ptr = &(if (a) |*v| v.* else |e| switch (e) {
826 else => return,
827 });
828 comptime assert(@TypeOf(ptr) == *usize);
829 unreachable;
830 }
831 }
750832 };
751833
752834 try comptime S.doTheTest();