Skip to content

Commit 1550b5b

Browse files
authored
astgen: fix result info for catch switch_block_err_union
1 parent cc39ce2 commit 1550b5b

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

lib/std/zig/AstGen.zig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ const assert = std.debug.assert;
33
const expect = std.testing.expect;
44
const expectError = std.testing.expectError;
55
const expectEqual = std.testing.expectEqual;
6+
const builtin = @import("builtin");
67

78
test "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

261302
test "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();

0 commit comments

Comments
 (0)