| 1 | const std = @import("std"); |
| 2 | const math = std.math; |
| 3 | const maxInt = math.maxInt; |
| 4 | const minInt = math.minInt; |
| 5 | const builtin = @import("builtin"); |
| 6 | const assert = std.debug.assert; |
| 7 | const expect = std.testing.expect; |
| 8 | |
| 9 | test "truncate u0 to larger integer allowed and has comptime-known result" { |
| 10 | var x: u0 = 0; |
| 11 | _ = &x; |
| 12 | const y = @as(u8, @truncate(x)); |
| 13 | comptime assert(y == 0); |
| 14 | } |
| 15 | |
| 16 | test "truncate.u0.literal" { |
| 17 | const z: u0 = @truncate(0); |
| 18 | try expect(z == 0); |
| 19 | } |
| 20 | |
| 21 | test "truncate.u0.const" { |
| 22 | const c0: usize = 0; |
| 23 | const z: u0 = @truncate(c0); |
| 24 | try expect(z == 0); |
| 25 | } |
| 26 | |
| 27 | test "truncate.u0.var" { |
| 28 | var d: u8 = 2; |
| 29 | _ = &d; |
| 30 | const z: u0 = @truncate(d); |
| 31 | try expect(z == 0); |
| 32 | } |
| 33 | |
| 34 | test "truncate on comptime integer" { |
| 35 | const x: u16 = @truncate(9999); |
| 36 | try expect(x == 9999); |
| 37 | const y: u16 = @truncate(-21555); |
| 38 | try expect(y == 0xabcd); |
| 39 | const z: i16 = @truncate(-65537); |
| 40 | try expect(z == -1); |
| 41 | const w: u1 = @truncate(1 << 100); |
| 42 | try expect(w == 0); |
| 43 | } |
| 44 | |
| 45 | fn testTruncate(comptime S: type, a: S, comptime D: type, expected: D) !void { |
| 46 | const actual: D = @truncate(a); |
| 47 | try expect(actual == expected); |
| 48 | } |
| 49 | |
| 50 | test "@truncate > 128 bits" { |
| 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 52 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 53 | |
| 54 | try testTruncate(u140, 0, u128, 0); |
| 55 | try testTruncate(u140, maxInt(u140), u128, maxInt(u128)); |
| 56 | try testTruncate(u140, 1 << 139, u128, 0); |
| 57 | try testTruncate(u140, (1 << 139) | (1 << 64) | 0x55, u128, (1 << 64) | 0x55); |
| 58 | try testTruncate(u140, (1 << 100) | (1 << 63), u128, (1 << 100) | (1 << 63)); |
| 59 | try testTruncate(u140, (1 << 130) | 0xabcd, u16, 0xabcd); |
| 60 | |
| 61 | try testTruncate(u256, 1 << 200, u128, 0); |
| 62 | try testTruncate(u256, (1 << 200) | (1 << 127) | 1, u128, (1 << 127) | 1); |
| 63 | try testTruncate(u256, maxInt(u256), u128, maxInt(u128)); |
| 64 | try testTruncate(u256, (1 << 255) | (1 << 128) | 0x1234_5678_9abc_def0, u64, 0x1234_5678_9abc_def0); |
| 65 | try testTruncate(u256, (1 << 250) | (1 << 32), u32, 0); |
| 66 | try testTruncate(u256, (1 << 129) | (1 << 63), u64, 1 << 63); |
| 67 | |
| 68 | try testTruncate(i140, 0, i128, 0); |
| 69 | try testTruncate(i140, -1, i128, -1); |
| 70 | try testTruncate(i140, -2, i8, -2); |
| 71 | try testTruncate(i140, -1 << 80, i64, 0); |
| 72 | try testTruncate(i140, (-1 << 80) | 0x1234, i16, 0x1234); |
| 73 | try testTruncate(i140, minInt(i140), i128, 0); |
| 74 | try testTruncate(i140, maxInt(i140), i128, -1); |
| 75 | try testTruncate(i140, (1 << 127) - 1, i128, maxInt(i128)); |
| 76 | |
| 77 | try testTruncate(i256, -1, i128, -1); |
| 78 | try testTruncate(i256, minInt(i256), i128, 0); |
| 79 | try testTruncate(i256, (-1 << 128) | maxInt(i128), i128, maxInt(i128)); |
| 80 | try testTruncate(i256, (-1 << 200) | (1 << 127), i128, minInt(i128)); |
| 81 | try testTruncate(i256, -255, i8, 1); |
| 82 | try testTruncate(i256, (-1 << 64) | 0x1234_5678, i32, 0x1234_5678); |
| 83 | |
| 84 | try testTruncate(i257, maxInt(i257), i256, -1); |
| 85 | try testTruncate(u257, maxInt(u257), u256, maxInt(u256)); |
| 86 | } |
| 87 | |
| 88 | test "truncate on vectors" { |
| 89 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 90 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 91 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 92 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 93 | if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; |
| 94 | |
| 95 | const S = struct { |
| 96 | fn doTheTest() !void { |
| 97 | var v1: @Vector(4, u16) = .{ 0xaabb, 0xccdd, 0xeeff, 0x1122 }; |
| 98 | _ = &v1; |
| 99 | const v2: @Vector(4, u8) = @truncate(v1); |
| 100 | try expect(std.mem.eql(u8, &@as([4]u8, v2), &[4]u8{ 0xbb, 0xdd, 0xff, 0x22 })); |
| 101 | } |
| 102 | }; |
| 103 | try comptime S.doTheTest(); |
| 104 | try S.doTheTest(); |
| 105 | } |