aboutsummaryrefslogtreecommitdiff
path: root/test/behavior/switch.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-01-17 19:52:24 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-01-17 19:52:24 -0700
commit2600978a9ddc295c347fd6ffe7c6ba20931b956e (patch)
tree7fe1f3ae85145879b12fdc3b4a6c9bbf4e700fc5 /test/behavior/switch.zig
parente69cb9105a716dfd4a8cc2684417545b2438f606 (diff)
downloadzig-2600978a9ddc295c347fd6ffe7c6ba20931b956e.tar.gz
zig-2600978a9ddc295c347fd6ffe7c6ba20931b956e.zip
behavior tests: a couple more switch cases are passing
Diffstat (limited to 'test/behavior/switch.zig')
-rw-r--r--test/behavior/switch.zig222
1 files changed, 222 insertions, 0 deletions
diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig
index c435d70b9f..0b43876869 100644
--- a/test/behavior/switch.zig
+++ b/test/behavior/switch.zig
@@ -347,3 +347,225 @@ fn switchWithUnreachable(x: i32) i32 {
}
return 10;
}
+
+test "capture value of switch with all unreachable prongs" {
+ const x = return_a_number() catch |err| switch (err) {
+ else => unreachable,
+ };
+ try expect(x == 1);
+}
+
+fn return_a_number() anyerror!i32 {
+ return 1;
+}
+
+test "else prong of switch on error set excludes other cases" {
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try expectError(error.C, bar());
+ }
+ const E = error{
+ A,
+ B,
+ } || E2;
+
+ const E2 = error{
+ C,
+ D,
+ };
+
+ fn foo() E!void {
+ return error.C;
+ }
+
+ fn bar() E2!void {
+ foo() catch |err| switch (err) {
+ error.A, error.B => {},
+ else => |e| return e,
+ };
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "switch prongs with error set cases make a new error set type for capture value" {
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try expectError(error.B, bar());
+ }
+ const E = E1 || E2;
+
+ const E1 = error{
+ A,
+ B,
+ };
+
+ const E2 = error{
+ C,
+ D,
+ };
+
+ fn foo() E!void {
+ return error.B;
+ }
+
+ fn bar() E1!void {
+ foo() catch |err| switch (err) {
+ error.A, error.B => |e| return e,
+ else => {},
+ };
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "return result loc and then switch with range implicit casted to error union" {
+ const S = struct {
+ fn doTheTest() !void {
+ try expect((func(0xb) catch unreachable) == 0xb);
+ }
+ fn func(d: u8) anyerror!u8 {
+ return switch (d) {
+ 0xa...0xf => d,
+ else => unreachable,
+ };
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "switch with null and T peer types and inferred result location type" {
+ const S = struct {
+ fn doTheTest(c: u8) !void {
+ if (switch (c) {
+ 0 => true,
+ else => null,
+ }) |v| {
+ _ = v;
+ @panic("fail");
+ }
+ }
+ };
+ try S.doTheTest(1);
+ comptime try S.doTheTest(1);
+}
+
+test "switch prongs with cases with identical payload types" {
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+
+ const Union = union(enum) {
+ A: usize,
+ B: isize,
+ C: usize,
+ };
+ const S = struct {
+ fn doTheTest() !void {
+ try doTheSwitch1(Union{ .A = 8 });
+ try doTheSwitch2(Union{ .B = -8 });
+ }
+ fn doTheSwitch1(u: Union) !void {
+ switch (u) {
+ .A, .C => |e| {
+ try expect(@TypeOf(e) == usize);
+ try expect(e == 8);
+ },
+ .B => |e| {
+ _ = e;
+ @panic("fail");
+ },
+ }
+ }
+ fn doTheSwitch2(u: Union) !void {
+ switch (u) {
+ .A, .C => |e| {
+ _ = e;
+ @panic("fail");
+ },
+ .B => |e| {
+ try expect(@TypeOf(e) == isize);
+ try expect(e == -8);
+ },
+ }
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "switch on pointer type" {
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const X = struct {
+ field: u32,
+ };
+
+ const P1 = @intToPtr(*X, 0x400);
+ const P2 = @intToPtr(*X, 0x800);
+ const P3 = @intToPtr(*X, 0xC00);
+
+ fn doTheTest(arg: *X) i32 {
+ switch (arg) {
+ P1 => return 1,
+ P2 => return 2,
+ else => return 3,
+ }
+ }
+ };
+
+ try expect(1 == S.doTheTest(S.P1));
+ try expect(2 == S.doTheTest(S.P2));
+ try expect(3 == S.doTheTest(S.P3));
+ comptime try expect(1 == S.doTheTest(S.P1));
+ comptime try expect(2 == S.doTheTest(S.P2));
+ comptime try expect(3 == S.doTheTest(S.P3));
+}
+
+test "switch on error set with single else" {
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var some: error{Foo} = error.Foo;
+ try expect(switch (some) {
+ else => |a| blk: {
+ a catch {};
+ break :blk true;
+ },
+ });
+ }
+ };
+
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "switch capture copies its payload" {
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var tmp: union(enum) {
+ A: u8,
+ B: u32,
+ } = .{ .A = 42 };
+ switch (tmp) {
+ .A => |value| {
+ // Modify the original union
+ tmp = .{ .B = 0x10101010 };
+ try expectEqual(@as(u8, 42), value);
+ },
+ else => unreachable,
+ }
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}