diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-02-26 16:52:39 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-26 16:52:39 -0800 |
| commit | 3e79c0f18ce05c302c6117e66275db4fcdf033e4 (patch) | |
| tree | 4ae226095dcc3b225301039da7e94be9922e518b /test | |
| parent | 00ff123b1eb237f72f918ffd413c8d9c8936c46d (diff) | |
| parent | 7cb227ab678b57dd10b65c1d9c89526a3e47cc2a (diff) | |
| download | zig-3e79c0f18ce05c302c6117e66275db4fcdf033e4.tar.gz zig-3e79c0f18ce05c302c6117e66275db4fcdf033e4.zip | |
Merge pull request #18859 from schmee/switch-union-capture-align
Sema: preserve field alignment in union pointer captures
Diffstat (limited to 'test')
| -rw-r--r-- | test/behavior/switch.zig | 77 | ||||
| -rw-r--r-- | test/cases/compile_errors/switch_capture_incompatible_types.zig | 4 |
2 files changed, 73 insertions, 8 deletions
diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 458c3530b8..a0adbb818f 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -410,8 +410,8 @@ test "switch on integer with else capturing expr" { var x: i32 = 5; _ = &x; switch (x + 10) { - 14 => @panic("fail"), - 16 => @panic("fail"), + 14 => return error.TestFailed, + 16 => return error.TestFailed, else => |e| try expect(e == 15), } } @@ -522,7 +522,7 @@ test "switch with null and T peer types and inferred result location type" { else => null, }) |v| { _ = v; - @panic("fail"); + return error.TestFailed; } } }; @@ -548,12 +548,12 @@ test "switch prongs with cases with identical payload types" { fn doTheSwitch1(u: Union) !void { switch (u) { .A, .C => |e| { - try expect(@TypeOf(e) == usize); + comptime assert(@TypeOf(e) == usize); try expect(e == 8); }, .B => |e| { _ = e; - @panic("fail"); + return error.TestFailed; }, } } @@ -561,10 +561,10 @@ test "switch prongs with cases with identical payload types" { switch (u) { .A, .C => |e| { _ = e; - @panic("fail"); + return error.TestFailed; }, .B => |e| { - try expect(@TypeOf(e) == isize); + comptime assert(@TypeOf(e) == isize); try expect(e == -8); }, } @@ -574,6 +574,69 @@ test "switch prongs with cases with identical payload types" { try comptime S.doTheTest(); } +test "switch prong pointer capture alignment" { + const U = union(enum) { + a: u8 align(8), + b: u8 align(4), + c: u8, + }; + + const S = struct { + fn doTheTest() !void { + const u = U{ .a = 1 }; + switch (u) { + .a => |*a| comptime assert(@TypeOf(a) == *align(8) const u8), + .b, .c => |*p| { + _ = p; + return error.TestFailed; + }, + } + + switch (u) { + .a, .b => |*p| comptime assert(@TypeOf(p) == *align(4) const u8), + .c => |*p| { + _ = p; + return error.TestFailed; + }, + } + + switch (u) { + .a, .c => |*p| comptime assert(@TypeOf(p) == *const u8), + .b => |*p| { + _ = p; + return error.TestFailed; + }, + } + } + + fn doTheTest2() !void { + const un1 = U{ .b = 1 }; + switch (un1) { + .b => |*b| comptime assert(@TypeOf(b) == *align(4) const u8), + .a, .c => |*p| { + _ = p; + return error.TestFailed; + }, + } + + const un2 = U{ .c = 1 }; + switch (un2) { + .c => |*c| comptime assert(@TypeOf(c) == *const u8), + .a, .b => |*p| { + _ = p; + return error.TestFailed; + }, + } + } + }; + + try S.doTheTest(); + try comptime S.doTheTest(); + + try S.doTheTest2(); + try comptime S.doTheTest2(); +} + test "switch on pointer type" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO diff --git a/test/cases/compile_errors/switch_capture_incompatible_types.zig b/test/cases/compile_errors/switch_capture_incompatible_types.zig index 967307441b..5fbee3b347 100644 --- a/test/cases/compile_errors/switch_capture_incompatible_types.zig +++ b/test/cases/compile_errors/switch_capture_incompatible_types.zig @@ -23,5 +23,7 @@ export fn g() void { // :5:10: note: type 'u32' here // :5:14: note: type '*u8' here // :13:20: error: capture group with incompatible types -// :13:14: note: pointer type child 'u32' cannot cast into resolved pointer type child 'u64' +// :13:20: note: incompatible types: '*u64' and '*u32' +// :13:10: note: type '*u64' here +// :13:14: note: type '*u32' here // :13:20: note: this coercion is only possible when capturing by value |
