From 6c11441cf2e8ecf77fc725e33f1ce86c916da4f7 Mon Sep 17 00:00:00 2001 From: Alex Huszagh Date: Sun, 8 Sep 2024 19:31:27 -0500 Subject: [PATCH] Update CI and benchmark/test features. --- .github/workflows/Comprehensive.yml | 5 +- .github/workflows/Cross.yml | 69 ++++++++++--------- .github/workflows/Features.yml | 5 +- .github/workflows/OSX.yml | 33 ++------- .github/workflows/Simple.yml | 28 ++++++-- .github/workflows/Valgrind.yml | 5 +- CHANGELOG | 3 + README.md | 4 -- ci/check.sh | 2 +- ci/comprehensive.sh | 5 +- ci/test.sh | 3 +- docs/Development.md | 4 +- lexical-asm/src/lib.rs | 1 + lexical-benchmark/algorithm/Cargo.toml | 12 ++-- lexical-benchmark/algorithm/bigint.rs | 12 ++-- lexical-benchmark/algorithm/division.rs | 2 +- lexical-benchmark/input.rs | 11 ++- lexical-benchmark/parse-float/Cargo.toml | 8 ++- lexical-benchmark/parse-float/black_box.rs | 1 + lexical-benchmark/parse-integer/Cargo.toml | 7 +- lexical-benchmark/write-float/Cargo.toml | 5 +- lexical-benchmark/write-integer/Cargo.toml | 7 +- lexical-core/src/lib.rs | 2 +- lexical-parse-float/Cargo.toml | 2 +- lexical-parse-float/src/lib.rs | 2 +- lexical-parse-integer/Cargo.toml | 2 +- lexical-parse-integer/docs/Algorithm.md | 4 +- lexical-parse-integer/src/lib.rs | 2 +- lexical-util/etc/div128.py | 17 ++++- lexical-util/etc/step.py | 10 ++- lexical-util/src/div128.rs | 1 + lexical-util/src/iterator.rs | 1 - lexical-util/src/lib.rs | 2 +- lexical-util/src/not_feature_format.rs | 6 ++ lexical-util/tests/div128_tests.rs | 4 +- lexical-util/tests/iterator_tests.rs | 4 +- lexical-write-float/Cargo.toml | 2 +- lexical-write-float/docs/Algorithm.md | 2 +- .../etc/correctness/Cargo.toml | 2 +- lexical-write-float/src/algorithm.rs | 13 ++-- lexical-write-float/src/lib.rs | 2 +- lexical-write-float/src/table_dragonbox.rs | 2 + lexical-write-integer/Cargo.toml | 2 +- lexical-write-integer/src/lib.rs | 2 +- lexical-write-integer/tests/api_tests.rs | 49 ++++++------- lexical/src/lib.rs | 2 +- scripts/check.sh | 2 +- setup.cfg | 2 + 48 files changed, 205 insertions(+), 168 deletions(-) create mode 100644 setup.cfg diff --git a/.github/workflows/Comprehensive.yml b/.github/workflows/Comprehensive.yml index 762cc824..c30284b1 100644 --- a/.github/workflows/Comprehensive.yml +++ b/.github/workflows/Comprehensive.yml @@ -10,12 +10,11 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true components: rustfmt, clippy - run: ci/comprehensive.sh - run: ALL_FEATURES=1 ci/comprehensive.sh diff --git a/.github/workflows/Cross.yml b/.github/workflows/Cross.yml index 60c423f0..03cff06d 100644 --- a/.github/workflows/Cross.yml +++ b/.github/workflows/Cross.yml @@ -3,6 +3,8 @@ name: Cross on: [pull_request, workflow_dispatch] +# NOTE: Use older toolchains since there's bugs cross-compiling +# for some more recent architectures. jobs: cross: name: Rust ${{matrix.target}} @@ -24,41 +26,35 @@ jobs: - armv7-unknown-linux-gnueabihf - i686-unknown-linux-gnu - i686-unknown-linux-musl - - mips-unknown-linux-gnu - - mips64-unknown-linux-gnuabi64 - - mips64el-unknown-linux-gnuabi64 - - mipsel-unknown-linux-gnu # NOTE: This fails on cross v0.2.1, which is unusual since # manually invoking the failing tests with qemu-5.1.0 passes. #- powerpc64le-unknown-linux-gnu - - x86_64-unknown-linux-gnu + # NOTE: This has glibc linker issues. Restore later. + #- x86_64-unknown-linux-gnu - x86_64-unknown-linux-musl # Windows - x86_64-pc-windows-gnu steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: toolchain: stable target: ${{matrix.target}} - override: true - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: check - args: --target ${{matrix.target}} - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: test - args: --target ${{matrix.target}} - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: test - args: --target ${{matrix.target}} --features=radix,format,compact + - name: Install Cross + run: | + cargo install cross@0.2.5 + rustup toolchain add 1.65.0 + - name: Run Check + run: | + cross +1.65.0 check --target ${{matrix.target}} + - name: Run Simple Test + run: | + cross +1.65.0 test --target ${{matrix.target}} + - name: Run Feature Test + run: | + cross +1.65.0 test --target ${{matrix.target}} --features=radix,format,compact notest: name: Rust ${{matrix.target}} @@ -76,15 +72,24 @@ jobs: - x86_64-unknown-freebsd - x86_64-unknown-netbsd + # MIPS + # These targets have been removed from Tier 2 + # support, so we're using an older compiler and + # just checking they can be checked. + - mips-unknown-linux-gnu + - mips64-unknown-linux-gnuabi64 + - mips64el-unknown-linux-gnuabi64 + - mipsel-unknown-linux-gnu steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: toolchain: stable - target: ${{matrix.target}} - override: true - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: check - args: --target ${{matrix.target}} + - name: Install Cross + run: | + cargo install cross@0.2.5 + rustup toolchain add 1.65.0 + rustup toolchain install 1.65.0 --target ${{matrix.target}} --profile minimal --no-self-update + - name: Run check + run: | + cross +1.65.0 check --target ${{matrix.target}} diff --git a/.github/workflows/Features.yml b/.github/workflows/Features.yml index 9de95bb3..17ea1422 100644 --- a/.github/workflows/Features.yml +++ b/.github/workflows/Features.yml @@ -10,12 +10,11 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true components: rustfmt, clippy - run: ci/test.sh - run: NIGHTLY=1 NO_STD=1 ci/test.sh diff --git a/.github/workflows/OSX.yml b/.github/workflows/OSX.yml index 4c1f91b7..17e38786 100644 --- a/.github/workflows/OSX.yml +++ b/.github/workflows/OSX.yml @@ -5,34 +5,13 @@ on: jobs: cross: - name: Rust ${{matrix.target}} + name: Rust MacOS runs-on: macos-latest - strategy: - fail-fast: false - matrix: - target: - # iOS targets don't work, since rust-embedded doesn't provide images. - - x86_64-apple-darwin - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: toolchain: stable - target: ${{matrix.target}} - override: true - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: check - args: --target ${{matrix.target}} - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: test - args: --target ${{matrix.target}} - - uses: actions-rs/cargo@v1 - with: - use-cross: true - command: test - args: --target ${{matrix.target}} --features=radix,format,compact + - run: cargo check + - run: cargo test + - run: cargo test --features=radix,format,compact diff --git a/.github/workflows/Simple.yml b/.github/workflows/Simple.yml index 136b65ce..3329c976 100644 --- a/.github/workflows/Simple.yml +++ b/.github/workflows/Simple.yml @@ -4,18 +4,35 @@ on: [push, pull_request, workflow_dispatch] jobs: + build: + name: Rust ${{matrix.rust}} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [1.63.0] + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{matrix.rust}} + - run: cargo check + - run: cargo build + test: name: Rust ${{matrix.rust}} runs-on: ubuntu-latest strategy: fail-fast: false matrix: - rust: [1.51.0, stable, beta, nightly] + rust: [1.65.0, stable, beta, nightly] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - - uses: dtolnay/rust-toolchain@master + - uses: dtolnay/rust-toolchain@stable with: toolchain: ${{matrix.rust}} - run: cargo check @@ -28,11 +45,10 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true components: rustfmt, clippy - run: ci/check.sh diff --git a/.github/workflows/Valgrind.yml b/.github/workflows/Valgrind.yml index 9d269603..3730b38b 100644 --- a/.github/workflows/Valgrind.yml +++ b/.github/workflows/Valgrind.yml @@ -10,12 +10,11 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true - run: sudo apt-get update - run: sudo apt-get install valgrind - run: cargo +nightly install cargo-valgrind diff --git a/CHANGELOG b/CHANGELOG index be33173c..8877e304 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated the MSRV to 1.63.0 (1.65.0 for development). +### Removed +- Support for mips (MIPS), mipsel (MIPS LE), mips64 (MIPS64 BE), and mips64el (MIPS64 LE) on Linux. + ## [0.8.5] 2022-06-06 ### Changed - Fixed the partial integer parser to correctly return negative values if parsing partial input. diff --git a/README.md b/README.md index 5cbc2d00..ba9efdf0 100644 --- a/README.md +++ b/README.md @@ -319,10 +319,6 @@ lexical-core is tested on a wide variety of platforms, including big and small-e - aarch64 (ARM8v8-A) Linux, Android, and iOS. - armv7 (ARMv7-A) Linux, Android, and iOS. - arm (ARMv6) Linux, and Android. -- mips (MIPS) Linux. -- mipsel (MIPS LE) Linux. -- mips64 (MIPS64 BE) Linux. -- mips64el (MIPS64 LE) Linux. - powerpc (PowerPC) Linux. - powerpc64 (PPC64) Linux. - powerpc64le (PPC64LE) Linux. diff --git a/ci/check.sh b/ci/check.sh index b1fc9d38..b97a6ba8 100755 --- a/ci/check.sh +++ b/ci/check.sh @@ -4,7 +4,7 @@ set -ex # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` +script_dir=$(dirname "${BASH_SOURCE[0]}") cd "$script_dir"/.. scripts/check.sh diff --git a/ci/comprehensive.sh b/ci/comprehensive.sh index c20339a6..b223b567 100755 --- a/ci/comprehensive.sh +++ b/ci/comprehensive.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2086,SC2236 # Run a small subset of our comprehensive test suite. set -ex @@ -7,8 +8,8 @@ set -ex cargo --version # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` -script_home=`realpath "$script_dir"` +script_dir=$(dirname "${BASH_SOURCE[0]}") +script_home=$(realpath "$script_dir") cd "$script_home"/.. FEATURES= diff --git a/ci/test.sh b/ci/test.sh index 15836a44..d7251143 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -1,10 +1,11 @@ #!/bin/bash +# shellcheck disable=SC2086,SC2236 # Run main test suite. set -ex # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` +script_dir=$(dirname "${BASH_SOURCE[0]}") cd "$script_dir"/.. # Print our cargo version, for debugging. diff --git a/docs/Development.md b/docs/Development.md index 46b3def3..f48fd165 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -59,7 +59,7 @@ In addition, the following non-Rust dependencies must be installed: # Development Process -The [scripts](https://github.com/Alexhuszagh/rust-lexical/tree/main/scripts) directory contains numerous scripts for testing, fuzzing, analyzing, and formatting code. Since many development features are nightly-only, this ensures the proper compiler features are used. This requires a recent version of a nightly compiler (1.51.0+) installed via Rustup, which can be invoked as `cargo +nightly`. +The [scripts](https://github.com/Alexhuszagh/rust-lexical/tree/main/scripts) directory contains numerous scripts for testing, fuzzing, analyzing, and formatting code. Since many development features are nightly-only, this ensures the proper compiler features are used. This requires a recent version of a nightly compiler (1.65.0+) installed via Rustup, which can be invoked as `cargo +nightly`. - [asm.sh](https://github.com/Alexhuszagh/rust-lexical/blob/main/scripts/asm.sh): Emit assembly for numeric conversion routines, to identify performance regression. - [bench.sh](https://github.com/Alexhuszagh/rust-lexical/blob/main/scripts/bench.sh): Check the benchmarks compile and run. @@ -82,7 +82,7 @@ All PRs must pass the following checks: RUSTFLAGS="--deny warnings" cargo +nightly build --features=lint # Ensure all rustfmt and clippy checks pass. scripts/check.sh -# Ensure all tests pass with common feature combinations. +# Ensure all tests pass with common feature combinations. # Miri is too slow, so skip those tests for most commits. SKIP_MIRI=1 scripts/test.sh ``` diff --git a/lexical-asm/src/lib.rs b/lexical-asm/src/lib.rs index e7504ae9..77d244d9 100644 --- a/lexical-asm/src/lib.rs +++ b/lexical-asm/src/lib.rs @@ -83,6 +83,7 @@ pub struct ParseIntError { pub kind: IntErrorKind, } +#[allow(dead_code)] trait FromStrRadixHelper: PartialOrd + Copy { fn min_value() -> Self; fn max_value() -> Self; diff --git a/lexical-benchmark/algorithm/Cargo.toml b/lexical-benchmark/algorithm/Cargo.toml index 893db6f0..4149e39f 100644 --- a/lexical-benchmark/algorithm/Cargo.toml +++ b/lexical-benchmark/algorithm/Cargo.toml @@ -16,13 +16,17 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -fastrand = "1.4" +criterion = { version = "0.5.0", features = ["html_reports"] } +fastrand = "2.1.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [features] -default = ["std", "integers"] +default = ["std", "integers", "floats", "json"] std = ["lexical-util/std", "lexical-parse-float/std"] -integers = [] +integers = ["lexical-util/integers"] +floats = ["lexical-util/floats"] +json = [] [[bench]] name = "bigint" diff --git a/lexical-benchmark/algorithm/bigint.rs b/lexical-benchmark/algorithm/bigint.rs index 0506eff0..975b01d7 100644 --- a/lexical-benchmark/algorithm/bigint.rs +++ b/lexical-benchmark/algorithm/bigint.rs @@ -187,7 +187,7 @@ fn karatsuba_mul_algo(big: &mut bigint::Bigint, y: &[bigint::Limb]) { // GENERATOR #[inline(always)] -fn new_limb(rng: &Rng) -> bigint::Limb { +fn new_limb(rng: &mut Rng) -> bigint::Limb { if bigint::LIMB_BITS == 32 { rng.u32(..) as bigint::Limb } else { @@ -200,10 +200,10 @@ macro_rules! generator { $group.bench_function($name, |bench| { let mut big = bigint::Bigint::new(); let seed = fastrand::u64(..); - let rng = Rng::with_seed(seed); + let mut rng = Rng::with_seed(seed); bench.iter(|| { unsafe { big.data.set_len(0) }; - big.data.try_push(new_limb(&rng)).unwrap(); + big.data.try_push(new_limb(&mut rng)).unwrap(); // Don't go any higher than 300. $cb(&mut big, rng.u32(1..300)); black_box(&big); @@ -220,18 +220,18 @@ macro_rules! generator { $group.bench_function($name, |bench| { let mut big = bigint::Bigint::new(); let seed = fastrand::u64(..); - let rng = Rng::with_seed(seed); + let mut rng = Rng::with_seed(seed); bench.iter(|| { unsafe { big.data.set_len(0) }; // Don't go higher than 20, since we a minimum of 60 limbs. let count = rng.usize(1..20); for _ in 0..count { - big.data.try_push(new_limb(&rng)).unwrap(); + big.data.try_push(new_limb(&mut rng)).unwrap(); } let count = rng.usize(1..20); let mut vec: Vec = Vec::new(); for _ in 0..count { - vec.push(new_limb(&rng)); + vec.push(new_limb(&mut rng)); } // Don't go any higher than 300. diff --git a/lexical-benchmark/algorithm/division.rs b/lexical-benchmark/algorithm/division.rs index a58412a6..23769f8d 100644 --- a/lexical-benchmark/algorithm/division.rs +++ b/lexical-benchmark/algorithm/division.rs @@ -35,7 +35,7 @@ fn fast_div(v: u32) -> (u32, u32) { let max_precision = 14; let additional_precision = 5; - let left_end = (((1 << (max_precision + additional_precision)) + divisor - 1) / divisor) as u32; + let left_end = ((1 << (max_precision + additional_precision)) + divisor - 1) / divisor; let quotient = (v.wrapping_mul(left_end)) >> (max_precision + additional_precision); let remainder = v - divisor * quotient; diff --git a/lexical-benchmark/input.rs b/lexical-benchmark/input.rs index b43fc403..2936f439 100644 --- a/lexical-benchmark/input.rs +++ b/lexical-benchmark/input.rs @@ -395,16 +395,12 @@ macro_rules! to_lexical_generator { macro_rules! dtoa_generator { ($group:ident, $name:expr, $iter:expr) => {{ - use lexical_util::constants::BUFFER_SIZE; - let mut buffer = vec![b'0'; BUFFER_SIZE]; + let mut buffer = dtoa::Buffer::new(); $group.bench_function($name, |bench| { bench.iter(|| { $iter.for_each(|x| { - dtoa::write(&mut buffer, *x).unwrap(); + dtoa::format(&mut buffer, *x).unwrap(); black_box(&buffer); - unsafe { - buffer.set_len(0); - } // Way faster than Vec::clear(). }) }) }); @@ -502,7 +498,8 @@ macro_rules! parse_integer_generator { macro_rules! write_float_generator { ($group:ident, $type:expr, $iter:expr, $fmt:ident) => {{ to_lexical_generator!($group, concat!("write_", $type, "_lexical"), $iter); - dtoa_generator!($group, concat!("write_", $type, "_dtoa"), $iter); + // FIXME: Restore dtoa format later + //dtoa_generator!($group, concat!("write_", $type, "_dtoa"), $iter); ryu_generator!($group, concat!("write_", $type, "_ryu"), $iter, $fmt); fmt_generator!($group, concat!("write_", $type, "_fmt"), $iter); }}; diff --git a/lexical-benchmark/parse-float/Cargo.toml b/lexical-benchmark/parse-float/Cargo.toml index e63844f4..04348a25 100644 --- a/lexical-benchmark/parse-float/Cargo.toml +++ b/lexical-benchmark/parse-float/Cargo.toml @@ -16,8 +16,8 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -fastrand = "1.4" +criterion = { version = "0.5", features = ["html_reports"] } +fastrand = "2.1.0" lazy_static = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -30,7 +30,9 @@ power-of-two = ["lexical-util/power-of-two", "lexical-parse-float/power-of-two"] format = ["lexical-util/format", "lexical-parse-float/format"] compact = ["lexical-util/compact", "lexical-parse-float/compact"] asm = [] -floats = [] +nightly = ["lexical-parse-float/nightly"] +integers = ["lexical-util/integers"] +floats = ["lexical-util/floats"] json = [] [[bench]] diff --git a/lexical-benchmark/parse-float/black_box.rs b/lexical-benchmark/parse-float/black_box.rs index 70189536..19cbcf83 100644 --- a/lexical-benchmark/parse-float/black_box.rs +++ b/lexical-benchmark/parse-float/black_box.rs @@ -15,6 +15,7 @@ pub fn black_box(mut dummy: f64) -> f64 { // Optimized black box using the nicer assembly syntax. #[cfg(not(feature = "asm"))] +#[allow(forgetting_copy_types)] pub fn black_box(dummy: f64) -> f64 { unsafe { let x = core::ptr::read_volatile(&dummy); diff --git a/lexical-benchmark/parse-integer/Cargo.toml b/lexical-benchmark/parse-integer/Cargo.toml index 0e4b34ac..3bd97a93 100644 --- a/lexical-benchmark/parse-integer/Cargo.toml +++ b/lexical-benchmark/parse-integer/Cargo.toml @@ -16,8 +16,8 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -fastrand = "1.4" +criterion = { version = "0.5.0", features = ["html_reports"] } +fastrand = "2.1.0" lazy_static = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -29,7 +29,8 @@ radix = ["lexical-util/radix", "lexical-parse-integer/radix"] power-of-two = ["lexical-util/power-of-two", "lexical-parse-integer/power-of-two"] format = ["lexical-util/format", "lexical-parse-integer/format"] compact = ["lexical-util/compact", "lexical-parse-integer/compact"] -integers = [] +integers = ["lexical-util/integers"] +floats = ["lexical-util/floats"] json = [] [[bench]] diff --git a/lexical-benchmark/write-float/Cargo.toml b/lexical-benchmark/write-float/Cargo.toml index 33704bfb..1543c3c0 100644 --- a/lexical-benchmark/write-float/Cargo.toml +++ b/lexical-benchmark/write-float/Cargo.toml @@ -18,7 +18,7 @@ features = [] [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } dtoa = "1.0.9" -fastrand = "2.1.1" +fastrand = "2.1.0" lazy_static = "1" ryu = "1.0" serde = { version = "1.0", features = ["derive"] } @@ -31,7 +31,8 @@ radix = ["lexical-util/radix", "lexical-write-float/radix"] power-of-two = ["lexical-util/power-of-two", "lexical-write-float/power-of-two"] format = ["lexical-util/format", "lexical-write-float/format"] compact = ["lexical-util/compact", "lexical-write-float/compact"] -floats = [] +integers = ["lexical-util/integers"] +floats = ["lexical-util/floats"] json = [] [[bench]] diff --git a/lexical-benchmark/write-integer/Cargo.toml b/lexical-benchmark/write-integer/Cargo.toml index d17bade2..a0555bcf 100644 --- a/lexical-benchmark/write-integer/Cargo.toml +++ b/lexical-benchmark/write-integer/Cargo.toml @@ -16,9 +16,9 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.5.0", features = ["html_reports"] } itoa = { version = "0.4", features = ["i128"] } -fastrand = "1.4" +fastrand = "2.1.0" lazy_static = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -30,7 +30,8 @@ radix = ["lexical-util/radix", "lexical-write-integer/radix"] power-of-two = ["lexical-util/power-of-two", "lexical-write-integer/power-of-two"] format = ["lexical-util/format", "lexical-write-integer/format"] compact = ["lexical-util/compact", "lexical-write-integer/compact"] -integers = [] +integers = ["lexical-util/integers"] +floats = ["lexical-util/floats"] json = [] [[bench]] diff --git a/lexical-core/src/lib.rs b/lexical-core/src/lib.rs index 24973f9e..c602d40c 100644 --- a/lexical-core/src/lib.rs +++ b/lexical-core/src/lib.rs @@ -308,7 +308,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. //! //! [`write`]: crate::write diff --git a/lexical-parse-float/Cargo.toml b/lexical-parse-float/Cargo.toml index 84054be5..29d5c165 100644 --- a/lexical-parse-float/Cargo.toml +++ b/lexical-parse-float/Cargo.toml @@ -38,7 +38,7 @@ static_assertions = "1" # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" [features] default = ["std"] diff --git a/lexical-parse-float/src/lib.rs b/lexical-parse-float/src/lib.rs index fad4ecb3..cc5a9d1d 100644 --- a/lexical-parse-float/src/lib.rs +++ b/lexical-parse-float/src/lib.rs @@ -71,7 +71,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. //! //! # Design diff --git a/lexical-parse-integer/Cargo.toml b/lexical-parse-integer/Cargo.toml index f6fe8391..bbfff0e3 100644 --- a/lexical-parse-integer/Cargo.toml +++ b/lexical-parse-integer/Cargo.toml @@ -32,7 +32,7 @@ features = ["parse-integers"] # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" [features] default = ["std"] diff --git a/lexical-parse-integer/docs/Algorithm.md b/lexical-parse-integer/docs/Algorithm.md index 201d40c2..d8c83dc2 100644 --- a/lexical-parse-integer/docs/Algorithm.md +++ b/lexical-parse-integer/docs/Algorithm.md @@ -145,8 +145,8 @@ let min_value = 10u64.pow(max as u32 - 1); let max_value = i64::MAX as u64 + 1; let is_overflow = count > max || (count == max && ( - value < min_value - || value > max_value + value < min_value + || value > max_value || (!is_negative && value == max_value) )); ``` diff --git a/lexical-parse-integer/src/lib.rs b/lexical-parse-integer/src/lib.rs index 390d096f..f571a6c9 100644 --- a/lexical-parse-integer/src/lib.rs +++ b/lexical-parse-integer/src/lib.rs @@ -46,7 +46,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. //! //! # Design diff --git a/lexical-util/etc/div128.py b/lexical-util/etc/div128.py index d85a52ac..8ce3160f 100644 --- a/lexical-util/etc/div128.py +++ b/lexical-util/etc/div128.py @@ -18,6 +18,7 @@ u64_max = 2**64 - 1 u128_max = 2**128-1 + def is_valid(x): '''Determine if the power is valid.''' return ( @@ -25,6 +26,7 @@ def is_valid(x): and (u128_max / (x**2)) < x ) + def find_power(radix): '''Find the power of the divisor.''' @@ -33,6 +35,7 @@ def find_power(radix): start_power += 1 return start_power - 1 + def choose_multiplier(divisor, bits, is_signed=False): ''' Choose multiplier algorithm from: @@ -58,6 +61,7 @@ def choose_multiplier(divisor, bits, is_signed=False): return (m_high, sh_post, div_bits) + def fast_shift(divisor): ''' Check if we can do a fast shift for quick division as a smaller type. @@ -69,6 +73,7 @@ def fast_shift(divisor): n += 1 return n + def is_pow2(radix): '''Determine if the value is an exact power-of-two.''' return radix == 2**int(math.log2(radix)) @@ -86,6 +91,7 @@ def print_comment(): // in the function signatures of the functions they call. ''') + def print_pow2(radix): '''Print the function for a power-of-two radix.''' @@ -100,6 +106,7 @@ def print_pow2(radix): print('}') print('') + def print_fast(radix, divisor, fast_shr, factor, factor_shr): '''Print the function for the fastest division algorithm.''' @@ -110,6 +117,7 @@ def print_fast(radix, divisor, fast_shr, factor, factor_shr): print('}') print('') + def print_moderate(radix, divisor, factor, factor_shr): '''Print the function for the moderate division algorithm.''' @@ -119,6 +127,7 @@ def print_moderate(radix, divisor, factor, factor_shr): print('}') print('') + def print_slow(radix, divisor): '''Print the function for the slow division algorithm.''' @@ -129,6 +138,7 @@ def print_slow(radix, divisor): print('}') print('') + def divisor_constants(): '''Generate all the divisor constants for all radices.''' @@ -156,10 +166,11 @@ def divisor_constants(): # PYTHON LOGIC # This is the approach, in Python, for how to do this. + def u128_mulhi(x, y): '''Multiply 2 128-bit integers, and get the high 128 bits.''' - lo_mask = (1<<64) - 1 + lo_mask = (1 << 64) - 1 x_lo = x & lo_mask x_hi = x >> 64 y_lo = y & lo_mask @@ -174,17 +185,19 @@ def u128_mulhi(x, y): return x_hi * y_hi + high1 + high2 + def udiv128(n, divisor=10**19): '''Do an exact division using pre-computed values.''' factor, factor_shr, _ = choose_multiplier(divisor, 128) shr = fast_shift(divisor) - if n < (1<<(64 + shr)): + if n < (1 << (64 + shr)): quotient = (n >> shr) // (divisor >> shr) else: quotient = u128_mulhi(n, factor) >> factor_shr remainder = (n - quotient * divisor) return (quotient, remainder) + if __name__ == '__main__': divisor_constants() diff --git a/lexical-util/etc/step.py b/lexical-util/etc/step.py index 5ebd7fca..6c2cd328 100644 --- a/lexical-util/etc/step.py +++ b/lexical-util/etc/step.py @@ -16,10 +16,12 @@ UNSIGNED_MAX = [2**i for i in WIDTHS] SIGNED_MAX = [2**(i - 1) for i in WIDTHS] + def is_pow2(radix): '''Determine if the value is an exact power-of-two.''' return radix == 2**int(math.log2(radix)) + def find_power(max_value, radix): '''Find the power of the divisor.''' @@ -34,6 +36,7 @@ def find_power(max_value, radix): return (power, power + 1) return (power, power) + def print_comment(): '''Print the auto-generated comment''' @@ -47,6 +50,7 @@ def print_comment(): // recurse. Under normal circumstances, this will never be called. ''') + def print_power(radix): '''Print the minimum and maximum powers.''' @@ -59,7 +63,7 @@ def print_power(radix): for index in range(len(WIDTHS)): print(f' {WIDTHS[index]} if is_signed => {signed[index][1]},') print(f' {WIDTHS[index]} if !is_signed => {unsigned[index][1]},') - print(f' _ => 1,') + print(' _ => 1,') print(' }') print('}') print('') @@ -70,11 +74,12 @@ def print_power(radix): for index in range(len(WIDTHS)): print(f' {WIDTHS[index]} if is_signed => {signed[index][0]},') print(f' {WIDTHS[index]} if !is_signed => {unsigned[index][0]},') - print(f' _ => 1,') + print(' _ => 1,') print(' }') print('}') print('') + def main(): '''Generate all the step sizes for given radixes.''' @@ -82,5 +87,6 @@ def main(): for radix in range(2, 37): print_power(radix) + if __name__ == '__main__': main() diff --git a/lexical-util/src/div128.rs b/lexical-util/src/div128.rs index 50b0fa57..72e5cf77 100644 --- a/lexical-util/src/div128.rs +++ b/lexical-util/src/div128.rs @@ -47,6 +47,7 @@ use crate::assert::debug_assert_radix; use crate::mul::mulhi; /// Calculate a div/remainder algorithm optimized for power-of-two radixes. +/// /// This is trivial: the number of digits we process is `64 / log2(radix)`. /// Therefore, the `shr` is `log2(radix) * digits`, and the mask is just the /// lower `shr` bits of the digits. diff --git a/lexical-util/src/iterator.rs b/lexical-util/src/iterator.rs index 77e004e3..e9864f77 100644 --- a/lexical-util/src/iterator.rs +++ b/lexical-util/src/iterator.rs @@ -124,7 +124,6 @@ pub trait BytesIter<'a>: Iterator { /// This advances the internal state of the iterator. fn read_u32(&self) -> Option; - /// Try to read the next eight bytes as a u64 /// This advances the internal state of the iterator. fn read_u64(&self) -> Option; diff --git a/lexical-util/src/lib.rs b/lexical-util/src/lib.rs index 7f86fadb..b51646aa 100644 --- a/lexical-util/src/lib.rs +++ b/lexical-util/src/lib.rs @@ -32,7 +32,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. // We want to have the same safety guarantees as Rust core, diff --git a/lexical-util/src/not_feature_format.rs b/lexical-util/src/not_feature_format.rs index 224f2cc5..181b825d 100644 --- a/lexical-util/src/not_feature_format.rs +++ b/lexical-util/src/not_feature_format.rs @@ -566,3 +566,9 @@ impl NumberFormat { NumberFormatBuilder::rebuild(FORMAT) } } + +impl Default for NumberFormat { + fn default() -> Self { + Self::new() + } +} diff --git a/lexical-util/tests/div128_tests.rs b/lexical-util/tests/div128_tests.rs index f64d9548..9d6c5bf8 100644 --- a/lexical-util/tests/div128_tests.rs +++ b/lexical-util/tests/div128_tests.rs @@ -8,7 +8,7 @@ use proptest::{prop_assert_eq, proptest}; proptest! { #[test] #[cfg_attr(miri, ignore)] - fn u128_divrem_proptest(i in u128::min_value()..u128::max_value()) { + fn u128_divrem_proptest(i in u128::MIN..u128::MAX) { let (hi, lo) = u128_divrem(i, 10); let step = u64_step(10); let d = 10u128.pow(step as u32); @@ -19,7 +19,7 @@ proptest! { #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u128_divrem_radix_proptest(i in u128::min_value()..u128::max_value(), radix in 2u32..=36) { + fn u128_divrem_radix_proptest(i in u128::MIN..u128::MAX, radix in 2u32..=36) { // Simulate a const expr. let (hi, lo) = u128_divrem(i, radix); let step = u64_step(radix); diff --git a/lexical-util/tests/iterator_tests.rs b/lexical-util/tests/iterator_tests.rs index 45245652..813217f2 100644 --- a/lexical-util/tests/iterator_tests.rs +++ b/lexical-util/tests/iterator_tests.rs @@ -21,7 +21,7 @@ fn digits_iterator_test() { assert_eq!(iter.as_ptr(), digits.as_ptr()); assert_eq!(iter.is_consumed(), false); assert_eq!(iter.is_done(), false); - assert_eq!(u32::from_le(iter.read::().unwrap()), 0x34333231); + assert_eq!(u32::from_le(iter.read_u32().unwrap()), 0x34333231); assert_eq!(iter.length(), 5); assert_eq!(iter.cursor(), 0); assert_eq!(iter.current_count(), 0); @@ -39,7 +39,7 @@ fn digits_iterator_test() { let mut byte = digits.bytes::<{ STANDARD }>(); let mut iter = byte.integer_iter(); - assert_eq!(iter.read::(), None); + assert_eq!(iter.read_u64(), None); assert_eq!(iter.nth(4).unwrap(), &b'5'); assert_eq!(iter.as_slice(), &digits[digits.len()..]); assert_eq!(iter.as_ptr(), digits[digits.len()..].as_ptr()); diff --git a/lexical-write-float/Cargo.toml b/lexical-write-float/Cargo.toml index cc163854..0dcc76cc 100644 --- a/lexical-write-float/Cargo.toml +++ b/lexical-write-float/Cargo.toml @@ -39,7 +39,7 @@ approx = "0.5.0" # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" fraction = "0.15.0" [features] diff --git a/lexical-write-float/docs/Algorithm.md b/lexical-write-float/docs/Algorithm.md index 5b470553..6217d537 100644 --- a/lexical-write-float/docs/Algorithm.md +++ b/lexical-write-float/docs/Algorithm.md @@ -20,7 +20,7 @@ This also allows us to use a simple, highly-optimized algorithm rather than heav Compilers optimize division/remainder by a constant efficiently: the result is 2 multiplication instructions (on x86) and with similar efficiency for common architectures (32-bit ARM/THUMB, 64-bit ARM, PowerPC64, MIPS, etc.). In short, the difference in performance is <3%, and has no impact on the overall algorithm efficiency. -3. When truncating the representation, we still use round-nearest, tie-even for the rounding mode. +3. When truncating the representation, we still use round-nearest, tie-even for the rounding mode. In order to determine rounding, Dragonbox calculates boundaries (called endpoints) based on the interval for `w`, or the float we are trying to print. We therefore define that `w-` is the largest, positive float smaller than `w`, and `w+` is the smallest, positive float larger than `w`. For round-nearest rounding algorithms, the interval is bounded by the arithmetic mean (`I = [m−w,m+w]` where `m-w := (w- + w) / 2` and `m+w := (w + w+) / 2`). For round-to-zero, the interval is bounded by the next, larger float (`I = [w,w+)`), which can paradoxically cause unexpected round-up when creating truncated representations. Likewise, the round-to-∞ algorithm is bounded by the previous, smaller float (`I = (w-,w]`), which can paradoxically cause unexpected round-down when creating truncated representations. diff --git a/lexical-write-float/etc/correctness/Cargo.toml b/lexical-write-float/etc/correctness/Cargo.toml index 6842560a..bbf9c08b 100644 --- a/lexical-write-float/etc/correctness/Cargo.toml +++ b/lexical-write-float/etc/correctness/Cargo.toml @@ -20,7 +20,7 @@ version = "4.5" features = ["derive"] [dependencies] -fastrand = "2.1" +fastrand = "2.1.0" [features] std = ["lexical-util/std", "lexical-write-float/std"] diff --git a/lexical-write-float/src/algorithm.rs b/lexical-write-float/src/algorithm.rs index f3a1fb41..687c75fc 100644 --- a/lexical-write-float/src/algorithm.rs +++ b/lexical-write-float/src/algorithm.rs @@ -793,10 +793,11 @@ pub unsafe fn write_digits_u32(bytes: &mut [u8], mantissa: u32) -> usize { unsafe { mantissa.write_mantissa::(bytes) } } -/// Write the significant digits, when the significant digits cannot fit in a -/// 32-bit integer. Returns the number of digits written. Note that this -/// might not be the same as the number of digits in the mantissa, since -/// trailing zeros will be removed. +/// Write the significant digits, when the significant digits cannot fit in a 32-bit integer. +/// +/// Returns the number of digits written. Note that this might not be the +/// same as the number of digits in the mantissa, since trailing zeros will +/// be removed. /// /// # Safety /// @@ -985,7 +986,7 @@ pub const fn divide_by_pow10_32(n: u32, exp: u32) -> u32 { if exp == 2 { ((n as u64 * 1374389535) >> 37) as u32 } else { - let divisor = pow32(exp as u32, 10); + let divisor = pow32(exp, 10); n / divisor } } @@ -999,7 +1000,7 @@ pub const fn divide_by_pow10_64(n: u64, exp: u32, n_max: u64) -> u64 { if exp == 3 && n_max <= 15534100272597517998 { umul128_upper64(n, 2361183241434822607) >> 7 } else { - let divisor = pow64(exp as u32, 10); + let divisor = pow64(exp, 10); n / divisor } } diff --git a/lexical-write-float/src/lib.rs b/lexical-write-float/src/lib.rs index a21fca10..df47bf2e 100644 --- a/lexical-write-float/src/lib.rs +++ b/lexical-write-float/src/lib.rs @@ -54,7 +54,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. //! //! # Design diff --git a/lexical-write-float/src/table_dragonbox.rs b/lexical-write-float/src/table_dragonbox.rs index 930bc32d..ae381111 100644 --- a/lexical-write-float/src/table_dragonbox.rs +++ b/lexical-write-float/src/table_dragonbox.rs @@ -20,6 +20,7 @@ pub const LARGEST_F64_POW5: i32 = 326; pub const N64_POWERS_OF_FIVE: usize = (LARGEST_F64_POW5 - SMALLEST_F64_POW5 + 1) as usize; /// Pre-computed powers-of-5 for the dragonbox algorithm for f32. +/// /// This is very similar to the high bits for `DRAGONBOX64_POWERS_OF_FIVE`, /// with rounding obviously for the bits. pub const DRAGONBOX32_POWERS_OF_FIVE: [u64; N32_POWERS_OF_FIVE] = [ @@ -104,6 +105,7 @@ pub const DRAGONBOX32_POWERS_OF_FIVE: [u64; N32_POWERS_OF_FIVE] = [ ]; /// Pre-computed powers-of-5 for the dragonbox algorithm for f64. +/// /// This is very similar to the Lemire table, however, a few slight /// differences exist: this goes from `5^-292` to `5^326`, a different /// range than Lemire which goes from `5^-342 to 5^308`. diff --git a/lexical-write-integer/Cargo.toml b/lexical-write-integer/Cargo.toml index b87de1a0..a4d9887e 100644 --- a/lexical-write-integer/Cargo.toml +++ b/lexical-write-integer/Cargo.toml @@ -32,7 +32,7 @@ features = ["write-integers"] # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" [features] default = ["std"] diff --git a/lexical-write-integer/src/lib.rs b/lexical-write-integer/src/lib.rs index 60290ce6..6993188a 100644 --- a/lexical-write-integer/src/lib.rs +++ b/lexical-write-integer/src/lib.rs @@ -34,7 +34,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. //! //! # Design diff --git a/lexical-write-integer/tests/api_tests.rs b/lexical-write-integer/tests/api_tests.rs index 4c938b5f..79a8c437 100644 --- a/lexical-write-integer/tests/api_tests.rs +++ b/lexical-write-integer/tests/api_tests.rs @@ -16,6 +16,7 @@ use quickcheck::quickcheck; use util::from_radix; trait Roundtrip: ToLexical + ToLexicalWithOptions + FromStr { + #[allow(dead_code)] fn from_str_radix(src: &str, radix: u32) -> Result; } @@ -1251,157 +1252,157 @@ quickcheck! { proptest! { #[test] #[cfg_attr(miri, ignore)] - fn u8_proptest(i in u8::min_value()..u8::max_value()) { + fn u8_proptest(i in u8::MIN..u8::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i8_proptest(i in i8::min_value()..i8::max_value()) { + fn i8_proptest(i in i8::MIN..i8::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u16_proptest(i in u16::min_value()..u16::max_value()) { + fn u16_proptest(i in u16::MIN..u16::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i16_proptest(i in i16::min_value()..i16::max_value()) { + fn i16_proptest(i in i16::MIN..i16::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u32_proptest(i in u32::min_value()..u32::max_value()) { + fn u32_proptest(i in u32::MIN..u32::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i32_proptest(i in i32::min_value()..i32::max_value()) { + fn i32_proptest(i in i32::MIN..i32::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u64_proptest(i in u64::min_value()..u64::max_value()) { + fn u64_proptest(i in u64::MIN..u64::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i64_proptest(i in i64::min_value()..i64::max_value()) { + fn i64_proptest(i in i64::MIN..i64::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u128_proptest(i in u128::min_value()..u128::max_value()) { + fn u128_proptest(i in u128::MIN..u128::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i128_proptest(i in i128::min_value()..i128::max_value()) { + fn i128_proptest(i in i128::MIN..i128::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn usize_proptest(i in usize::min_value()..usize::max_value()) { + fn usize_proptest(i in usize::MIN..usize::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn isize_proptest(i in isize::min_value()..isize::max_value()) { + fn isize_proptest(i in isize::MIN..isize::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u8_proptest_radix(i in u8::min_value()..u8::max_value(), radix in 2u32..=36) { + fn u8_proptest_radix(i in u8::MIN..u8::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i8_proptest_radix(i in i8::min_value()..i8::max_value(), radix in 2u32..=36) { + fn i8_proptest_radix(i in i8::MIN..i8::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u16_proptest_radix(i in u16::min_value()..u16::max_value(), radix in 2u32..=36) { + fn u16_proptest_radix(i in u16::MIN..u16::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i16_proptest_radix(i in i16::min_value()..i16::max_value(), radix in 2u32..=36) { + fn i16_proptest_radix(i in i16::MIN..i16::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u32_proptest_radix(i in u32::min_value()..u32::max_value(), radix in 2u32..=36) { + fn u32_proptest_radix(i in u32::MIN..u32::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i32_proptest_radix(i in i32::min_value()..i32::max_value(), radix in 2u32..=36) { + fn i32_proptest_radix(i in i32::MIN..i32::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u64_proptest_radix(i in u64::min_value()..u64::max_value(), radix in 2u32..=36) { + fn u64_proptest_radix(i in u64::MIN..u64::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i64_proptest_radix(i in i64::min_value()..i64::max_value(), radix in 2u32..=36) { + fn i64_proptest_radix(i in i64::MIN..i64::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u128_proptest_radix(i in u128::min_value()..u128::max_value(), radix in 2u32..=36) { + fn u128_proptest_radix(i in u128::MIN..u128::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i128_proptest_radix(i in i128::min_value()..i128::max_value(), radix in 2u32..=36) { + fn i128_proptest_radix(i in i128::MIN..i128::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn usize_proptest_radix(i in usize::min_value()..usize::max_value(), radix in 2u32..=36) { + fn usize_proptest_radix(i in usize::MIN..usize::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn isize_proptest_radix(i in isize::min_value()..isize::max_value(), radix in 2u32..=36) { + fn isize_proptest_radix(i in isize::MIN..isize::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } } diff --git a/lexical/src/lib.rs b/lexical/src/lib.rs index bcdbb2ef..e9b393c6 100644 --- a/lexical/src/lib.rs +++ b/lexical/src/lib.rs @@ -246,7 +246,7 @@ //! //! # Version Support //! -//! The minimum, standard, required version is 1.51.0, for const generic +//! The minimum, standard, required version is 1.63.0, for const generic //! support. Older versions of lexical support older Rust versions. //! //! [`to_string`]: fn.to_string.html diff --git a/scripts/check.sh b/scripts/check.sh index 3b7da291..70fb5e7f 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -4,7 +4,7 @@ set -ex # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` +script_dir=$(dirname "${BASH_SOURCE[0]}") cd "$script_dir"/.. # Make sure we error on warnings, and don't format in-place. diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..c836869e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 110