diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-02 20:15:03 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-02 20:15:03 -0700 |
| commit | c4df9bf56f204f63f4e87255933ba453d69d0182 (patch) | |
| tree | 647cec61769d5723385f8ac9b1392b3c935a219b /test/behavior/switch.zig | |
| parent | 61a53a587558ff1fe1b0ec98bb424022885edccf (diff) | |
| download | zig-c4df9bf56f204f63f4e87255933ba453d69d0182.tar.gz zig-c4df9bf56f204f63f4e87255933ba453d69d0182.zip | |
AstGen: fix `while` and `for` with unreachable bodies
Companion commit to 61a53a587558ff1fe1b0ec98bb424022885edccf.
This commit also moves over a bunch of behavior test cases to the
passing-for-stage2 section.
Diffstat (limited to 'test/behavior/switch.zig')
| -rw-r--r-- | test/behavior/switch.zig | 545 |
1 files changed, 0 insertions, 545 deletions
diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 62afc74d83..9524e69540 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -2,548 +2,3 @@ const std = @import("std"); const expect = std.testing.expect; const expectError = std.testing.expectError; const expectEqual = std.testing.expectEqual; - -test "switch with numbers" { - try testSwitchWithNumbers(13); -} - -fn testSwitchWithNumbers(x: u32) !void { - const result = switch (x) { - 1, 2, 3, 4...8 => false, - 13 => true, - else => false, - }; - try expect(result); -} - -test "switch with all ranges" { - try expect(testSwitchWithAllRanges(50, 3) == 1); - try expect(testSwitchWithAllRanges(101, 0) == 2); - try expect(testSwitchWithAllRanges(300, 5) == 3); - try expect(testSwitchWithAllRanges(301, 6) == 6); -} - -fn testSwitchWithAllRanges(x: u32, y: u32) u32 { - return switch (x) { - 0...100 => 1, - 101...200 => 2, - 201...300 => 3, - else => y, - }; -} - -test "implicit comptime switch" { - const x = 3 + 4; - const result = switch (x) { - 3 => 10, - 4 => 11, - 5, 6 => 12, - 7, 8 => 13, - else => 14, - }; - - comptime { - try expect(result + 1 == 14); - } -} - -test "switch on enum" { - const fruit = Fruit.Orange; - nonConstSwitchOnEnum(fruit); -} -const Fruit = enum { - Apple, - Orange, - Banana, -}; -fn nonConstSwitchOnEnum(fruit: Fruit) void { - switch (fruit) { - Fruit.Apple => unreachable, - Fruit.Orange => {}, - Fruit.Banana => unreachable, - } -} - -test "switch statement" { - try nonConstSwitch(SwitchStatementFoo.C); -} -fn nonConstSwitch(foo: SwitchStatementFoo) !void { - const val = switch (foo) { - SwitchStatementFoo.A => @as(i32, 1), - SwitchStatementFoo.B => 2, - SwitchStatementFoo.C => 3, - SwitchStatementFoo.D => 4, - }; - try expect(val == 3); -} -const SwitchStatementFoo = enum { - A, - B, - C, - D, -}; - -test "switch prong with variable" { - try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 }); - try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 }); - try switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} }); -} -const SwitchProngWithVarEnum = union(enum) { - One: i32, - Two: f32, - Meh: void, -}; -fn switchProngWithVarFn(a: SwitchProngWithVarEnum) !void { - switch (a) { - SwitchProngWithVarEnum.One => |x| { - try expect(x == 13); - }, - SwitchProngWithVarEnum.Two => |x| { - try expect(x == 13.0); - }, - SwitchProngWithVarEnum.Meh => |x| { - const v: void = x; - _ = v; - }, - } -} - -test "switch on enum using pointer capture" { - try testSwitchEnumPtrCapture(); - comptime try testSwitchEnumPtrCapture(); -} - -fn testSwitchEnumPtrCapture() !void { - var value = SwitchProngWithVarEnum{ .One = 1234 }; - switch (value) { - SwitchProngWithVarEnum.One => |*x| x.* += 1, - else => unreachable, - } - switch (value) { - SwitchProngWithVarEnum.One => |x| try expect(x == 1235), - else => unreachable, - } -} - -test "switch with multiple expressions" { - const x = switch (returnsFive()) { - 1, 2, 3 => 1, - 4, 5, 6 => 2, - else => @as(i32, 3), - }; - try expect(x == 2); -} -fn returnsFive() i32 { - return 5; -} - -const Number = union(enum) { - One: u64, - Two: u8, - Three: f32, -}; - -const number = Number{ .Three = 1.23 }; - -fn returnsFalse() bool { - switch (number) { - Number.One => |x| return x > 1234, - Number.Two => |x| return x == 'a', - Number.Three => |x| return x > 12.34, - } -} -test "switch on const enum with var" { - try expect(!returnsFalse()); -} - -test "switch on type" { - try expect(trueIfBoolFalseOtherwise(bool)); - try expect(!trueIfBoolFalseOtherwise(i32)); -} - -fn trueIfBoolFalseOtherwise(comptime T: type) bool { - return switch (T) { - bool => true, - else => false, - }; -} - -test "switch handles all cases of number" { - try testSwitchHandleAllCases(); - comptime try testSwitchHandleAllCases(); -} - -fn testSwitchHandleAllCases() !void { - try expect(testSwitchHandleAllCasesExhaustive(0) == 3); - try expect(testSwitchHandleAllCasesExhaustive(1) == 2); - try expect(testSwitchHandleAllCasesExhaustive(2) == 1); - try expect(testSwitchHandleAllCasesExhaustive(3) == 0); - - try expect(testSwitchHandleAllCasesRange(100) == 0); - try expect(testSwitchHandleAllCasesRange(200) == 1); - try expect(testSwitchHandleAllCasesRange(201) == 2); - try expect(testSwitchHandleAllCasesRange(202) == 4); - try expect(testSwitchHandleAllCasesRange(230) == 3); -} - -fn testSwitchHandleAllCasesExhaustive(x: u2) u2 { - return switch (x) { - 0 => @as(u2, 3), - 1 => 2, - 2 => 1, - 3 => 0, - }; -} - -fn testSwitchHandleAllCasesRange(x: u8) u8 { - return switch (x) { - 0...100 => @as(u8, 0), - 101...200 => 1, - 201, 203 => 2, - 202 => 4, - 204...255 => 3, - }; -} - -test "switch all prongs unreachable" { - try testAllProngsUnreachable(); - comptime try testAllProngsUnreachable(); -} - -fn testAllProngsUnreachable() !void { - try expect(switchWithUnreachable(1) == 2); - try expect(switchWithUnreachable(2) == 10); -} - -fn switchWithUnreachable(x: i32) i32 { - while (true) { - switch (x) { - 1 => return 2, - 2 => break, - else => continue, - } - } - return 10; -} - -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 "switching on booleans" { - try testSwitchOnBools(); - comptime try testSwitchOnBools(); -} - -fn testSwitchOnBools() !void { - try expect(testSwitchOnBoolsTrueAndFalse(true) == false); - try expect(testSwitchOnBoolsTrueAndFalse(false) == true); - - try expect(testSwitchOnBoolsTrueWithElse(true) == false); - try expect(testSwitchOnBoolsTrueWithElse(false) == true); - - try expect(testSwitchOnBoolsFalseWithElse(true) == false); - try expect(testSwitchOnBoolsFalseWithElse(false) == true); -} - -fn testSwitchOnBoolsTrueAndFalse(x: bool) bool { - return switch (x) { - true => false, - false => true, - }; -} - -fn testSwitchOnBoolsTrueWithElse(x: bool) bool { - return switch (x) { - true => false, - else => true, - }; -} - -fn testSwitchOnBoolsFalseWithElse(x: bool) bool { - return switch (x) { - false => true, - else => false, - }; -} - -test "u0" { - var val: u0 = 0; - switch (val) { - 0 => try expect(val == 0), - } -} - -test "undefined.u0" { - var val: u0 = undefined; - switch (val) { - 0 => try expect(val == 0), - } -} - -test "anon enum literal used in switch on union enum" { - const Foo = union(enum) { - a: i32, - }; - - var foo = Foo{ .a = 1234 }; - switch (foo) { - .a => |x| { - try expect(x == 1234); - }, - } -} - -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 with disjoint range" { - var q: u8 = 0; - switch (q) { - 0...125 => {}, - 127...255 => {}, - 126...126 => {}, - } -} - -test "switch variable for range and multiple prongs" { - const S = struct { - fn doTheTest() !void { - var u: u8 = 16; - try doTheSwitch(u); - comptime try doTheSwitch(u); - var v: u8 = 42; - try doTheSwitch(v); - comptime try doTheSwitch(v); - } - fn doTheSwitch(q: u8) !void { - switch (q) { - 0...40 => |x| try expect(x == 16), - 41, 42, 43 => |x| try expect(x == 42), - else => try expect(false), - } - } - }; - _ = S; -} - -var state: u32 = 0; -fn poll() void { - switch (state) { - 0 => { - state = 1; - }, - else => { - state += 1; - }, - } -} - -test "switch on global mutable var isn't constant-folded" { - while (state < 2) { - poll(); - } -} - -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 "while 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(); -} |
