diff --git a/crates/core_simd/tests/helpers/biteq.rs b/crates/core_simd/tests/helpers/biteq.rs deleted file mode 100644 index 9da2bdfce42e..000000000000 --- a/crates/core_simd/tests/helpers/biteq.rs +++ /dev/null @@ -1,120 +0,0 @@ -pub(crate) trait BitEq { - fn biteq(&self, other: &Self) -> bool; - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result; -} - -macro_rules! impl_biteq { - { integer impl BitEq for $($type:ty,)* } => { - $( - impl BitEq for $type { - fn biteq(&self, other: &Self) -> bool { - self == other - } - - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{:?} ({:x})", self, self) - } - } - )* - }; - { float impl BitEq for $($type:ty,)* } => { - $( - impl BitEq for $type { - fn biteq(&self, other: &Self) -> bool { - self.to_bits() == other.to_bits() - } - - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{:?} ({:x})", self, self.to_bits()) - } - } - )* - }; - { vector impl BitEq for $($type:ty,)* } => { - $( - impl BitEq for $type { - fn biteq(&self, other: &Self) -> bool { - let a: &[_] = self.as_ref(); - let b: &[_] = other.as_ref(); - if a.len() == b.len() { - a.iter().zip(b.iter()).fold(true, |value, (left, right)| { - value && left.biteq(right) - }) - } else { - false - } - } - - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - #[repr(transparent)] - struct Wrapper<'a, T: BitEq>(&'a T); - - impl core::fmt::Debug for Wrapper<'_, T> { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.0.fmt(f) - } - } - - let slice: &[_] = self.as_ref(); - - f.debug_list() - .entries(slice.iter().map(|x| Wrapper(x))) - .finish() - } - } - )* - }; -} - -impl_biteq! { - integer impl BitEq for - u8, u16, u32, u64, u128, usize, - i8, i16, i32, i64, i128, isize, -} - -impl_biteq! { - float impl BitEq for f32, f64, -} - -impl_biteq! { - vector impl BitEq for - core_simd::u8x8, core_simd::u8x16, core_simd::u8x32, core_simd::u8x64, - core_simd::i8x8, core_simd::i8x16, core_simd::i8x32, core_simd::i8x64, - core_simd::u16x4, core_simd::u16x8, core_simd::u16x16, core_simd::u16x32, - core_simd::i16x4, core_simd::i16x8, core_simd::i16x16, core_simd::i16x32, - core_simd::u32x2, core_simd::u32x4, core_simd::u32x8, core_simd::u32x16, - core_simd::i32x2, core_simd::i32x4, core_simd::i32x8, core_simd::i32x16, - core_simd::u64x2, core_simd::u64x4, core_simd::u64x8, - core_simd::i64x2, core_simd::i64x4, core_simd::i64x8, - core_simd::u128x2, core_simd::u128x4, - core_simd::i128x2, core_simd::i128x4, - core_simd::usizex2, core_simd::usizex4, core_simd::usizex8, - core_simd::isizex2, core_simd::isizex4, core_simd::isizex8, - core_simd::f32x2, core_simd::f32x4, core_simd::f32x8, core_simd::f32x16, - core_simd::f64x2, core_simd::f64x4, core_simd::f64x8, -} - -pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T); - -impl PartialEq for BitEqWrapper<'_, T> { - fn eq(&self, other: &Self) -> bool { - self.0.biteq(other.0) - } -} - -impl core::fmt::Debug for BitEqWrapper<'_, T> { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.0.fmt(f) - } -} - -macro_rules! assert_biteq { - { $a:expr, $b:expr } => { - { - use helpers::biteq::BitEqWrapper; - let a = $a; - let b = $b; - assert_eq!(BitEqWrapper(&a), BitEqWrapper(&b)); - } - } -} diff --git a/crates/core_simd/tests/helpers/mod.rs b/crates/core_simd/tests/helpers/mod.rs deleted file mode 100644 index 41b4fea9d95d..000000000000 --- a/crates/core_simd/tests/helpers/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[macro_use] -pub mod biteq; diff --git a/crates/core_simd/tests/mask_ops_impl/mod.rs b/crates/core_simd/tests/mask_ops_impl/mod.rs index 89f5e1b0b52a..99d735be2935 100644 --- a/crates/core_simd/tests/mask_ops_impl/mod.rs +++ b/crates/core_simd/tests/mask_ops_impl/mod.rs @@ -1,7 +1,3 @@ -#[macro_use] -#[path = "../helpers/mod.rs"] -mod helpers; - #[macro_use] mod mask_macros; diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index a4b26a1777af..58e80a8f277e 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -1,3 +1,6 @@ +/// Implements a test on a unary operation using proptest. +/// +/// Compares the vector operation to the equivalent scalar operation. #[macro_export] macro_rules! impl_unary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $scalar_fn:expr } => { @@ -16,6 +19,9 @@ macro_rules! impl_unary_op_test { }; } +/// Implements a test on a binary operation using proptest. +/// +/// Compares the vector operation to the equivalent scalar operation. #[macro_export] macro_rules! impl_binary_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => { @@ -70,6 +76,12 @@ macro_rules! impl_binary_op_test { }; } +/// Implements a test on a binary operation using proptest. +/// +/// Like `impl_binary_op_test`, but allows providing a function for rejecting particular inputs +/// (like the `proptest_assume` macro). +/// +/// Compares the vector operation to the equivalent scalar operation. #[macro_export] macro_rules! impl_binary_checked_op_test { { $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => { @@ -124,6 +136,7 @@ macro_rules! impl_binary_checked_op_test { }; } +/// Implement tests for signed integers. #[macro_export] macro_rules! impl_signed_tests { { $vector:ident, $scalar:tt } => { @@ -191,6 +204,8 @@ macro_rules! impl_signed_tests { impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); + + // Exclude Div and Rem panicking cases impl_binary_checked_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |x, y| y != 0 && !(x == Scalar::MIN && y == -1)); impl_binary_checked_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |x, y| y != 0 && !(x == Scalar::MIN && y == -1)); @@ -202,6 +217,7 @@ macro_rules! impl_signed_tests { } } +/// Implement tests for unsigned integers. #[macro_export] macro_rules! impl_unsigned_tests { { $vector:ident, $scalar:tt } => { @@ -220,6 +236,8 @@ macro_rules! impl_unsigned_tests { impl_binary_op_test!(Vector, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Vector, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Vector, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul); + + // Exclude Div and Rem panicking cases impl_binary_checked_op_test!(Vector, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |_, y| y != 0); impl_binary_checked_op_test!(Vector, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |_, y| y != 0); @@ -231,6 +249,7 @@ macro_rules! impl_unsigned_tests { } } +/// Implement tests for floating point numbers. #[macro_export] macro_rules! impl_float_tests { { $vector:ident, $scalar:tt, $int_scalar:tt } => { diff --git a/crates/test_helpers/src/array.rs b/crates/test_helpers/src/array.rs index 3953d0bbea5e..c64bfee4f2d1 100644 --- a/crates/test_helpers/src/array.rs +++ b/crates/test_helpers/src/array.rs @@ -1,3 +1,5 @@ +//! Generic-length array strategy. + // Adapted from proptest's array code // Copyright 2017 Jason Lingle diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs index 23aa7d4d908e..8c6280643803 100644 --- a/crates/test_helpers/src/biteq.rs +++ b/crates/test_helpers/src/biteq.rs @@ -1,3 +1,5 @@ +//! Compare numeric types by exact bit value. + pub trait BitEq { fn biteq(&self, other: &Self) -> bool; fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result; diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 253435dea336..a81713e865b7 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -6,6 +6,9 @@ pub mod wasm; #[macro_use] pub mod biteq; +/// Specifies the default strategy for testing a type. +/// +/// This strategy should be what "makes sense" to test. pub trait DefaultStrategy { type Strategy: proptest::strategy::Strategy; fn default_strategy() -> Self::Strategy; @@ -74,6 +77,7 @@ impl DefaultStrategy } } +/// Test a function that takes a single value. pub fn test_1( f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult, ) { @@ -81,6 +85,7 @@ pub fn test_1( runner.run(&A::default_strategy(), f).unwrap(); } +/// Test a function that takes two values. pub fn test_2( f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult, ) { @@ -92,6 +97,7 @@ pub fn test_2( fv: &dyn Fn(Vector) -> VectorResult, @@ -118,6 +124,7 @@ pub fn test_unary_elementwise { pub(crate) mod $name {