diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9a1eab14..05fe70e3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,8 +15,10 @@ jobs: rust: [ 1.31.0, # 2018! 1.32.0, # rand - 1.34.0, # quickcheck, has_try_from + 1.34.0, # has_try_from 1.36.0, # alloc + 1.40.0, # arbitrary + 1.46.0, # quickcheck stable, beta, nightly diff --git a/Cargo.toml b/Cargo.toml index 1c85c17e..2b6fcd4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,12 +57,12 @@ default-features = false [dependencies.quickcheck] optional = true -version = "0.9" +version = "1" default-features = false [dependencies.arbitrary] optional = true -version = "0.4" +version = "1" default-features = false [features] diff --git a/ci/big_quickcheck/Cargo.toml b/ci/big_quickcheck/Cargo.toml index c58f6d47..6002eedb 100644 --- a/ci/big_quickcheck/Cargo.toml +++ b/ci/big_quickcheck/Cargo.toml @@ -7,10 +7,10 @@ edition = "2018" [dependencies] num-integer = "0.1.42" num-traits = "0.2.11" -quickcheck_macros = "0.9" +quickcheck_macros = "1" [dependencies.quickcheck] -version = "0.9" +version = "1" default-features = false [dependencies.num-bigint] diff --git a/ci/big_quickcheck/src/lib.rs b/ci/big_quickcheck/src/lib.rs index 36d52877..4db72f8f 100644 --- a/ci/big_quickcheck/src/lib.rs +++ b/ci/big_quickcheck/src/lib.rs @@ -9,7 +9,7 @@ use num_bigint::{BigInt, BigUint}; use num_integer::Integer; use num_traits::{Num, One, Signed, Zero}; -use quickcheck::{QuickCheck, StdThreadGen, TestResult}; +use quickcheck::{Gen, QuickCheck, TestResult}; use quickcheck_macros::quickcheck; #[quickcheck] @@ -42,8 +42,8 @@ fn quickcheck_signed_eq_symmetric(a: BigInt, b: BigInt) -> bool { #[test] fn quickcheck_arith_primitive() { - let gen = StdThreadGen::new(usize::max_value()); - let mut qc = QuickCheck::with_gen(gen); + let gen = Gen::new(usize::max_value()); + let mut qc = QuickCheck::new().gen(gen); fn test_unsigned_add_primitive(a: usize, b: usize) -> TestResult { let actual = BigUint::from(a) + BigUint::from(b); @@ -79,11 +79,11 @@ fn quickcheck_arith_primitive() { } } - fn test_signed_sub_primitive(a: i128, b: i128) -> bool { - if b < a { - BigInt::from(a - b) == BigInt::from(a) - BigInt::from(b) - } else { - BigInt::from(b - a) == BigInt::from(b) - BigInt::from(a) + fn test_signed_sub_primitive(a: i128, b: i128) -> TestResult { + let actual = BigInt::from(a) - BigInt::from(b); + match a.checked_sub(b) { + None => TestResult::discard(), + Some(expected) => TestResult::from_bool(BigInt::from(expected) == actual), } } @@ -96,7 +96,7 @@ fn quickcheck_arith_primitive() { } fn test_signed_div_primitive(a: i128, b: i128) -> TestResult { - if b == 0 { + if b == 0 || (a == i128::MIN && b == -1) { TestResult::discard() } else { TestResult::from_bool(BigInt::from(a / b) == BigInt::from(a) / BigInt::from(b)) @@ -108,7 +108,7 @@ fn quickcheck_arith_primitive() { qc.quickcheck(test_unsigned_mul_primitive as fn(u64, u64) -> bool); qc.quickcheck(test_signed_mul_primitive as fn(i64, i64) -> bool); qc.quickcheck(test_unsigned_sub_primitive as fn(u128, u128) -> bool); - qc.quickcheck(test_signed_sub_primitive as fn(i128, i128) -> bool); + qc.quickcheck(test_signed_sub_primitive as fn(i128, i128) -> TestResult); qc.quickcheck(test_unsigned_div_primitive as fn(u128, u128) -> TestResult); qc.quickcheck(test_signed_div_primitive as fn(i128, i128) -> TestResult); } @@ -280,8 +280,8 @@ fn quickcheck_signed_conversion(a: BigInt, radix: u8) -> TestResult { #[test] fn quicktest_shift() { - let gen = StdThreadGen::new(usize::max_value()); - let mut qc = QuickCheck::with_gen(gen); + let gen = Gen::new(usize::max_value()); + let mut qc = QuickCheck::new().gen(gen); fn test_shr_unsigned(a: u64, shift: u8) -> TestResult { let shift = (shift % 64) as usize; //shift at most 64 bits @@ -317,8 +317,8 @@ fn quicktest_shift() { #[test] fn quickcheck_modpow() { - let gen = StdThreadGen::new(usize::max_value()); - let mut qc = QuickCheck::with_gen(gen); + let gen = Gen::new(usize::max_value()); + let mut qc = QuickCheck::new().gen(gen); fn simple_modpow(base: &BigInt, exponent: &BigInt, modulus: &BigInt) -> BigInt { assert!(!exponent.is_negative()); diff --git a/ci/test_full.sh b/ci/test_full.sh index 3b3b472d..cfada9fd 100755 --- a/ci/test_full.sh +++ b/ci/test_full.sh @@ -29,9 +29,9 @@ fi STD_FEATURES=(serde) check_version 1.32 && STD_FEATURES+=(rand) -check_version 1.34 && STD_FEATURES+=(quickcheck) check_version 1.36 && NO_STD_FEATURES=(serde rand) check_version 1.40 && STD_FEATURES+=(arbitrary) +check_version 1.46 && STD_FEATURES+=(quickcheck) echo "Testing supported features: ${STD_FEATURES[*]}" if [ -n "${NO_STD_FEATURES[*]}" ]; then echo " no_std supported features: ${NO_STD_FEATURES[*]}" diff --git a/src/bigint/arbitrary.rs b/src/bigint/arbitrary.rs index 08e05f9e..df66050e 100644 --- a/src/bigint/arbitrary.rs +++ b/src/bigint/arbitrary.rs @@ -1,11 +1,12 @@ use super::{BigInt, Sign}; +#[cfg(feature = "quickcheck")] use crate::std_alloc::Box; use crate::BigUint; #[cfg(feature = "quickcheck")] impl quickcheck::Arbitrary for BigInt { - fn arbitrary(g: &mut G) -> Self { + fn arbitrary(g: &mut quickcheck::Gen) -> Self { let positive = bool::arbitrary(g); let sign = if positive { Sign::Plus } else { Sign::Minus }; Self::from_biguint(sign, BigUint::arbitrary(g)) @@ -19,16 +20,20 @@ impl quickcheck::Arbitrary for BigInt { } #[cfg(feature = "arbitrary")] -impl arbitrary::Arbitrary for BigInt { +impl arbitrary::Arbitrary<'_> for BigInt { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { let positive = bool::arbitrary(u)?; let sign = if positive { Sign::Plus } else { Sign::Minus }; Ok(Self::from_biguint(sign, BigUint::arbitrary(u)?)) } - fn shrink(&self) -> Box> { - let sign = self.sign(); - let unsigned_shrink = self.data.shrink(); - Box::new(unsigned_shrink.map(move |x| BigInt::from_biguint(sign, x))) + fn arbitrary_take_rest(mut u: arbitrary::Unstructured<'_>) -> arbitrary::Result { + let positive = bool::arbitrary(&mut u)?; + let sign = if positive { Sign::Plus } else { Sign::Minus }; + Ok(Self::from_biguint(sign, BigUint::arbitrary_take_rest(u)?)) + } + + fn size_hint(depth: usize) -> (usize, Option) { + arbitrary::size_hint::and(bool::size_hint(depth), BigUint::size_hint(depth)) } } diff --git a/src/biguint/arbitrary.rs b/src/biguint/arbitrary.rs index 8a2eb9e9..6fa91c0f 100644 --- a/src/biguint/arbitrary.rs +++ b/src/biguint/arbitrary.rs @@ -1,11 +1,13 @@ use super::{biguint_from_vec, BigUint}; use crate::big_digit::BigDigit; -use crate::std_alloc::{Box, Vec}; +#[cfg(feature = "quickcheck")] +use crate::std_alloc::Box; +use crate::std_alloc::Vec; #[cfg(feature = "quickcheck")] impl quickcheck::Arbitrary for BigUint { - fn arbitrary(g: &mut G) -> Self { + fn arbitrary(g: &mut quickcheck::Gen) -> Self { // Use arbitrary from Vec biguint_from_vec(Vec::::arbitrary(g)) } @@ -17,12 +19,16 @@ impl quickcheck::Arbitrary for BigUint { } #[cfg(feature = "arbitrary")] -impl arbitrary::Arbitrary for BigUint { +impl arbitrary::Arbitrary<'_> for BigUint { fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { Ok(biguint_from_vec(Vec::::arbitrary(u)?)) } - fn shrink(&self) -> Box> { - Box::new(self.data.shrink().map(biguint_from_vec)) + fn arbitrary_take_rest(u: arbitrary::Unstructured<'_>) -> arbitrary::Result { + Ok(biguint_from_vec(Vec::::arbitrary_take_rest(u)?)) + } + + fn size_hint(depth: usize) -> (usize, Option) { + Vec::::size_hint(depth) } } diff --git a/src/lib.rs b/src/lib.rs index bfca016c..a4ab704a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,7 +94,7 @@ extern crate std; #[cfg(feature = "std")] mod std_alloc { pub(crate) use std::borrow::Cow; - #[cfg(any(feature = "quickcheck", feature = "arbitrary"))] + #[cfg(any(feature = "quickcheck"))] pub(crate) use std::boxed::Box; pub(crate) use std::string::String; pub(crate) use std::vec::Vec; @@ -107,7 +107,7 @@ extern crate alloc; #[cfg(not(feature = "std"))] mod std_alloc { pub(crate) use alloc::borrow::Cow; - #[cfg(any(feature = "quickcheck", feature = "arbitrary"))] + #[cfg(any(feature = "quickcheck"))] pub(crate) use alloc::boxed::Box; pub(crate) use alloc::string::String; pub(crate) use alloc::vec::Vec;