diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-07-27 01:33:01 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-07-27 18:56:16 +0300 |
| commit | 9be35f82c1abf2ecbab489bca9eca138ea648312 (patch) | |
| tree | 69888506e34af447d9748c0d542de3ba1dd76210 /src/test/ui/numbers-arithmetic | |
| parent | ca9faa52f5ada0054b1fa27d97aedf448afb059b (diff) | |
| download | rust-9be35f82c1abf2ecbab489bca9eca138ea648312.tar.gz rust-9be35f82c1abf2ecbab489bca9eca138ea648312.zip | |
tests: Move run-pass tests without naming conflicts to ui
Diffstat (limited to 'src/test/ui/numbers-arithmetic')
39 files changed, 1693 insertions, 0 deletions
diff --git a/src/test/ui/numbers-arithmetic/arith-0.rs b/src/test/ui/numbers-arithmetic/arith-0.rs new file mode 100644 index 00000000000..7943cb908d1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-0.rs @@ -0,0 +1,8 @@ +// run-pass + + +pub fn main() { + let a: isize = 10; + println!("{}", a); + assert_eq!(a * (a - 1), 90); +} diff --git a/src/test/ui/numbers-arithmetic/arith-1.rs b/src/test/ui/numbers-arithmetic/arith-1.rs new file mode 100644 index 00000000000..c13c8d8b765 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-1.rs @@ -0,0 +1,24 @@ +// run-pass + + +pub fn main() { + let i32_a: isize = 10; + assert_eq!(i32_a, 10); + assert_eq!(i32_a - 10, 0); + assert_eq!(i32_a / 10, 1); + assert_eq!(i32_a - 20, -10); + assert_eq!(i32_a << 10, 10240); + assert_eq!(i32_a << 16, 655360); + assert_eq!(i32_a * 16, 160); + assert_eq!(i32_a * i32_a * i32_a, 1000); + assert_eq!(i32_a * i32_a * i32_a * i32_a, 10000); + assert_eq!(i32_a * i32_a / i32_a * i32_a, 100); + assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as usize), 368640); + let i32_b: isize = 0x10101010; + assert_eq!(i32_b + 1 - 1, i32_b); + assert_eq!(i32_b << 1, i32_b << 1); + assert_eq!(i32_b >> 1, i32_b >> 1); + assert_eq!(i32_b & i32_b << 1, 0); + println!("{}", i32_b | i32_b << 1); + assert_eq!(i32_b | i32_b << 1, 0x30303030); +} diff --git a/src/test/ui/numbers-arithmetic/arith-2.rs b/src/test/ui/numbers-arithmetic/arith-2.rs new file mode 100644 index 00000000000..46c280677ce --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-2.rs @@ -0,0 +1,9 @@ +// run-pass + + + +pub fn main() { + let i32_c: isize = 0x10101010; + assert_eq!(i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3), + i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3)); +} diff --git a/src/test/ui/numbers-arithmetic/arith-unsigned.rs b/src/test/ui/numbers-arithmetic/arith-unsigned.rs new file mode 100644 index 00000000000..ad57d9f8645 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/arith-unsigned.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_comparisons)] + +// Unsigned integer operations +pub fn main() { + assert!((0u8 < 255u8)); + assert!((0u8 <= 255u8)); + assert!((255u8 > 0u8)); + assert!((255u8 >= 0u8)); + assert_eq!(250u8 / 10u8, 25u8); + assert_eq!(255u8 % 10u8, 5u8); + assert!((0u16 < 60000u16)); + assert!((0u16 <= 60000u16)); + assert!((60000u16 > 0u16)); + assert!((60000u16 >= 0u16)); + assert_eq!(60000u16 / 10u16, 6000u16); + assert_eq!(60005u16 % 10u16, 5u16); + assert!((0u32 < 4000000000u32)); + assert!((0u32 <= 4000000000u32)); + assert!((4000000000u32 > 0u32)); + assert!((4000000000u32 >= 0u32)); + assert_eq!(4000000000u32 / 10u32, 400000000u32); + assert_eq!(4000000005u32 % 10u32, 5u32); + // 64-bit numbers have some flakiness yet. Not tested + +} diff --git a/src/test/ui/numbers-arithmetic/div-mod.rs b/src/test/ui/numbers-arithmetic/div-mod.rs new file mode 100644 index 00000000000..acb92a7df73 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/div-mod.rs @@ -0,0 +1,19 @@ +// run-pass + + + + +pub fn main() { + let x: isize = 15; + let y: isize = 5; + assert_eq!(x / 5, 3); + assert_eq!(x / 4, 3); + assert_eq!(x / 3, 5); + assert_eq!(x / y, 3); + assert_eq!(15 / y, 3); + assert_eq!(x % 5, 0); + assert_eq!(x % 4, 3); + assert_eq!(x % 3, 0); + assert_eq!(x % y, 0); + assert_eq!(15 % y, 0); +} diff --git a/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs new file mode 100644 index 00000000000..d210abdf499 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs @@ -0,0 +1,53 @@ +// run-pass +// ignore-emscripten no i128 support + +#![deny(const_err)] + +use std::{f32, f64}; + +// Forces evaluation of constants, triggering hard error +fn force<T>(_: T) {} + +fn main() { + { const X: u16 = -1. as u16; force(X); } + { const X: u128 = -100. as u128; force(X); } + + { const X: i8 = f32::NAN as i8; force(X); } + { const X: i32 = f32::NAN as i32; force(X); } + { const X: u64 = f32::NAN as u64; force(X); } + { const X: u128 = f32::NAN as u128; force(X); } + + { const X: i8 = f32::INFINITY as i8; force(X); } + { const X: u32 = f32::INFINITY as u32; force(X); } + { const X: i128 = f32::INFINITY as i128; force(X); } + { const X: u128 = f32::INFINITY as u128; force(X); } + + { const X: u8 = f32::NEG_INFINITY as u8; force(X); } + { const X: u16 = f32::NEG_INFINITY as u16; force(X); } + { const X: i64 = f32::NEG_INFINITY as i64; force(X); } + { const X: i128 = f32::NEG_INFINITY as i128; force(X); } + + { const X: i8 = f64::NAN as i8; force(X); } + { const X: i32 = f64::NAN as i32; force(X); } + { const X: u64 = f64::NAN as u64; force(X); } + { const X: u128 = f64::NAN as u128; force(X); } + + { const X: i8 = f64::INFINITY as i8; force(X); } + { const X: u32 = f64::INFINITY as u32; force(X); } + { const X: i128 = f64::INFINITY as i128; force(X); } + { const X: u128 = f64::INFINITY as u128; force(X); } + + { const X: u8 = f64::NEG_INFINITY as u8; force(X); } + { const X: u16 = f64::NEG_INFINITY as u16; force(X); } + { const X: i64 = f64::NEG_INFINITY as i64; force(X); } + { const X: i128 = f64::NEG_INFINITY as i128; force(X); } + + { const X: u8 = 256. as u8; force(X); } + { const X: i8 = -129. as i8; force(X); } + { const X: i8 = 128. as i8; force(X); } + { const X: i32 = 2147483648. as i32; force(X); } + { const X: i32 = -2147483904. as i32; force(X); } + { const X: u32 = 4294967296. as u32; force(X); } + { const X: u128 = 1e40 as u128; force(X); } + { const X: i128 = 1e40 as i128; force(X); } +} diff --git a/src/test/ui/numbers-arithmetic/float-literal-inference.rs b/src/test/ui/numbers-arithmetic/float-literal-inference.rs new file mode 100644 index 00000000000..c4645e4f8ff --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-literal-inference.rs @@ -0,0 +1,13 @@ +// run-pass +struct S { + z: f64 +} + +pub fn main() { + let x: f32 = 4.0; + println!("{}", x); + let y: f64 = 64.0; + println!("{}", y); + let z = S { z: 1.0 }; + println!("{}", z.z); +} diff --git a/src/test/ui/numbers-arithmetic/float-nan.rs b/src/test/ui/numbers-arithmetic/float-nan.rs new file mode 100644 index 00000000000..ee87b8cccfe --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-nan.rs @@ -0,0 +1,83 @@ +// run-pass +use std::f64; + +pub fn main() { + let nan: f64 = f64::NAN; + assert!((nan).is_nan()); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = -f64::INFINITY; + assert_eq!(-inf, neg_inf); + + assert!( nan != nan); + assert!( nan != -nan); + assert!(-nan != -nan); + assert!(-nan != nan); + + assert!( nan != 1.); + assert!( nan != 0.); + assert!( nan != inf); + assert!( nan != -inf); + + assert!( 1. != nan); + assert!( 0. != nan); + assert!( inf != nan); + assert!(-inf != nan); + + assert!(!( nan == nan)); + assert!(!( nan == -nan)); + assert!(!( nan == 1.)); + assert!(!( nan == 0.)); + assert!(!( nan == inf)); + assert!(!( nan == -inf)); + assert!(!( 1. == nan)); + assert!(!( 0. == nan)); + assert!(!( inf == nan)); + assert!(!(-inf == nan)); + assert!(!(-nan == nan)); + assert!(!(-nan == -nan)); + + assert!(!( nan > nan)); + assert!(!( nan > -nan)); + assert!(!( nan > 0.)); + assert!(!( nan > inf)); + assert!(!( nan > -inf)); + assert!(!( 0. > nan)); + assert!(!( inf > nan)); + assert!(!(-inf > nan)); + assert!(!(-nan > nan)); + + assert!(!(nan < 0.)); + assert!(!(nan < 1.)); + assert!(!(nan < -1.)); + assert!(!(nan < inf)); + assert!(!(nan < -inf)); + assert!(!(nan < nan)); + assert!(!(nan < -nan)); + + assert!(!( 0. < nan)); + assert!(!( 1. < nan)); + assert!(!( -1. < nan)); + assert!(!( inf < nan)); + assert!(!(-inf < nan)); + assert!(!(-nan < nan)); + + assert!((nan + inf).is_nan()); + assert!((nan + -inf).is_nan()); + assert!((nan + 0.).is_nan()); + assert!((nan + 1.).is_nan()); + assert!((nan * 1.).is_nan()); + assert!((nan / 1.).is_nan()); + assert!((nan / 0.).is_nan()); + assert!((0.0/0.0f64).is_nan()); + assert!((-inf + inf).is_nan()); + assert!((inf - inf).is_nan()); + + assert!(!(-1.0f64).is_nan()); + assert!(!(0.0f64).is_nan()); + assert!(!(0.1f64).is_nan()); + assert!(!(1.0f64).is_nan()); + assert!(!(inf).is_nan()); + assert!(!(-inf).is_nan()); + assert!(!(1./-inf).is_nan()); +} diff --git a/src/test/ui/numbers-arithmetic/float-signature.rs b/src/test/ui/numbers-arithmetic/float-signature.rs new file mode 100644 index 00000000000..d47280ea2e7 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float-signature.rs @@ -0,0 +1,9 @@ +// run-pass + + +pub fn main() { + fn foo(n: f64) -> f64 { return n + 0.12345; } + let n: f64 = 0.1; + let m: f64 = foo(n); + println!("{}", m); +} diff --git a/src/test/ui/numbers-arithmetic/float.rs b/src/test/ui/numbers-arithmetic/float.rs new file mode 100644 index 00000000000..d55c05857b6 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float.rs @@ -0,0 +1,9 @@ +// run-pass +pub fn main() { + let pi = 3.1415927f64; + println!("{}", -pi * (pi + 2.0 / pi) - pi * 5.0); + if pi == 5.0 || pi < 10.0 || pi <= 2.0 || pi != 22.0 / 7.0 || pi >= 10.0 + || pi > 1.0 { + println!("yes"); + } +} diff --git a/src/test/ui/numbers-arithmetic/float2.rs b/src/test/ui/numbers-arithmetic/float2.rs new file mode 100644 index 00000000000..b1bcf8da5a3 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float2.rs @@ -0,0 +1,26 @@ +// run-pass + + + +pub fn main() { + let a = 1.5e6f64; + let b = 1.5E6f64; + let c = 1e6f64; + let d = 1E6f64; + let e = 3.0f32; + let f = 5.9f64; + let g = 1e6f32; + let h = 1.0e7f64; + let i = 1.0E7f64; + let j = 3.1e+9f64; + let k = 3.2e-10f64; + assert_eq!(a, b); + assert!((c < b)); + assert_eq!(c, d); + assert!((e < g)); + assert!((f < h)); + assert_eq!(g, 1000000.0f32); + assert_eq!(h, i); + assert!((j > k)); + assert!((k < a)); +} diff --git a/src/test/ui/numbers-arithmetic/float_math.rs b/src/test/ui/numbers-arithmetic/float_math.rs new file mode 100644 index 00000000000..a2902ee5608 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/float_math.rs @@ -0,0 +1,21 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::{fadd_fast, fsub_fast, fmul_fast, fdiv_fast, frem_fast}; + +#[inline(never)] +pub fn test_operations(a: f64, b: f64) { + // make sure they all map to the correct operation + unsafe { + assert_eq!(fadd_fast(a, b), a + b); + assert_eq!(fsub_fast(a, b), a - b); + assert_eq!(fmul_fast(a, b), a * b); + assert_eq!(fdiv_fast(a, b), a / b); + assert_eq!(frem_fast(a, b), a % b); + } +} + +fn main() { + test_operations(1., 2.); + test_operations(10., 5.); +} diff --git a/src/test/ui/numbers-arithmetic/floatlits.rs b/src/test/ui/numbers-arithmetic/floatlits.rs new file mode 100644 index 00000000000..07049af315b --- /dev/null +++ b/src/test/ui/numbers-arithmetic/floatlits.rs @@ -0,0 +1,12 @@ +// run-pass + + + +pub fn main() { + let f = 4.999999999999f64; + assert!((f > 4.90f64)); + assert!((f < 5.0f64)); + let g = 4.90000000001e-10f64; + assert!((g > 5e-11f64)); + assert!((g < 5e-9f64)); +} diff --git a/src/test/ui/numbers-arithmetic/i128-ffi.rs b/src/test/ui/numbers-arithmetic/i128-ffi.rs new file mode 100644 index 00000000000..19edf9779f3 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i128-ffi.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(improper_ctypes)] + +// MSVC doesn't support 128 bit integers, and other Windows +// C compilers have very inconsistent views on how the ABI +// should look like. + +// ignore-windows +// ignore-32bit + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn identity(f: u128) -> u128; + fn square(f: i128) -> i128; + fn sub(f: i128, f: i128) -> i128; +} + +fn main() { + unsafe { + let a = 0x734C_C2F2_A521; + let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41; + let b_out = identity(b); + assert_eq!(b, b_out); + let a_square = square(a); + assert_eq!(b, a_square as u128); + let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420; + let k_out = sub(k_d, k); + assert_eq!(k, k_out); + } +} diff --git a/src/test/ui/numbers-arithmetic/i128.rs b/src/test/ui/numbers-arithmetic/i128.rs new file mode 100644 index 00000000000..ea0ef95e4f1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i128.rs @@ -0,0 +1,110 @@ +// run-pass +#![allow(overflowing_literals)] + +// ignore-emscripten i128 doesn't work + + +#![feature(test)] + +extern crate test; +use test::black_box as b; + +fn main() { + let x: i128 = -1; + assert_eq!(0, !x); + let y: i128 = -2; + assert_eq!(!1, y); + let z: i128 = 0xABCD_EF; + assert_eq!(z * z, 0x734C_C2F2_A521); + assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z * -z, 0x734C_C2F2_A521); + assert_eq!(-z * -z * -z * -z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z + -z + -z + -z, -0x2AF3_7BC); + let k: i128 = -0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + assert_eq!(k + k, -0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420); + assert_eq!(0, k - k); + assert_eq!(-0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k + z); + assert_eq!(-0x1000_0000_0000_0000_0000_0000_0000_000, + k + 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(-0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42); + assert_eq!(-k, k / -1); + assert_eq!(-0x91A2_B3C4_D5E6_F8, k >> 65); + assert_eq!(-0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65); + assert!(k < z); + assert!(y > k); + assert!(y < x); + assert_eq!(x as i64, -1); + assert_eq!(z as i64, 0xABCD_EF); + assert_eq!(k as i64, -0xFEDC_BA98_7654_3210); + assert_eq!(k as u128, 0xFEDC_BA98_7654_3210_0123_4567_89AB_CDF0); + assert_eq!(-k as u128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!((-z as f64) as i128, -z); + assert_eq!((-z as f32) as i128, -z); + assert_eq!((-z as f64 * 16.0) as i128, -z * 16); + assert_eq!((-z as f32 * 16.0) as i128, -z * 16); + // Same stuff as above, but blackboxed, to force use of intrinsics + let x: i128 = b(-1); + assert_eq!(0, !x); + let y: i128 = b(-2); + assert_eq!(!1, y); + let z: i128 = b(0xABCD_EF); + assert_eq!(z * z, 0x734C_C2F2_A521); + assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z * -z, 0x734C_C2F2_A521); + assert_eq!(-z * -z * -z * -z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z + -z + -z + -z, -0x2AF3_7BC); + let k: i128 = b(-0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(k + k, -0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420); + assert_eq!(0, k - k); + assert_eq!(-0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k + z); + assert_eq!(-0x1000_0000_0000_0000_0000_0000_0000_000, + k + 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(-0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42); + assert_eq!(-k, k / -1); + assert_eq!(-0x91A2_B3C4_D5E6_F8, k >> 65); + assert_eq!(-0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65); + assert!(k < z); + assert!(y > k); + assert!(y < x); + assert_eq!(x as i64, -1); + assert_eq!(z as i64, 0xABCD_EF); + assert_eq!(k as i64, -0xFEDC_BA98_7654_3210); + assert_eq!(k as u128, 0xFEDC_BA98_7654_3210_0123_4567_89AB_CDF0); + assert_eq!(-k as u128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!((-z as f64) as i128, -z); + assert_eq!((-z as f32) as i128, -z); + assert_eq!((-z as f64 * 16.0) as i128, -z * 16); + assert_eq!((-z as f32 * 16.0) as i128, -z * 16); + // formatting + let j: i128 = -(1 << 67); + assert_eq!("-147573952589676412928", format!("{}", j)); + assert_eq!("fffffffffffffff80000000000000000", format!("{:x}", j)); + assert_eq!("3777777777777777777760000000000000000000000", format!("{:o}", j)); + assert_eq!("1111111111111111111111111111111111111111111111111111111111111\ + 0000000000000000000000000000000000000000000000000000000000000000000", + format!("{:b}", j)); + assert_eq!("-147573952589676412928", format!("{:?}", j)); + // common traits + assert_eq!(x, b(x.clone())); + // overflow checks + assert_eq!((-z).checked_mul(-z), Some(0x734C_C2F2_A521)); + assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); + assert_eq!((k).checked_mul(k), None); + let l: i128 = b(i128::min_value()); + let o: i128 = b(17); + assert_eq!(l.checked_sub(b(2)), None); + assert_eq!(l.checked_add(l), None); + assert_eq!((-(l + 1)).checked_add(2), None); + assert_eq!(l.checked_sub(l), Some(0)); + assert_eq!(b(1u128).checked_shl(b(127)), Some(1 << 127)); + assert_eq!(o.checked_shl(b(128)), None); + + // https://github.com/rust-lang/rust/issues/41228 + assert_eq!(b(-87559967289969187895646876466835277875_i128) / + b(84285771033834995895337664386045050880_i128), + -1i128); + + // iter-arithmetic traits + assert_eq!(10i128, [1i128, 2, 3, 4].iter().sum()); + assert_eq!(24i128, [1i128, 2, 3, 4].iter().product()); +} diff --git a/src/test/ui/numbers-arithmetic/i32-sub.rs b/src/test/ui/numbers-arithmetic/i32-sub.rs new file mode 100644 index 00000000000..56df772b4e1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i32-sub.rs @@ -0,0 +1,6 @@ +// run-pass + + + + +pub fn main() { let mut x: i32 = -400; x = 0 - x; assert_eq!(x, 400); } diff --git a/src/test/ui/numbers-arithmetic/i8-incr.rs b/src/test/ui/numbers-arithmetic/i8-incr.rs new file mode 100644 index 00000000000..718d259f735 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/i8-incr.rs @@ -0,0 +1,12 @@ +// run-pass + + + + +pub fn main() { + let mut x: i8 = -12; + let y: i8 = -12; + x = x + 1; + x = x - 1; + assert_eq!(x, y); +} diff --git a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs new file mode 100644 index 00000000000..2bc018445db --- /dev/null +++ b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs @@ -0,0 +1,13 @@ +// run-pass +// compile-flags: -Z force-overflow-checks=on +// ignore-emscripten no threads support + +use std::thread; + +fn main() { + assert!(thread::spawn(|| i8::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i16::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i32::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| i64::min_value().abs()).join().is_err()); + assert!(thread::spawn(|| isize::min_value().abs()).join().is_err()); +} diff --git a/src/test/ui/numbers-arithmetic/int.rs b/src/test/ui/numbers-arithmetic/int.rs new file mode 100644 index 00000000000..b496a70a6fe --- /dev/null +++ b/src/test/ui/numbers-arithmetic/int.rs @@ -0,0 +1,7 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +pub fn main() { let _x: isize = 10; } diff --git a/src/test/ui/numbers-arithmetic/integer-literal-radix.rs b/src/test/ui/numbers-arithmetic/integer-literal-radix.rs new file mode 100644 index 00000000000..8f61ea17a12 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-radix.rs @@ -0,0 +1,19 @@ +// run-pass + +pub fn main() { + let a = 0xBEEF_isize; + let b = 0o755_isize; + let c = 0b10101_isize; + let d = -0xBEEF_isize; + let e = -0o755_isize; + let f = -0b10101_isize; + + assert_eq!(a, 48879); + assert_eq!(b, 493); + assert_eq!(c, 21); + assert_eq!(d, -48879); + assert_eq!(e, -493); + assert_eq!(f, -21); + + +} diff --git a/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs new file mode 100644 index 00000000000..80248dc223d --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn foo(_: *const ()) {} + +fn main() { + let a = 3; + foo(&a as *const _ as *const ()); +} diff --git a/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs new file mode 100644 index 00000000000..bec718a3c6a --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs @@ -0,0 +1,4 @@ +// run-pass +fn main() { + println!("{}", std::mem::size_of_val(&1)); +} diff --git a/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs new file mode 100644 index 00000000000..d177ced1a69 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/integer-literal-suffix-inference.rs @@ -0,0 +1,60 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + fn id_i8(n: i8) -> i8 { n } + fn id_i16(n: i16) -> i16 { n } + fn id_i32(n: i32) -> i32 { n } + fn id_i64(n: i64) -> i64 { n } + + fn id_uint(n: usize) -> usize { n } + fn id_u8(n: u8) -> u8 { n } + fn id_u16(n: u16) -> u16 { n } + fn id_u32(n: u32) -> u32 { n } + fn id_u64(n: u64) -> u64 { n } + + let _i: i8 = -128; + let j = -128; + id_i8(j); + id_i8(-128); + + let _i: i16 = -32_768; + let j = -32_768; + id_i16(j); + id_i16(-32_768); + + let _i: i32 = -2_147_483_648; + let j = -2_147_483_648; + id_i32(j); + id_i32(-2_147_483_648); + + let _i: i64 = -9_223_372_036_854_775_808; + let j = -9_223_372_036_854_775_808; + id_i64(j); + id_i64(-9_223_372_036_854_775_808); + + let _i: usize = 1; + let j = 1; + id_uint(j); + id_uint(1); + + let _i: u8 = 255; + let j = 255; + id_u8(j); + id_u8(255); + + let _i: u16 = 65_535; + let j = 65_535; + id_u16(j); + id_u16(65_535); + + let _i: u32 = 4_294_967_295; + let j = 4_294_967_295; + id_u32(j); + id_u32(4_294_967_295); + + let _i: u64 = 18_446_744_073_709_551_615; + let j = 18_446_744_073_709_551_615; + id_u64(j); + id_u64(18_446_744_073_709_551_615); +} diff --git a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs new file mode 100644 index 00000000000..e9927304f23 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: -C debug_assertions=yes +// ignore-wasm32-bare compiled with panic=abort by default +// ignore-emscripten dies with an LLVM error + +use std::panic; + +fn main() { + macro_rules! overflow_test { + ($t:ident) => ( + let r = panic::catch_unwind(|| { + ($t::max_value()).next_power_of_two() + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + (($t::max_value() >> 1) + 2).next_power_of_two() + }); + assert!(r.is_err()); + ) + } + overflow_test!(u8); + overflow_test!(u16); + overflow_test!(u32); + overflow_test!(u64); + overflow_test!(u128); +} diff --git a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs new file mode 100644 index 00000000000..982cd97c50a --- /dev/null +++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: -C debug_assertions=no +// ignore-emscripten dies with an LLVM error + +fn main() { + for i in 129..256 { + assert_eq!((i as u8).next_power_of_two(), 0); + } + + assert_eq!(((1u16 << 15) + 1).next_power_of_two(), 0); + assert_eq!(((1u32 << 31) + 1).next_power_of_two(), 0); + assert_eq!(((1u64 << 63) + 1).next_power_of_two(), 0); + assert_eq!(((1u128 << 127) + 1).next_power_of_two(), 0); +} diff --git a/src/test/ui/numbers-arithmetic/num-wrapping.rs b/src/test/ui/numbers-arithmetic/num-wrapping.rs new file mode 100644 index 00000000000..9a01549ecd2 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/num-wrapping.rs @@ -0,0 +1,447 @@ +// run-pass +#![allow(unused_macros)] + +// compile-flags: -C debug-assertions +// +// Test std::num::Wrapping<T> for {uN, iN, usize, isize} + +#![feature(test)] + +extern crate test; + +use std::num::Wrapping; +use std::ops::{ + Add, Sub, Mul, Div, Rem, BitXor, BitOr, BitAnd, + AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, BitXorAssign, BitOrAssign, BitAndAssign, + Shl, Shr, ShlAssign, ShrAssign +}; +use test::black_box; + +macro_rules! int_modules { + ($(($name:ident, $size:expr),)*) => ($( + mod $name { + pub const BITS: usize = $size; + pub use std::$name::*; + } + )*) +} + +int_modules! { + (i8, 8), + (i16, 16), + (i32, 32), + (i64, 64), + (u8, 8), + (u16, 16), + (u32, 32), + (u64, 64), +} + +#[cfg(target_pointer_width = "32")] +int_modules! { + (isize, 32), + (usize, 32), +} + +#[cfg(target_pointer_width = "64")] +int_modules! { + (isize, 64), + (usize, 64), +} + +fn main() { + test_ops(); + test_op_assigns(); + test_sh_ops(); + test_sh_op_assigns(); +} + +fn test_ops() { + macro_rules! op_test { + ($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => { + assert_eq!(black_box(Wrapping($lhs).$op(Wrapping($rhs))), Wrapping($ans)); + // FIXME(30524): uncomment this test when it's implemented + // assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans)); + } + } + + op_test!(add(i8::MAX, 1) == i8::MIN); + op_test!(add(i16::MAX, 1) == i16::MIN); + op_test!(add(i32::MAX, 1) == i32::MIN); + op_test!(add(i64::MAX, 1) == i64::MIN); + op_test!(add(isize::MAX, 1) == isize::MIN); + + op_test!(add(u8::MAX, 1) == 0); + op_test!(add(u16::MAX, 1) == 0); + op_test!(add(u32::MAX, 1) == 0); + op_test!(add(u64::MAX, 1) == 0); + op_test!(add(usize::MAX, 1) == 0); + + + op_test!(sub(i8::MIN, 1) == i8::MAX); + op_test!(sub(i16::MIN, 1) == i16::MAX); + op_test!(sub(i32::MIN, 1) == i32::MAX); + op_test!(sub(i64::MIN, 1) == i64::MAX); + op_test!(sub(isize::MIN, 1) == isize::MAX); + + op_test!(sub(0u8, 1) == u8::MAX); + op_test!(sub(0u16, 1) == u16::MAX); + op_test!(sub(0u32, 1) == u32::MAX); + op_test!(sub(0u64, 1) == u64::MAX); + op_test!(sub(0usize, 1) == usize::MAX); + + + op_test!(mul(i8::MAX, 2) == -2); + op_test!(mul(i16::MAX, 2) == -2); + op_test!(mul(i32::MAX, 2) == -2); + op_test!(mul(i64::MAX, 2) == -2); + op_test!(mul(isize::MAX, 2) == -2); + + op_test!(mul(u8::MAX, 2) == u8::MAX - 1); + op_test!(mul(u16::MAX, 2) == u16::MAX - 1); + op_test!(mul(u32::MAX, 2) == u32::MAX - 1); + op_test!(mul(u64::MAX, 2) == u64::MAX - 1); + op_test!(mul(usize::MAX, 2) == usize::MAX - 1); + + + op_test!(div(i8::MIN, -1) == i8::MIN); + op_test!(div(i16::MIN, -1) == i16::MIN); + op_test!(div(i32::MIN, -1) == i32::MIN); + op_test!(div(i64::MIN, -1) == i64::MIN); + op_test!(div(isize::MIN, -1) == isize::MIN); + + + op_test!(rem(i8::MIN, -1) == 0); + op_test!(rem(i16::MIN, -1) == 0); + op_test!(rem(i32::MIN, -1) == 0); + op_test!(rem(i64::MIN, -1) == 0); + op_test!(rem(isize::MIN, -1) == 0); + + // these are not that interesting, just testing to make sure they are implemented correctly + op_test!(bitxor(0b101010i8, 0b100110) == 0b001100); + op_test!(bitxor(0b101010i16, 0b100110) == 0b001100); + op_test!(bitxor(0b101010i32, 0b100110) == 0b001100); + op_test!(bitxor(0b101010i64, 0b100110) == 0b001100); + op_test!(bitxor(0b101010isize, 0b100110) == 0b001100); + + op_test!(bitxor(0b101010u8, 0b100110) == 0b001100); + op_test!(bitxor(0b101010u16, 0b100110) == 0b001100); + op_test!(bitxor(0b101010u32, 0b100110) == 0b001100); + op_test!(bitxor(0b101010u64, 0b100110) == 0b001100); + op_test!(bitxor(0b101010usize, 0b100110) == 0b001100); + + + op_test!(bitor(0b101010i8, 0b100110) == 0b101110); + op_test!(bitor(0b101010i16, 0b100110) == 0b101110); + op_test!(bitor(0b101010i32, 0b100110) == 0b101110); + op_test!(bitor(0b101010i64, 0b100110) == 0b101110); + op_test!(bitor(0b101010isize, 0b100110) == 0b101110); + + op_test!(bitor(0b101010u8, 0b100110) == 0b101110); + op_test!(bitor(0b101010u16, 0b100110) == 0b101110); + op_test!(bitor(0b101010u32, 0b100110) == 0b101110); + op_test!(bitor(0b101010u64, 0b100110) == 0b101110); + op_test!(bitor(0b101010usize, 0b100110) == 0b101110); + + + op_test!(bitand(0b101010i8, 0b100110) == 0b100010); + op_test!(bitand(0b101010i16, 0b100110) == 0b100010); + op_test!(bitand(0b101010i32, 0b100110) == 0b100010); + op_test!(bitand(0b101010i64, 0b100110) == 0b100010); + op_test!(bitand(0b101010isize, 0b100110) == 0b100010); + + op_test!(bitand(0b101010u8, 0b100110) == 0b100010); + op_test!(bitand(0b101010u16, 0b100110) == 0b100010); + op_test!(bitand(0b101010u32, 0b100110) == 0b100010); + op_test!(bitand(0b101010u64, 0b100110) == 0b100010); + op_test!(bitand(0b101010usize, 0b100110) == 0b100010); +} + +fn test_op_assigns() { + macro_rules! op_assign_test { + ($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => { + { + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op(Wrapping($rhs)); + assert_eq!(black_box(tmp), Wrapping($ans)); + } + + // also test that a &Wrapping<T> right-hand side is possible + { + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op(&Wrapping($rhs)); + assert_eq!(black_box(tmp), Wrapping($ans)); + } + + // FIXME(30524): uncomment this test + /* + { + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op($rhs); + assert_eq!(black_box(tmp), Wrapping($ans)); + } + */ + } + } + op_assign_test!(add_assign(i8::MAX, 1) == i8::MIN); + op_assign_test!(add_assign(i16::MAX, 1) == i16::MIN); + op_assign_test!(add_assign(i32::MAX, 1) == i32::MIN); + op_assign_test!(add_assign(i64::MAX, 1) == i64::MIN); + op_assign_test!(add_assign(isize::MAX, 1) == isize::MIN); + + op_assign_test!(add_assign(u8::MAX, 1) == u8::MIN); + op_assign_test!(add_assign(u16::MAX, 1) == u16::MIN); + op_assign_test!(add_assign(u32::MAX, 1) == u32::MIN); + op_assign_test!(add_assign(u64::MAX, 1) == u64::MIN); + op_assign_test!(add_assign(usize::MAX, 1) == usize::MIN); + + + op_assign_test!(sub_assign(i8::MIN, 1) == i8::MAX); + op_assign_test!(sub_assign(i16::MIN, 1) == i16::MAX); + op_assign_test!(sub_assign(i32::MIN, 1) == i32::MAX); + op_assign_test!(sub_assign(i64::MIN, 1) == i64::MAX); + op_assign_test!(sub_assign(isize::MIN, 1) == isize::MAX); + + op_assign_test!(sub_assign(u8::MIN, 1) == u8::MAX); + op_assign_test!(sub_assign(u16::MIN, 1) == u16::MAX); + op_assign_test!(sub_assign(u32::MIN, 1) == u32::MAX); + op_assign_test!(sub_assign(u64::MIN, 1) == u64::MAX); + op_assign_test!(sub_assign(usize::MIN, 1) == usize::MAX); + + + op_assign_test!(mul_assign(i8::MAX, 2) == -2); + op_assign_test!(mul_assign(i16::MAX, 2) == -2); + op_assign_test!(mul_assign(i32::MAX, 2) == -2); + op_assign_test!(mul_assign(i64::MAX, 2) == -2); + op_assign_test!(mul_assign(isize::MAX, 2) == -2); + + op_assign_test!(mul_assign(u8::MAX, 2) == u8::MAX - 1); + op_assign_test!(mul_assign(u16::MAX, 2) == u16::MAX - 1); + op_assign_test!(mul_assign(u32::MAX, 2) == u32::MAX - 1); + op_assign_test!(mul_assign(u64::MAX, 2) == u64::MAX - 1); + op_assign_test!(mul_assign(usize::MAX, 2) == usize::MAX - 1); + + + op_assign_test!(div_assign(i8::MIN, -1) == i8::MIN); + op_assign_test!(div_assign(i16::MIN, -1) == i16::MIN); + op_assign_test!(div_assign(i32::MIN, -1) == i32::MIN); + op_assign_test!(div_assign(i64::MIN, -1) == i64::MIN); + op_assign_test!(div_assign(isize::MIN, -1) == isize::MIN); + + + op_assign_test!(rem_assign(i8::MIN, -1) == 0); + op_assign_test!(rem_assign(i16::MIN, -1) == 0); + op_assign_test!(rem_assign(i32::MIN, -1) == 0); + op_assign_test!(rem_assign(i64::MIN, -1) == 0); + op_assign_test!(rem_assign(isize::MIN, -1) == 0); + + + // these are not that interesting, just testing to make sure they are implemented correctly + op_assign_test!(bitxor_assign(0b101010i8, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010i16, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010i32, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010i64, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010isize, 0b100110) == 0b001100); + + op_assign_test!(bitxor_assign(0b101010u8, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010u16, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010u32, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010u64, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010usize, 0b100110) == 0b001100); + + + op_assign_test!(bitor_assign(0b101010i8, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010i16, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010i32, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010i64, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010isize, 0b100110) == 0b101110); + + op_assign_test!(bitor_assign(0b101010u8, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010u16, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010u32, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010u64, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010usize, 0b100110) == 0b101110); + + + op_assign_test!(bitand_assign(0b101010i8, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010i16, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010i32, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010i64, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010isize, 0b100110) == 0b100010); + + op_assign_test!(bitand_assign(0b101010u8, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010u16, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010u32, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010u64, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010usize, 0b100110) == 0b100010); +} + +fn test_sh_ops() { + macro_rules! sh_test { + ($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => { + assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans)); + } + } + // NOTE: This will break for i8 if we ever get i/u128 + macro_rules! sh_test_all { + ($t:ty) => { + sh_test!(shl(i8::MAX, (i8::BITS + 1) as $t) == -2); + sh_test!(shl(i16::MAX, (i16::BITS + 1) as $t) == -2); + sh_test!(shl(i32::MAX, (i32::BITS + 1) as $t) == -2); + sh_test!(shl(i64::MAX, (i64::BITS + 1) as $t) == -2); + sh_test!(shl(isize::MAX, (isize::BITS + 1) as $t) == -2); + + sh_test!(shl(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX - 1); + sh_test!(shl(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX - 1); + sh_test!(shl(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX - 1); + sh_test!(shl(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX - 1); + sh_test!(shl(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX - 1); + + + sh_test!(shr(i8::MAX, (i8::BITS + 1) as $t) == i8::MAX / 2); + sh_test!(shr(i16::MAX, (i16::BITS + 1) as $t) == i16::MAX / 2); + sh_test!(shr(i32::MAX, (i32::BITS + 1) as $t) == i32::MAX / 2); + sh_test!(shr(i64::MAX, (i64::BITS + 1) as $t) == i64::MAX / 2); + sh_test!(shr(isize::MAX, (isize::BITS + 1) as $t) == isize::MAX / 2); + + sh_test!(shr(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX / 2); + sh_test!(shr(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX / 2); + sh_test!(shr(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX / 2); + sh_test!(shr(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX / 2); + sh_test!(shr(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX / 2); + } + } + macro_rules! sh_test_negative_all { + ($t:ty) => { + sh_test!(shr(i8::MAX, -((i8::BITS + 1) as $t)) == -2); + sh_test!(shr(i16::MAX, -((i16::BITS + 1) as $t)) == -2); + sh_test!(shr(i32::MAX, -((i32::BITS + 1) as $t)) == -2); + sh_test!(shr(i64::MAX, -((i64::BITS + 1) as $t)) == -2); + sh_test!(shr(isize::MAX, -((isize::BITS + 1) as $t)) == -2); + + sh_test!(shr(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX - 1); + sh_test!(shr(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX - 1); + sh_test!(shr(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX - 1); + sh_test!(shr(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX - 1); + sh_test!(shr(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX - 1); + + + sh_test!(shl(i8::MAX, -((i8::BITS + 1) as $t)) == i8::MAX / 2); + sh_test!(shl(i16::MAX, -((i16::BITS + 1) as $t)) == i16::MAX / 2); + sh_test!(shl(i32::MAX, -((i32::BITS + 1) as $t)) == i32::MAX / 2); + sh_test!(shl(i64::MAX, -((i64::BITS + 1) as $t)) == i64::MAX / 2); + sh_test!(shl(isize::MAX, -((isize::BITS + 1) as $t)) == isize::MAX / 2); + + sh_test!(shl(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX / 2); + sh_test!(shl(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX / 2); + sh_test!(shl(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX / 2); + sh_test!(shl(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX / 2); + sh_test!(shl(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX / 2); + } + } + // FIXME(#23545): Uncomment the remaining tests + //sh_test_all!(i8); + //sh_test_all!(u8); + //sh_test_all!(i16); + //sh_test_all!(u16); + //sh_test_all!(i32); + //sh_test_all!(u32); + //sh_test_all!(i64); + //sh_test_all!(u64); + //sh_test_all!(isize); + sh_test_all!(usize); + + //sh_test_negative_all!(i8); + //sh_test_negative_all!(i16); + //sh_test_negative_all!(i32); + //sh_test_negative_all!(i64); + //sh_test_negative_all!(isize); +} + +fn test_sh_op_assigns() { + macro_rules! sh_assign_test { + ($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => {{ + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op($rhs); + assert_eq!(black_box(tmp), Wrapping($ans)); + }} + } + macro_rules! sh_assign_test_all { + ($t:ty) => { + sh_assign_test!(shl_assign(i8::MAX, (i8::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(i16::MAX, (i16::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(i32::MAX, (i32::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(i64::MAX, (i64::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(isize::MAX, (isize::BITS + 1) as $t) == -2); + + sh_assign_test!(shl_assign(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX - 1); + sh_assign_test!(shl_assign(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX - 1); + sh_assign_test!(shl_assign(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX - 1); + sh_assign_test!(shl_assign(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX - 1); + sh_assign_test!(shl_assign(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX - 1); + + + sh_assign_test!(shr_assign(i8::MAX, (i8::BITS + 1) as $t) == i8::MAX / 2); + sh_assign_test!(shr_assign(i16::MAX, (i16::BITS + 1) as $t) == i16::MAX / 2); + sh_assign_test!(shr_assign(i32::MAX, (i32::BITS + 1) as $t) == i32::MAX / 2); + sh_assign_test!(shr_assign(i64::MAX, (i64::BITS + 1) as $t) == i64::MAX / 2); + sh_assign_test!(shr_assign(isize::MAX, (isize::BITS + 1) as $t) == isize::MAX / 2); + + sh_assign_test!(shr_assign(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX / 2); + sh_assign_test!(shr_assign(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX / 2); + sh_assign_test!(shr_assign(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX / 2); + sh_assign_test!(shr_assign(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX / 2); + sh_assign_test!(shr_assign(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX / 2); + } + } + macro_rules! sh_assign_test_negative_all { + ($t:ty) => { + sh_assign_test!(shr_assign(i8::MAX, -((i8::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(i16::MAX, -((i16::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(i32::MAX, -((i32::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(i64::MAX, -((i64::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(isize::MAX, -((isize::BITS + 1) as $t)) == -2); + + sh_assign_test!(shr_assign(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX - 1); + sh_assign_test!(shr_assign(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX - 1); + sh_assign_test!(shr_assign(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX - 1); + sh_assign_test!(shr_assign(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX - 1); + sh_assign_test!(shr_assign(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX - 1); + + + sh_assign_test!(shl_assign(i8::MAX, -((i8::BITS + 1) as $t)) == i8::MAX / 2); + sh_assign_test!(shl_assign(i16::MAX, -((i16::BITS + 1) as $t)) == i16::MAX / 2); + sh_assign_test!(shl_assign(i32::MAX, -((i32::BITS + 1) as $t)) == i32::MAX / 2); + sh_assign_test!(shl_assign(i64::MAX, -((i64::BITS + 1) as $t)) == i64::MAX / 2); + sh_assign_test!(shl_assign(isize::MAX, -((isize::BITS + 1) as $t)) == isize::MAX / 2); + + sh_assign_test!(shl_assign(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX / 2); + sh_assign_test!(shl_assign(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX / 2); + sh_assign_test!(shl_assign(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX / 2); + sh_assign_test!(shl_assign(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX / 2); + sh_assign_test!(shl_assign(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX / 2); + } + } + + // FIXME(#23545): Uncomment the remaining tests + //sh_assign_test_all!(i8); + //sh_assign_test_all!(u8); + //sh_assign_test_all!(i16); + //sh_assign_test_all!(u16); + //sh_assign_test_all!(i32); + //sh_assign_test_all!(u32); + //sh_assign_test_all!(i64); + //sh_assign_test_all!(u64); + //sh_assign_test_all!(isize); + sh_assign_test_all!(usize); + + //sh_assign_test_negative_all!(i8); + //sh_assign_test_negative_all!(i16); + //sh_assign_test_negative_all!(i32); + //sh_assign_test_negative_all!(i64); + //sh_assign_test_negative_all!(isize); +} diff --git a/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs b/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs new file mode 100644 index 00000000000..5798c2591a0 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/numeric-method-autoexport.rs @@ -0,0 +1,25 @@ +// run-pass +// This file is intended to test only that methods are automatically +// reachable for each numeric type, for each exported impl, with no imports +// necessary. Testing the methods of the impls is done within the source +// file for each numeric type. + +use std::ops::Add; + +pub fn main() { +// ints + // num + assert_eq!(15_isize.add(6_isize), 21_isize); + assert_eq!(15_i8.add(6i8), 21_i8); + assert_eq!(15_i16.add(6i16), 21_i16); + assert_eq!(15_i32.add(6i32), 21_i32); + assert_eq!(15_i64.add(6i64), 21_i64); + +// uints + // num + assert_eq!(15_usize.add(6_usize), 21_usize); + assert_eq!(15_u8.add(6u8), 21_u8); + assert_eq!(15_u16.add(6u16), 21_u16); + assert_eq!(15_u32.add(6u32), 21_u32); + assert_eq!(15_u64.add(6u64), 21_u64); +} diff --git a/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs new file mode 100644 index 00000000000..a3b8ff58a73 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/promoted_overflow_opt.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(const_err)] + +// compile-flags: -O + +fn main() { + let x = &(0u32 - 1); + assert_eq!(*x, u32::max_value()) +} diff --git a/src/test/ui/numbers-arithmetic/saturating-float-casts.rs b/src/test/ui/numbers-arithmetic/saturating-float-casts.rs new file mode 100644 index 00000000000..f13964fb386 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/saturating-float-casts.rs @@ -0,0 +1,135 @@ +// run-pass +// Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. +// compile-flags: -Z saturating-float-casts + +#![feature(test, stmt_expr_attributes)] +#![deny(overflowing_literals)] +extern crate test; + +use std::{f32, f64}; +use std::{u8, i8, u16, i16, u32, i32, u64, i64}; +#[cfg(not(target_os="emscripten"))] +use std::{u128, i128}; +use test::black_box; + +macro_rules! test { + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ( + // black_box disables constant evaluation to test run-time conversions: + assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected, + "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + ); + + ($fval:expr, f* -> $ity:ident, $ival:expr) => ( + test!($fval, f32 -> $ity, $ival); + test!($fval, f64 -> $ity, $ival); + ) +} + +// This macro tests const eval in addition to run-time evaluation. +// If and when saturating casts are adopted, this macro should be merged with test!() to ensure +// that run-time and const eval agree on inputs that currently trigger a const eval error. +macro_rules! test_c { + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({ + test!($val, $src_ty -> $dest_ty, $expected); + { + const X: $src_ty = $val; + const Y: $dest_ty = X as $dest_ty; + assert_eq!(Y, $expected, + "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + } + }); + + ($fval:expr, f* -> $ity:ident, $ival:expr) => ( + test_c!($fval, f32 -> $ity, $ival); + test_c!($fval, f64 -> $ity, $ival); + ) +} + +macro_rules! common_fptoi_tests { + ($fty:ident -> $($ity:ident)+) => ({ $( + test!($fty::NAN, $fty -> $ity, 0); + test!($fty::INFINITY, $fty -> $ity, $ity::MAX); + test!($fty::NEG_INFINITY, $fty -> $ity, $ity::MIN); + // These two tests are not solely float->int tests, in particular the latter relies on + // `u128::MAX as f32` not being UB. But that's okay, since this file tests int->float + // as well, the test is just slightly misplaced. + test!($ity::MIN as $fty, $fty -> $ity, $ity::MIN); + test!($ity::MAX as $fty, $fty -> $ity, $ity::MAX); + test_c!(0., $fty -> $ity, 0); + test_c!($fty::MIN_POSITIVE, $fty -> $ity, 0); + test!(-0.9, $fty -> $ity, 0); + test_c!(1., $fty -> $ity, 1); + test_c!(42., $fty -> $ity, 42); + )+ }); + + (f* -> $($ity:ident)+) => ({ + common_fptoi_tests!(f32 -> $($ity)+); + common_fptoi_tests!(f64 -> $($ity)+); + }) +} + +macro_rules! fptoui_tests { + ($fty: ident -> $($ity: ident)+) => ({ $( + test!(-0., $fty -> $ity, 0); + test!(-$fty::MIN_POSITIVE, $fty -> $ity, 0); + test!(-0.99999994, $fty -> $ity, 0); + test!(-1., $fty -> $ity, 0); + test!(-100., $fty -> $ity, 0); + test!(#[allow(overflowing_literals)] -1e50, $fty -> $ity, 0); + test!(#[allow(overflowing_literals)] -1e130, $fty -> $ity, 0); + )+ }); + + (f* -> $($ity:ident)+) => ({ + fptoui_tests!(f32 -> $($ity)+); + fptoui_tests!(f64 -> $($ity)+); + }) +} + +pub fn main() { + common_fptoi_tests!(f* -> i8 i16 i32 i64 u8 u16 u32 u64); + fptoui_tests!(f* -> u8 u16 u32 u64); + // FIXME emscripten does not support i128 + #[cfg(not(target_os="emscripten"))] { + common_fptoi_tests!(f* -> i128 u128); + fptoui_tests!(f* -> u128); + } + + // The following tests cover edge cases for some integer types. + + // # u8 + test_c!(254., f* -> u8, 254); + test!(256., f* -> u8, 255); + + // # i8 + test_c!(-127., f* -> i8, -127); + test!(-129., f* -> i8, -128); + test_c!(126., f* -> i8, 126); + test!(128., f* -> i8, 127); + + // # i32 + // -2147483648. is i32::MIN (exactly) + test_c!(-2147483648., f* -> i32, i32::MIN); + // 2147483648. is i32::MAX rounded up + test!(2147483648., f32 -> i32, 2147483647); + // With 24 significand bits, floats with magnitude in [2^30 + 1, 2^31] are rounded to + // multiples of 2^7. Therefore, nextDown(round(i32::MAX)) is 2^31 - 128: + test_c!(2147483520., f32 -> i32, 2147483520); + // Similarly, nextUp(i32::MIN) is i32::MIN + 2^8 and nextDown(i32::MIN) is i32::MIN - 2^7 + test!(-2147483904., f* -> i32, i32::MIN); + test_c!(-2147483520., f* -> i32, -2147483520); + + // # u32 + // round(MAX) and nextUp(round(MAX)) + test_c!(4294967040., f* -> u32, 4294967040); + test!(4294967296., f* -> u32, 4294967295); + + // # u128 + #[cfg(not(target_os="emscripten"))] + { + // float->int: + test_c!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000); + // nextDown(f32::MAX) = 2^128 - 2 * 2^104 + const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; + test_c!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000); + } +} diff --git a/src/test/ui/numbers-arithmetic/shift-near-oflo.rs b/src/test/ui/numbers-arithmetic/shift-near-oflo.rs new file mode 100644 index 00000000000..939eb974612 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/shift-near-oflo.rs @@ -0,0 +1,100 @@ +// run-pass +// compile-flags: -C debug-assertions + +// Check that we do *not* overflow on a number of edge cases. +// (compare with test/run-fail/overflowing-{lsh,rsh}*.rs) + +fn main() { + test_left_shift(); + test_right_shift(); +} + +pub static mut HACK: i32 = 0; + +// Work around constant-evaluation +// The point of this test is to exercise the code generated for execution at runtime, +// `id` can never be flagged as a const fn by future aggressive analyses... +// due to the modification of the static +#[inline(never)] +fn id<T>(x: T) -> T { + unsafe { HACK += 1; } + x +} + +fn test_left_shift() { + // negative rhs can panic, but values in [0,N-1] are okay for iN + + macro_rules! tests { + ($iN:ty, $uN:ty, $max_rhs:expr, $expect_i:expr, $expect_u:expr) => { { + let x = (1 as $iN) << id(0); + assert_eq!(x, 1); + let x = (1 as $uN) << id(0); + assert_eq!(x, 1); + let x = (1 as $iN) << id($max_rhs); + assert_eq!(x, $expect_i); + let x = (1 as $uN) << id($max_rhs); + assert_eq!(x, $expect_u); + // high-order bits on LHS are silently discarded without panic. + let x = (3 as $iN) << id($max_rhs); + assert_eq!(x, $expect_i); + let x = (3 as $uN) << id($max_rhs); + assert_eq!(x, $expect_u); + } } + } + + let x = 1_i8 << id(0); + assert_eq!(x, 1); + let x = 1_u8 << id(0); + assert_eq!(x, 1); + let x = 1_i8 << id(7); + assert_eq!(x, std::i8::MIN); + let x = 1_u8 << id(7); + assert_eq!(x, 0x80); + // high-order bits on LHS are silently discarded without panic. + let x = 3_i8 << id(7); + assert_eq!(x, std::i8::MIN); + let x = 3_u8 << id(7); + assert_eq!(x, 0x80); + + // above is (approximately) expanded from: + tests!(i8, u8, 7, std::i8::MIN, 0x80_u8); + + tests!(i16, u16, 15, std::i16::MIN, 0x8000_u16); + tests!(i32, u32, 31, std::i32::MIN, 0x8000_0000_u32); + tests!(i64, u64, 63, std::i64::MIN, 0x8000_0000_0000_0000_u64); +} + +fn test_right_shift() { + // negative rhs can panic, but values in [0,N-1] are okay for iN + + macro_rules! tests { + ($iN:ty, $uN:ty, $max_rhs:expr, + $signbit_i:expr, $highbit_i:expr, $highbit_u:expr) => + { { + let x = (1 as $iN) >> id(0); + assert_eq!(x, 1); + let x = (1 as $uN) >> id(0); + assert_eq!(x, 1); + let x = ($highbit_i) >> id($max_rhs-1); + assert_eq!(x, 1); + let x = ($highbit_u) >> id($max_rhs); + assert_eq!(x, 1); + // sign-bit is carried by arithmetic right shift + let x = ($signbit_i) >> id($max_rhs); + assert_eq!(x, -1); + // low-order bits on LHS are silently discarded without panic. + let x = ($highbit_i + 1) >> id($max_rhs-1); + assert_eq!(x, 1); + let x = ($highbit_u + 1) >> id($max_rhs); + assert_eq!(x, 1); + let x = ($signbit_i + 1) >> id($max_rhs); + assert_eq!(x, -1); + } } + } + + tests!(i8, u8, 7, std::i8::MIN, 0x40_i8, 0x80_u8); + tests!(i16, u16, 15, std::i16::MIN, 0x4000_u16, 0x8000_u16); + tests!(i32, u32, 31, std::i32::MIN, 0x4000_0000_u32, 0x8000_0000_u32); + tests!(i64, u64, 63, std::i64::MIN, + 0x4000_0000_0000_0000_u64, 0x8000_0000_0000_0000_u64); +} diff --git a/src/test/ui/numbers-arithmetic/shift-various-types.rs b/src/test/ui/numbers-arithmetic/shift-various-types.rs new file mode 100644 index 00000000000..473bda3d76e --- /dev/null +++ b/src/test/ui/numbers-arithmetic/shift-various-types.rs @@ -0,0 +1,48 @@ +// run-pass +// Test that we can do shifts by any integral type. + + +struct Panolpy { + i8: i8, + i16: i16, + i32: i32, + i64: i64, + isize: isize, + + u8: u8, + u16: u16, + u32: u32, + u64: u64, + usize: usize, +} + +fn foo(p: &Panolpy) { + assert_eq!(22 >> p.i8, 11); + assert_eq!(22 >> p.i16, 11); + assert_eq!(22 >> p.i32, 11); + assert_eq!(22 >> p.i64, 11); + assert_eq!(22 >> p.isize, 11); + + assert_eq!(22 >> p.u8, 11); + assert_eq!(22 >> p.u16, 11); + assert_eq!(22 >> p.u32, 11); + assert_eq!(22 >> p.u64, 11); + assert_eq!(22 >> p.usize, 11); +} + +fn main() { + let p = Panolpy { + i8: 1, + i16: 1, + i32: 1, + i64: 1, + isize: 1, + + u8: 1, + u16: 1, + u32: 1, + u64: 1, + usize: 1, + }; + foo(&p) +} diff --git a/src/test/ui/numbers-arithmetic/shift.rs b/src/test/ui/numbers-arithmetic/shift.rs new file mode 100644 index 00000000000..2fc77928ef1 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/shift.rs @@ -0,0 +1,76 @@ +// run-pass +#![allow(non_upper_case_globals)] +#![allow(overflowing_literals)] + +// Testing shifts for various combinations of integers +// Issue #1570 + + +pub fn main() { + test_misc(); + test_expr(); + test_const(); +} + +fn test_misc() { + assert_eq!(1 << 1 << 1 << 1 << 1 << 1, 32); +} + +fn test_expr() { + let v10 = 10 as usize; + let v4 = 4 as u8; + let v2 = 2 as u8; + assert_eq!(v10 >> v2 as usize, v2 as usize); + assert_eq!(v10 << v4 as usize, 160 as usize); + + let v10 = 10 as u8; + let v4 = 4 as usize; + let v2 = 2 as usize; + assert_eq!(v10 >> v2 as usize, v2 as u8); + assert_eq!(v10 << v4 as usize, 160 as u8); + + let v10 = 10 as isize; + let v4 = 4 as i8; + let v2 = 2 as i8; + assert_eq!(v10 >> v2 as usize, v2 as isize); + assert_eq!(v10 << v4 as usize, 160 as isize); + + let v10 = 10 as i8; + let v4 = 4 as isize; + let v2 = 2 as isize; + assert_eq!(v10 >> v2 as usize, v2 as i8); + assert_eq!(v10 << v4 as usize, 160 as i8); + + let v10 = 10 as usize; + let v4 = 4 as isize; + let v2 = 2 as isize; + assert_eq!(v10 >> v2 as usize, v2 as usize); + assert_eq!(v10 << v4 as usize, 160 as usize); +} + +fn test_const() { + static r1_1: usize = 10_usize >> 2_usize; + static r2_1: usize = 10_usize << 4_usize; + assert_eq!(r1_1, 2 as usize); + assert_eq!(r2_1, 160 as usize); + + static r1_2: u8 = 10u8 >> 2_usize; + static r2_2: u8 = 10u8 << 4_usize; + assert_eq!(r1_2, 2 as u8); + assert_eq!(r2_2, 160 as u8); + + static r1_3: isize = 10 >> 2_usize; + static r2_3: isize = 10 << 4_usize; + assert_eq!(r1_3, 2 as isize); + assert_eq!(r2_3, 160 as isize); + + static r1_4: i8 = 10i8 >> 2_usize; + static r2_4: i8 = 10i8 << 4_usize; + assert_eq!(r1_4, 2 as i8); + assert_eq!(r2_4, 160 as i8); + + static r1_5: usize = 10_usize >> 2_usize; + static r2_5: usize = 10_usize << 4_usize; + assert_eq!(r1_5, 2 as usize); + assert_eq!(r2_5, 160 as usize); +} diff --git a/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs b/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs new file mode 100644 index 00000000000..6d0462b460e --- /dev/null +++ b/src/test/ui/numbers-arithmetic/signed-shift-const-eval.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(non_camel_case_types)] + + +enum test { thing = -5 >> 1_usize } +pub fn main() { + assert_eq!(test::thing as isize, -3); +} diff --git a/src/test/ui/numbers-arithmetic/u128-as-f32.rs b/src/test/ui/numbers-arithmetic/u128-as-f32.rs new file mode 100644 index 00000000000..bef7deb6276 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u128-as-f32.rs @@ -0,0 +1,49 @@ +// run-pass +// ignore-emscripten u128 not supported + +#![feature(test)] +#![deny(overflowing_literals)] +extern crate test; + +use std::f32; +use std::u128; +use test::black_box; + +macro_rules! test { + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({ + { + const X: $src_ty = $val; + const Y: $dest_ty = X as $dest_ty; + assert_eq!(Y, $expected, + "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + } + // black_box disables constant evaluation to test run-time conversions: + assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected, + "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + }); +} + +pub fn main() { + // nextDown(f32::MAX) = 2^128 - 2 * 2^104 + const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; + + // f32::MAX - 0.5 ULP and smaller should be rounded down + test!(0xfffffe00000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32); + test!(0xfffffe7fffffffffffffffffffffffff, u128 -> f32, SECOND_LARGEST_F32); + test!(0xfffffe80000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32); + // numbers within < 0.5 ULP of f32::MAX it should be rounded to f32::MAX + test!(0xfffffe80000000000000000000000001, u128 -> f32, f32::MAX); + test!(0xfffffeffffffffffffffffffffffffff, u128 -> f32, f32::MAX); + test!(0xffffff00000000000000000000000000, u128 -> f32, f32::MAX); + test!(0xffffff00000000000000000000000001, u128 -> f32, f32::MAX); + test!(0xffffff7fffffffffffffffffffffffff, u128 -> f32, f32::MAX); + // f32::MAX + 0.5 ULP and greater should be rounded to infinity + test!(0xffffff80000000000000000000000000, u128 -> f32, f32::INFINITY); + test!(0xffffff80000000f00000000000000000, u128 -> f32, f32::INFINITY); + test!(0xffffff87ffffffffffffffff00000001, u128 -> f32, f32::INFINITY); + + // u128->f64 should not be affected by the u128->f32 checks + test!(0xffffff80000000000000000000000000, u128 -> f64, + 340282356779733661637539395458142568448.0); + test!(u128::MAX, u128 -> f64, 340282366920938463463374607431768211455.0); +} diff --git a/src/test/ui/numbers-arithmetic/u128.rs b/src/test/ui/numbers-arithmetic/u128.rs new file mode 100644 index 00000000000..93940716323 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u128.rs @@ -0,0 +1,121 @@ +// run-pass +// ignore-emscripten u128 not supported + + +#![feature(test)] + +extern crate test; +use test::black_box as b; + +fn main() { + let x: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFF; + assert_eq!(0, !x); + assert_eq!(0, !x); + let y: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFE; + assert_eq!(!1, y); + assert_eq!(x, y | 1); + assert_eq!(0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFE, + y & + 0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFF); + let z: u128 = 0xABCD_EF; + assert_eq!(z * z, 0x734C_C2F2_A521); + assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(z + z + z + z, 0x2AF3_7BC); + let k: u128 = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + assert_eq!(k + k, 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420); + assert_eq!(0, k - k); + assert_eq!(0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k - z); + assert_eq!(0x1000_0000_0000_0000_0000_0000_0000_000, + k - 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42); + assert_eq!(0, k % 42); + assert_eq!(15, z % 42); + assert_eq!(0x169D_A8020_CEC18, k % 0x3ACB_FE49_FF24_AC); + assert_eq!(0x91A2_B3C4_D5E6_F7, k >> 65); + assert_eq!(0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65); + assert!(k > z); + assert!(y > k); + assert!(y < x); + assert_eq!(x as u64, !0); + assert_eq!(z as u64, 0xABCD_EF); + assert_eq!(k as u64, 0xFEDC_BA98_7654_3210); + assert_eq!(k as i128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!((z as f64) as u128, z); + assert_eq!((z as f32) as u128, z); + assert_eq!((z as f64 * 16.0) as u128, z * 16); + assert_eq!((z as f32 * 16.0) as u128, z * 16); + let l :u128 = 432 << 100; + assert_eq!((l as f32) as u128, l); + assert_eq!((l as f64) as u128, l); + // formatting + let j: u128 = 1 << 67; + assert_eq!("147573952589676412928", format!("{}", j)); + assert_eq!("80000000000000000", format!("{:x}", j)); + assert_eq!("20000000000000000000000", format!("{:o}", j)); + assert_eq!("10000000000000000000000000000000000000000000000000000000000000000000", + format!("{:b}", j)); + assert_eq!("340282366920938463463374607431768211455", + format!("{}", u128::max_value())); + assert_eq!("147573952589676412928", format!("{:?}", j)); + // common traits + assert_eq!(x, b(x.clone())); + // overflow checks + assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); + assert_eq!((k).checked_mul(k), None); + let l: u128 = b(u128::max_value() - 10); + let o: u128 = b(17); + assert_eq!(l.checked_add(b(11)), None); + assert_eq!(l.checked_sub(l), Some(0)); + assert_eq!(o.checked_sub(b(18)), None); + assert_eq!(b(1u128).checked_shl(b(127)), Some(1 << 127)); + assert_eq!(o.checked_shl(b(128)), None); + + // Test cases for all udivmodti4 branches. + // case "0X/0X" + assert_eq!(b(0x69545bd57727c050_u128) / + b(0x3283527a3350d88c_u128), + 2u128); + // case "0X/KX" + assert_eq!(b(0x0_8003c9c50b473ae6_u128) / + b(0x1_283e8838c30fa8f4_u128), + 0u128); + // case "K0/K0" + assert_eq!(b(0xc43f42a207978720_u128 << 64) / + b(0x098e62b74c23cf1a_u128 << 64), + 20u128); + // case "KK/K0" for power-of-two D. + assert_eq!(b(0xa9008fb6c9d81e42_0e25730562a601c8_u128) / + b(1u128 << 120), + 169u128); + // case "KK/K0" with N >= D (https://github.com/rust-lang/rust/issues/41228). + assert_eq!(b(0xe4d26e59f0640328_06da5b06efe83a41_u128) / + b(0x330fcb030ea4447c_u128 << 64), + 4u128); + assert_eq!(b(3u128 << 64 | 1) / + b(3u128 << 64), + 1u128); + // case "KK/K0" with N < D. + assert_eq!(b(0x6655c9fb66ca2884_e2d1dfd470158c62_u128) / + b(0xb35b667cab7e355b_u128 << 64), + 0u128); + // case "KX/0K" for power-of-two D. + assert_eq!(b(0x3e49dd84feb2df59_7b2f97d93a253969_u128) / + b(1u128 << 4), + 0x03e49dd84feb2df5_97b2f97d93a25396_u128); + // case "KX/0K" in general. + assert_eq!(b(0x299692b3a1dae5bd_6162e6f489d2620e_u128) / + b(0x900b6f027571d6f7_u128), + 0x49e95f54b0442578_u128); + // case "KX/KK" with N >= D. + assert_eq!(b(0xc7b889180b67b07d_bc1a3c88783d35b5_u128) / + b(0x1d7e69f53160b9e2_60074771e852f244_u128), + 6u128); + // case "KX/KK" with N < D. + assert_eq!(b(0x679289ac23bb334f_36144401cf882172_u128) / + b(0x7b0b271b64865f05_f54a7b72746c062f_u128), + 0u128); + + // iter-arithmetic traits + assert_eq!(10u128, [1u128, 2, 3, 4].iter().sum()); + assert_eq!(24u128, [1u128, 2, 3, 4].iter().product()); +} diff --git a/src/test/ui/numbers-arithmetic/u32-decr.rs b/src/test/ui/numbers-arithmetic/u32-decr.rs new file mode 100644 index 00000000000..d9e09781877 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u32-decr.rs @@ -0,0 +1,10 @@ +// run-pass + + + + +pub fn main() { + let mut word: u32 = 200000; + word = word - 1; + assert_eq!(word, 199999); +} diff --git a/src/test/ui/numbers-arithmetic/u8-incr-decr.rs b/src/test/ui/numbers-arithmetic/u8-incr-decr.rs new file mode 100644 index 00000000000..b16ec011d06 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u8-incr-decr.rs @@ -0,0 +1,19 @@ +// run-pass + + + + +// These constants were chosen because they aren't used anywhere +// in the rest of the generated code so they're easily grep-able. + +pub fn main() { + let mut x: u8 = 19; // 0x13 + + let mut y: u8 = 35; // 0x23 + + x = x + 7; // 0x7 + + y = y - 9; // 0x9 + + assert_eq!(x, y); +} diff --git a/src/test/ui/numbers-arithmetic/u8-incr.rs b/src/test/ui/numbers-arithmetic/u8-incr.rs new file mode 100644 index 00000000000..5242acf5b98 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/u8-incr.rs @@ -0,0 +1,15 @@ +// run-pass + + + + +pub fn main() { + let mut x: u8 = 12; + let y: u8 = 12; + x = x + 1; + x = x - 1; + assert_eq!(x, y); + // x = 14; + // x = x + 1; + +} diff --git a/src/test/ui/numbers-arithmetic/uint.rs b/src/test/ui/numbers-arithmetic/uint.rs new file mode 100644 index 00000000000..d219eae8f33 --- /dev/null +++ b/src/test/ui/numbers-arithmetic/uint.rs @@ -0,0 +1,7 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +pub fn main() { let _x: usize = 10 as usize; } |
