aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-06-13 08:45:12 -0700
committerGitHub <noreply@github.com>2023-06-13 08:45:12 -0700
commitdf6319418a08b611bae23307ace6688f95bedea2 (patch)
tree6cdf873c6800aebccdd8c03a443f9594acb84729 /test
parent387f9568ad0dabd426d382efb45b9c52a4ccc5bb (diff)
parent42dc7539c5b0a39e9b64c5ad92757945b0ca05ad (diff)
downloadzig-df6319418a08b611bae23307ace6688f95bedea2.tar.gz
zig-df6319418a08b611bae23307ace6688f95bedea2.zip
Merge pull request #15880 from mlugg/feat/better-switch-zir-2
Simplify and compact switch ZIR, and resolve union payload captures with PTR
Diffstat (limited to 'test')
-rw-r--r--test/behavior/switch.zig68
-rw-r--r--test/cases/compile_errors/capture_group_on_switch_prong_with_incompatible_payload_types.zig21
-rw-r--r--test/cases/compile_errors/switch_capture_incompatible_types.zig27
-rw-r--r--test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig4
4 files changed, 97 insertions, 23 deletions
diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig
index 3f6cd37298..72a36c9883 100644
--- a/test/behavior/switch.zig
+++ b/test/behavior/switch.zig
@@ -1,5 +1,6 @@
const builtin = @import("builtin");
const std = @import("std");
+const assert = std.debug.assert;
const expect = std.testing.expect;
const expectError = std.testing.expectError;
const expectEqual = std.testing.expectEqual;
@@ -717,3 +718,70 @@ test "comptime inline switch" {
try expectEqual(u32, value);
}
+
+test "switch capture peer type resolution" {
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+
+ const U = union(enum) {
+ a: u32,
+ b: u64,
+ fn innerVal(u: @This()) u64 {
+ switch (u) {
+ .a, .b => |x| return x,
+ }
+ }
+ };
+
+ try expectEqual(@as(u64, 100), U.innerVal(.{ .a = 100 }));
+ try expectEqual(@as(u64, 200), U.innerVal(.{ .b = 200 }));
+}
+
+test "switch capture peer type resolution for in-memory coercible payloads" {
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+
+ const T1 = c_int;
+ const T2 = @Type(@typeInfo(T1));
+
+ comptime assert(T1 != T2);
+
+ const U = union(enum) {
+ a: T1,
+ b: T2,
+ fn innerVal(u: @This()) c_int {
+ switch (u) {
+ .a, .b => |x| return x,
+ }
+ }
+ };
+
+ try expectEqual(@as(c_int, 100), U.innerVal(.{ .a = 100 }));
+ try expectEqual(@as(c_int, 200), U.innerVal(.{ .b = 200 }));
+}
+
+test "switch pointer capture peer type resolution" {
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+
+ const T1 = c_int;
+ const T2 = @Type(@typeInfo(T1));
+
+ comptime assert(T1 != T2);
+
+ const U = union(enum) {
+ a: T1,
+ b: T2,
+ fn innerVal(u: *@This()) *c_int {
+ switch (u.*) {
+ .a, .b => |*ptr| return ptr,
+ }
+ }
+ };
+
+ var ua: U = .{ .a = 100 };
+ var ub: U = .{ .b = 200 };
+
+ ua.innerVal().* = 111;
+ ub.innerVal().* = 222;
+
+ try expectEqual(U{ .a = 111 }, ua);
+ try expectEqual(U{ .b = 222 }, ub);
+}
diff --git a/test/cases/compile_errors/capture_group_on_switch_prong_with_incompatible_payload_types.zig b/test/cases/compile_errors/capture_group_on_switch_prong_with_incompatible_payload_types.zig
deleted file mode 100644
index cff9a58bc6..0000000000
--- a/test/cases/compile_errors/capture_group_on_switch_prong_with_incompatible_payload_types.zig
+++ /dev/null
@@ -1,21 +0,0 @@
-const Union = union(enum) {
- A: usize,
- B: isize,
-};
-comptime {
- var u = Union{ .A = 8 };
- switch (u) {
- .A, .B => |e| {
- _ = e;
- unreachable;
- },
- }
-}
-
-// error
-// backend=stage2
-// target=native
-//
-// :8:20: error: capture group with incompatible types
-// :8:10: note: type 'usize' here
-// :8:14: note: type 'isize' here
diff --git a/test/cases/compile_errors/switch_capture_incompatible_types.zig b/test/cases/compile_errors/switch_capture_incompatible_types.zig
new file mode 100644
index 0000000000..b6de7d5bf5
--- /dev/null
+++ b/test/cases/compile_errors/switch_capture_incompatible_types.zig
@@ -0,0 +1,27 @@
+export fn f() void {
+ const U = union(enum) { a: u32, b: *u8 };
+ var u: U = undefined;
+ switch (u) {
+ .a, .b => |val| _ = val,
+ }
+}
+
+export fn g() void {
+ const U = union(enum) { a: u64, b: u32 };
+ var u: U = undefined;
+ switch (u) {
+ .a, .b => |*ptr| _ = ptr,
+ }
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :5:20: error: capture group with incompatible types
+// :5:20: note: incompatible types: 'u32' and '*u8'
+// :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: this coercion is only possible when capturing by value
diff --git a/test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig b/test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig
index 4d8742d32e..d9bc2abb91 100644
--- a/test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig
+++ b/test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig
@@ -4,12 +4,12 @@ const Payload = union {
C: bool,
};
export fn entry() void {
- const a = Payload { .A = 1234 };
+ const a = Payload{ .A = 1234 };
foo(&a);
}
fn foo(a: *const Payload) void {
switch (a.*) {
- Payload.A => {},
+ .A => {},
else => unreachable,
}
}