From 2600978a9ddc295c347fd6ffe7c6ba20931b956e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 17 Jan 2022 19:52:24 -0700 Subject: [PATCH] behavior tests: a couple more switch cases are passing --- test/behavior.zig | 1 - test/behavior/switch.zig | 222 ++++++++++++++++++++++++++++++++ test/behavior/switch_stage1.zig | 214 ------------------------------ 3 files changed, 222 insertions(+), 215 deletions(-) delete mode 100644 test/behavior/switch_stage1.zig diff --git a/test/behavior.zig b/test/behavior.zig index a89a36b879740f16f1c392f828a1261f52927011..811050445c2290dd618e1baf1be78f7f34d01f31 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -191,7 +191,6 @@ test { _ = @import("behavior/struct_stage1.zig"); _ = @import("behavior/switch_prong_err_enum.zig"); _ = @import("behavior/switch_prong_implicit_cast.zig"); - _ = @import("behavior/switch_stage1.zig"); _ = @import("behavior/truncate_stage1.zig"); _ = @import("behavior/tuple.zig"); _ = @import("behavior/type_stage1.zig"); diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index c435d70b9f176d133a7a14235b155aa0dacb7daa..0b438768698f29028deb881be76e64eddbbe8114 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(); +} diff --git a/test/behavior/switch_stage1.zig b/test/behavior/switch_stage1.zig deleted file mode 100644 index 3716eca1c44b8a3fd9e2fa8014777ab66d6b2e01..0000000000000000000000000000000000000000 --- a/test/behavior/switch_stage1.zig +++ /dev/null @@ -1,214 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; -const expectError = std.testing.expectError; -const expectEqual = std.testing.expectEqual; - -fn return_a_number() anyerror!i32 { - return 1; -} - -test "capture value of switch with all unreachable prongs" { - const x = return_a_number() catch |err| switch (err) { - else => unreachable, - }; - try expect(x == 1); -} - -test "else prong of switch on error set excludes other cases" { - 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" { - 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" { - 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" { - 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" { - 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" { - 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(); -} -- 2.54.0