authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2024-05-11 19:06:13+10:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-22 07:04:01-07:00
log869880adac4f708b0fd1e65de6046b561c38528c
tree23c7d47536e52c6ed2e6c40fa70ae7ea24685031
parent511aa28983a4aae2cfae5f1bb5a2d66181f55373

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(...@@ -7071,8 +7071,10 @@ fn switchExprErrUnion(
7071 .ctx = ri.ctx,7071 .ctx = ri.ctx,
7072 };7072 };
70737073
7074 const payload_is_ref = node_ty == .@"if" and7074 const payload_is_ref = switch (node_ty) {
7075 if_full.payload_token != null and token_tags[if_full.payload_token.?] == .asterisk;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
7077 // We need to call `rvalue` to write through to the pointer only if we had a7079 // We need to call `rvalue` to write through to the pointer only if we had a
7078 // result pointer and aren't forwarding it.7080 // result pointer and aren't forwarding it.
test/behavior.zig+1
...@@ -89,6 +89,7 @@ test {...@@ -89,6 +89,7 @@ test {
89 _ = @import("behavior/switch.zig");89 _ = @import("behavior/switch.zig");
90 _ = @import("behavior/switch_prong_err_enum.zig");90 _ = @import("behavior/switch_prong_err_enum.zig");
91 _ = @import("behavior/switch_prong_implicit_cast.zig");91 _ = @import("behavior/switch_prong_implicit_cast.zig");
92 _ = @import("behavior/switch_on_captured_error.zig");
92 _ = @import("behavior/this.zig");93 _ = @import("behavior/this.zig");
93 _ = @import("behavior/threadlocal.zig");94 _ = @import("behavior/threadlocal.zig");
94 _ = @import("behavior/truncate.zig");95 _ = @import("behavior/truncate.zig");
test/behavior/switch_on_captured_error.zig+82
...@@ -3,9 +3,11 @@ const assert = std.debug.assert;...@@ -3,9 +3,11 @@ const assert = std.debug.assert;
3const expect = std.testing.expect;3const expect = std.testing.expect;
4const expectError = std.testing.expectError;4const expectError = std.testing.expectError;
5const expectEqual = std.testing.expectEqual;5const expectEqual = std.testing.expectEqual;
6const builtin = @import("builtin");
67
7test "switch on error union catch capture" {8test "switch on error union catch capture" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
911
10 const S = struct {12 const S = struct {
11 const Error = error{ A, B, C };13 const Error = error{ A, B, C };
...@@ -16,6 +18,7 @@ test "switch on error union catch capture" {...@@ -16,6 +18,7 @@ test "switch on error union catch capture" {
16 try testCapture();18 try testCapture();
17 try testInline();19 try testInline();
18 try testEmptyErrSet();20 try testEmptyErrSet();
21 try testAddressOf();
19 }22 }
2023
21 fn testScalar() !void {24 fn testScalar() !void {
...@@ -252,6 +255,44 @@ test "switch on error union catch capture" {...@@ -252,6 +255,44 @@ test "switch on error union catch capture" {
252 try expectEqual(@as(u64, 0), b);255 try expectEqual(@as(u64, 0), b);
253 }256 }
254 }257 }
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 }
255 };296 };
256297
257 try comptime S.doTheTest();298 try comptime S.doTheTest();
...@@ -260,6 +301,7 @@ test "switch on error union catch capture" {...@@ -260,6 +301,7 @@ test "switch on error union catch capture" {
260301
261test "switch on error union if else capture" {302test "switch on error union if else capture" {
262 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;303 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
304 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
263305
264 const S = struct {306 const S = struct {
265 const Error = error{ A, B, C };307 const Error = error{ A, B, C };
...@@ -276,6 +318,7 @@ test "switch on error union if else capture" {...@@ -276,6 +318,7 @@ test "switch on error union if else capture" {
276 try testInlinePtr();318 try testInlinePtr();
277 try testEmptyErrSet();319 try testEmptyErrSet();
278 try testEmptyErrSetPtr();320 try testEmptyErrSetPtr();
321 try testAddressOf();
279 }322 }
280323
281 fn testScalar() !void {324 fn testScalar() !void {
...@@ -747,6 +790,45 @@ test "switch on error union if else capture" {...@@ -747,6 +790,45 @@ test "switch on error union if else capture" {
747 try expectEqual(@as(u64, 0), b);790 try expectEqual(@as(u64, 0), b);
748 }791 }
749 }792 }
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 }
750 };832 };
751833
752 try comptime S.doTheTest();834 try comptime S.doTheTest();