diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 62a84930..8ddca545 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,11 +9,7 @@ jobs: strategy: matrix: rust: [ - 1.31.0, # 2018! - 1.34.0, # has_try_from - 1.36.0, # alloc, rand - 1.40.0, # arbitrary - 1.46.0, # quickcheck + 1.60.0, # MSRV stable, beta, nightly diff --git a/.github/workflows/master.yaml b/.github/workflows/master.yaml index 68c4900d..034e3793 100644 --- a/.github/workflows/master.yaml +++ b/.github/workflows/master.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [1.31.0, stable] + rust: [1.60.0, stable] steps: - uses: actions/checkout@v4 - uses: actions/cache@v4 diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 787f9081..baac6484 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [1.31.0, stable] + rust: [1.60.0, stable] steps: - uses: actions/checkout@v4 - uses: actions/cache@v4 diff --git a/Cargo.toml b/Cargo.toml index 98350a5b..ba14b04f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,16 @@ version = "0.4.4" readme = "README.md" build = "build.rs" exclude = ["/ci/*", "/.github/*"] -edition = "2018" +edition = "2021" +rust-version = "1.60" [features] default = ["std"] std = ["num-integer/std", "num-traits/std"] +arbitrary = ["dep:arbitrary"] +quickcheck = ["dep:quickcheck"] +rand = ["dep:rand"] +serde = ["dep:serde"] [package.metadata.docs.rs] features = ["std", "serde", "rand", "quickcheck", "arbitrary"] @@ -68,6 +73,3 @@ default-features = false optional = true version = "1" default-features = false - -[build-dependencies] -autocfg = "1" diff --git a/README.md b/README.md index 21f7749a..cce185b9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![crate](https://img.shields.io/crates/v/num-bigint.svg)](https://crates.io/crates/num-bigint) [![documentation](https://docs.rs/num-bigint/badge.svg)](https://docs.rs/num-bigint) -[![minimum rustc 1.31](https://img.shields.io/badge/rustc-1.31+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html) +[![minimum rustc 1.60](https://img.shields.io/badge/rustc-1.60+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html) [![build status](https://github.com/rust-num/num-bigint/workflows/master/badge.svg)](https://github.com/rust-num/num-bigint/actions) Big integer types for Rust, `BigInt` and `BigUint`. @@ -42,7 +42,7 @@ Release notes are available in [RELEASES.md](RELEASES.md). ## Compatibility -The `num-bigint` crate is tested for rustc 1.31 and greater. +The `num-bigint` crate is tested for rustc 1.60 and greater. ## Alternatives @@ -52,10 +52,10 @@ table offers a brief comparison to a few alternatives. | Crate | License | Min rustc | Implementation | Features | | :--------------- | :------------- | :-------- | :------------- | :------- | -| **`num-bigint`** | MIT/Apache-2.0 | 1.31 | pure rust | dynamic width, number theoretical functions | +| **`num-bigint`** | MIT/Apache-2.0 | 1.60 | pure rust | dynamic width, number theoretical functions | | [`awint`] | MIT/Apache-2.0 | 1.66 | pure rust | fixed width, heap or stack, concatenation macros | -| [`bnum`] | MIT/Apache-2.0 | 1.61 | pure rust | fixed width, parity with Rust primitives including floats | -| [`crypto-bigint`] | MIT/Apache-2.0 | 1.57 | pure rust | fixed width, stack only | +| [`bnum`] | MIT/Apache-2.0 | 1.65 | pure rust | fixed width, parity with Rust primitives including floats | +| [`crypto-bigint`] | MIT/Apache-2.0 | 1.73 | pure rust | fixed width, stack only | | [`ibig`] | MIT/Apache-2.0 | 1.49 | pure rust | dynamic width, number theoretical functions | | [`rug`] | LGPL-3.0+ | 1.65 | bundles [GMP] via [`gmp-mpfr-sys`] | all the features of GMP, MPFR, and MPC | diff --git a/build.rs b/build.rs index 5d5406c9..278abf26 100644 --- a/build.rs +++ b/build.rs @@ -12,32 +12,16 @@ fn main() { .unwrap_or(false); if u64_digit { - autocfg::emit("u64_digit"); - } - - let ac = autocfg::new(); - let std = if ac.probe_sysroot_crate("std") { - "std" - } else { - "core" - }; - - if ac.probe_path(&format!("{}::convert::TryFrom", std)) { - autocfg::emit("has_try_from"); + println!("cargo:rustc-cfg=u64_digit"); } if let Ok(arch) = env::var("CARGO_CFG_TARGET_ARCH") { if arch == "x86_64" || arch == "x86" { - let digit = if u64_digit { "u64" } else { "u32" }; - - let addcarry = format!("{}::arch::{}::_addcarry_{}", std, arch, digit); - if ac.probe_path(&addcarry) { - autocfg::emit("use_addcarry"); - } + println!("cargo:rustc-cfg=use_addcarry"); } } - autocfg::rerun_path("build.rs"); + println!("cargo:rerun-if-changed=build.rs"); write_radix_bases().unwrap(); } @@ -54,7 +38,7 @@ fn main() { fn write_radix_bases() -> Result<(), Box> { let out_dir = env::var("OUT_DIR")?; let dest_path = Path::new(&out_dir).join("radix_bases.rs"); - let mut f = File::create(&dest_path)?; + let mut f = File::create(dest_path)?; for &bits in &[16, 32, 64] { let max = if bits < 64 { diff --git a/ci/rustup.sh b/ci/rustup.sh index 607901c0..6cfe67ef 100755 --- a/ci/rustup.sh +++ b/ci/rustup.sh @@ -5,6 +5,6 @@ set -ex ci=$(dirname $0) -for version in 1.31.0 1.34.0 1.36.0 1.40.0 1.46.0 stable beta nightly; do +for version in 1.60.0 stable beta nightly; do rustup run "$version" "$ci/test_full.sh" done diff --git a/ci/test_full.sh b/ci/test_full.sh index 0130964b..3924be90 100755 --- a/ci/test_full.sh +++ b/ci/test_full.sh @@ -3,7 +3,7 @@ set -e CRATE=num-bigint -MSRV=1.31 +MSRV=1.60 get_rust_version() { local array=($(rustc --version)); @@ -27,18 +27,15 @@ if ! check_version $MSRV ; then exit 1 fi -STD_FEATURES=(serde) -check_version 1.36 && STD_FEATURES+=(rand) -check_version 1.36 && NO_STD_FEATURES=(serde rand) -check_version 1.40 && STD_FEATURES+=(arbitrary) -check_version 1.46 && STD_FEATURES+=(quickcheck) +STD_FEATURES=(arbitrary quickcheck rand serde) +NO_STD_FEATURES=(serde rand) echo "Testing supported features: ${STD_FEATURES[*]}" if [ -n "${NO_STD_FEATURES[*]}" ]; then echo " no_std supported features: ${NO_STD_FEATURES[*]}" fi -# arbitrary 1.0.1 added const-generic arrays, which requires Rust 1.51 -check_version 1.51.0 || cargo update -p arbitrary --precise 1.0.0 +# arbitrary 1.1.4 started using array::from_fn +check_version 1.63.0 || cargo update -p arbitrary --precise 1.1.3 set -x @@ -82,22 +79,11 @@ fi case "${STD_FEATURES[*]}" in *serde*) ( cd ci/big_serde - # serde_test updated to 2021 edition after this version - check_version 1.56.0 || ( - cargo generate-lockfile - cargo update -p serde_test --precise 1.0.175 - ) cargo test ) ;;& *rand*) cargo test --manifest-path ci/big_rand/Cargo.toml ;;& *quickcheck*) ( cd ci/big_quickcheck - # quote and proc-macro2 updated to 2021 edition after these versions - check_version 1.56.0 || ( - cargo generate-lockfile - cargo update -p quote --precise 1.0.30 - cargo update -p proc-macro2 --precise 1.0.65 - ) cargo test ) ;;& esac diff --git a/src/bigint/convert.rs b/src/bigint/convert.rs index c4f888b9..74280ceb 100644 --- a/src/bigint/convert.rs +++ b/src/bigint/convert.rs @@ -2,12 +2,10 @@ use super::Sign::{self, Minus, NoSign, Plus}; use super::{BigInt, ToBigInt}; use crate::std_alloc::Vec; -#[cfg(has_try_from)] use crate::TryFromBigIntError; use crate::{BigUint, ParseBigIntError, ToBigUint}; use core::cmp::Ordering::{Equal, Greater, Less}; -#[cfg(has_try_from)] use core::convert::TryFrom; use core::str::{self, FromStr}; use num_traits::{FromPrimitive, Num, One, ToPrimitive, Zero}; @@ -109,7 +107,6 @@ impl ToPrimitive for BigInt { macro_rules! impl_try_from_bigint { ($T:ty, $to_ty:path) => { - #[cfg(has_try_from)] impl TryFrom<&BigInt> for $T { type Error = TryFromBigIntError<()>; @@ -119,7 +116,6 @@ macro_rules! impl_try_from_bigint { } } - #[cfg(has_try_from)] impl TryFrom for $T { type Error = TryFromBigIntError; @@ -313,7 +309,6 @@ impl ToBigUint for BigInt { } } -#[cfg(has_try_from)] impl TryFrom<&BigInt> for BigUint { type Error = TryFromBigIntError<()>; @@ -325,7 +320,6 @@ impl TryFrom<&BigInt> for BigUint { } } -#[cfg(has_try_from)] impl TryFrom for BigUint { type Error = TryFromBigIntError; diff --git a/src/biguint.rs b/src/biguint.rs index 1554eb0f..8303f957 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -906,10 +906,7 @@ impl BigUint { /// Returns the number of least-significant bits that are ones. pub fn trailing_ones(&self) -> u64 { if let Some(i) = self.data.iter().position(|&digit| !digit != 0) { - // XXX u64::trailing_ones() introduced in Rust 1.46, - // but we need to be compatible further back. - // Thanks to cuviper for this workaround. - let ones: u64 = (!self.data[i]).trailing_zeros().into(); + let ones: u64 = self.data[i].trailing_ones().into(); i as u64 * u64::from(big_digit::BITS) + ones } else { self.data.len() as u64 * u64::from(big_digit::BITS) diff --git a/src/biguint/convert.rs b/src/biguint/convert.rs index f19bc758..4d983676 100644 --- a/src/biguint/convert.rs +++ b/src/biguint/convert.rs @@ -10,11 +10,9 @@ use super::multiplication::mac_with_carry; use crate::big_digit::{self, BigDigit}; use crate::std_alloc::Vec; use crate::ParseBigIntError; -#[cfg(has_try_from)] use crate::TryFromBigIntError; use core::cmp::Ordering::{Equal, Greater, Less}; -#[cfg(has_try_from)] use core::convert::TryFrom; use core::mem; use core::str::FromStr; @@ -396,7 +394,6 @@ impl ToPrimitive for BigUint { macro_rules! impl_try_from_biguint { ($T:ty, $to_ty:path) => { - #[cfg(has_try_from)] impl TryFrom<&BigUint> for $T { type Error = TryFromBigIntError<()>; @@ -406,7 +403,6 @@ macro_rules! impl_try_from_biguint { } } - #[cfg(has_try_from)] impl TryFrom for $T { type Error = TryFromBigIntError; @@ -539,7 +535,6 @@ impl_biguint_from_uint!(usize); macro_rules! impl_biguint_try_from_int { ($T:ty, $from_ty:path) => { - #[cfg(has_try_from)] impl TryFrom<$T> for BigUint { type Error = TryFromBigIntError<()>; diff --git a/src/lib.rs b/src/lib.rs index 893b7473..6bf2edf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,7 +81,7 @@ //! //! ## Compatibility //! -//! The `num-bigint` crate is tested for rustc 1.31 and greater. +//! The `num-bigint` crate is tested for rustc 1.60 and greater. #![doc(html_root_url = "https://docs.rs/num-bigint/0.4")] #![warn(rust_2018_idioms)] @@ -183,13 +183,11 @@ impl Error for ParseBigIntError { } /// The error type returned when a checked conversion regarding big integer fails. -#[cfg(has_try_from)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct TryFromBigIntError { original: T, } -#[cfg(has_try_from)] impl TryFromBigIntError { fn new(original: T) -> Self { TryFromBigIntError { original } @@ -206,7 +204,7 @@ impl TryFromBigIntError { } } -#[cfg(all(feature = "std", has_try_from))] +#[cfg(feature = "std")] impl std::error::Error for TryFromBigIntError where T: fmt::Debug, @@ -216,7 +214,6 @@ where } } -#[cfg(has_try_from)] impl fmt::Display for TryFromBigIntError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.__description().fmt(f)