diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:20:10 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-10 07:20:10 +0000 |
commit | c79a57f0c887cc4a6d2f640b31d8ca02df54e1e0 (patch) | |
tree | 8a1df24ff4549f3ff836f4b7f89f4bbeff716fc4 | |
parent | 4fa15855ccdce8238c39081894e507043138543c (diff) | |
parent | d5fcc9aabd36be3a474596b2f7f51f6a080f5480 (diff) | |
download | cast-android13-mainline-os-statsd-release.tar.gz |
Snap for 8564071 from d5fcc9aabd36be3a474596b2f7f51f6a080f5480 to mainline-os-statsd-releaseaml_sta_331910000aml_sta_331811000aml_sta_331711010aml_sta_331610000aml_sta_331511000aml_sta_331410000aml_sta_331311000aml_sta_331010010aml_sta_330910000android13-mainline-os-statsd-release
Change-Id: I196cecd30e3aac386d97f30ac552019f9cb47fdc
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 67 | ||||
-rw-r--r-- | .travis.yml | 35 | ||||
-rw-r--r-- | Android.bp | 36 | ||||
-rw-r--r-- | CHANGELOG.md | 60 | ||||
-rw-r--r-- | Cargo.toml | 10 | ||||
-rw-r--r-- | Cargo.toml.orig | 13 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | TEST_MAPPING | 27 | ||||
-rw-r--r-- | build.rs | 8 | ||||
-rw-r--r-- | cargo2android.json | 5 | ||||
-rw-r--r-- | ci/install.sh | 9 | ||||
-rw-r--r-- | ci/script.sh | 43 | ||||
-rw-r--r-- | src/lib.rs | 73 | ||||
-rw-r--r-- | src/test.rs | 119 |
15 files changed, 277 insertions, 240 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 13f1433..f0b37b5 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "74cec5dcf2014ecfe7cb05837b147cbb4f49024e" + "sha1": "052288097de1846b938e854e27845a93a6f4b59d" } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4670b2b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +on: + push: + branches: [main] + pull_request: + branches: [main] + +name: Continuous integration + +jobs: + test : + name: Test Suite + runs-on: ubuntu-latest + + strategy: + matrix: + target: + - x86_64-unknown-linux-gnu + - i686-unknown-linux-musl + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: ${{ matrix.target }} + override: true + + - uses: actions-rs/cargo@v1 + with: + command: test + args: --target ${{ matrix.target }} + + - uses: actions-rs/cargo@v1 + with: + command: test + args: --target ${{ matrix.target }} --features std + + # only cargo build + msrv: + name: MSRV check + runs-on: ubuntu-latest + + strategy: + matrix: + target: + - x86_64-unknown-linux-gnu + - i686-unknown-linux-musl + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.31.0 + target: ${{ matrix.target }} + override: true + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --target ${{ matrix.target }} + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --target ${{ matrix.target }} --features std diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6da2fc0..0000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: rust - -matrix: - include: - # MSRV - - env: TARGET=x86_64-unknown-linux-gnu - rust: 1.13.0 - - # 32-bit - - env: TARGET=i686-unknown-linux-musl - - env: TARGET=x86_64-unknown-linux-gnu - -before_install: set -e - -install: - - bash ci/install.sh - -script: - - bash ci/script.sh - -after_script: set +e - -cache: cargo - -before_cache: - - chmod -R a+r $HOME/.cargo - -branches: - only: - - staging - - trying - -notifications: - email: - on_success: never @@ -1,4 +1,4 @@ -// This file is generated by cargo2android.py --run --device --dependencies. +// This file is generated by cargo2android.py --config cargo2android.json. // Do not modify this file as changes will be overridden on upgrade. package { @@ -37,22 +37,30 @@ license { ], } -rust_library { - name: "libcast", +rust_test { + name: "cast_test_src_lib", host_supported: true, crate_name: "cast", + cargo_env_compat: true, + cargo_pkg_version: "0.3.0", srcs: ["src/lib.rs"], - edition: "2015", - features: [ - "default", - "std", - ], - flags: [ - "--cfg stable_i128", + test_suites: ["general-tests"], + auto_gen_config: true, + test_options: { + unit_test: true, + }, + edition: "2018", + rustlibs: [ + "libquickcheck", ], } -// dependent_library ["feature_list"] -// rustc_version-0.2.3 -// semver-0.9.0 "default" -// semver-parser-0.7.0 +rust_library { + name: "libcast", + host_supported: true, + crate_name: "cast", + cargo_env_compat: true, + cargo_pkg_version: "0.3.0", + srcs: ["src/lib.rs"], + edition: "2018", +} diff --git a/CHANGELOG.md b/CHANGELOG.md index eb26758..6efacb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,62 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.3.0] - 2021-09-04 + +### Changed + +- (breaking change) The guaranteed MSRV is now 1.31.0. ([#40]) +- (breaking change) The `std` Cargo feature is no longer enabled by default. ([#44]) +- 128-bit integer support is now always available by default. ([#37]) + +[#37]: https://github.com/japaric/cast.rs/pull/37 +[#40]: https://github.com/japaric/cast.rs/pull/40 +[#44]: https://github.com/japaric/cast.rs/pull/44 + +### Fixed + +- fixed casting `255f32` to `u8` returning `Error::Overflow` ([#23], [#42]) +- fixed intent of promote-and-back tests ([#39], [#43]) + +[#23]: https://github.com/japaric/cast.rs/issues/23 +[#39]: https://github.com/japaric/cast.rs/issues/39 +[#42]: https://github.com/japaric/cast.rs/pull/42 +[#43]: https://github.com/japaric/cast.rs/pull/43 + +### Removed + +- (breaking change) The `x128` Cargo feature has been removed +- removed `rustc_version` and `semver` build dependencies ([#35], [#37]) +- removed all internal use of `unsafe` code ([#41]) + +[#35]: https://github.com/japaric/cast.rs/issues/35 +[#41]: https://github.com/japaric/cast.rs/pull/41 + +## [v0.2.7] - 2021-07-03 + +### Changed + +- Bumped `rustc_version` dependency to v0.4.0 + +## [v0.2.6] - 2021-05-15 + +### Changed + +- Bumped `rustc_version` dependency + +## [v0.2.5] - 2021-04-13 + +### Fixed + +- Build on platforms with 32-bit pointers + +## [v0.2.4] - 2021-04-11 - YANKED + ## [v0.2.3] - 2018-11-17 ### Changed -- Documented the guaranteed MRSV to be 1.13 +- Documented the guaranteed MSRV to be 1.13 - The `x128` feature now works on *stable* Rust 1.26+ ### Fixed @@ -47,7 +98,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Initial release -[Unreleased]: https://github.com/japaric/cast.rs/compare/v0.2.3...HEAD +[Unreleased]: https://github.com/japaric/cast.rs/compare/v0.3.0...HEAD +[v0.3.0]: https://github.com/japaric/cast.rs/compare/v0.2.7...v0.3.0 +[v0.2.7]: https://github.com/japaric/cast.rs/compare/v0.2.6...v0.2.7 +[v0.2.6]: https://github.com/japaric/cast.rs/compare/v0.2.5...v0.2.6 +[v0.2.5]: https://github.com/japaric/cast.rs/compare/v0.2.4...v0.2.5 +[v0.2.4]: https://github.com/japaric/cast.rs/compare/v0.2.3...v0.2.4 [v0.2.3]: https://github.com/japaric/cast.rs/compare/v0.2.2...v0.2.3 [v0.2.2]: https://github.com/japaric/cast.rs/compare/v0.2.1...v0.2.2 [v0.2.1]: https://github.com/japaric/cast.rs/compare/v0.2.0...v0.2.1 @@ -11,21 +11,17 @@ # will likely look very different (and much more reasonable) [package] +edition = "2018" name = "cast" -version = "0.2.3" +version = "0.3.0" authors = ["Jorge Aparicio <jorge@japaric.io>"] -build = "build.rs" description = "Ergonomic, checked cast functions for primitive types" documentation = "https://docs.rs/cast" keywords = ["checked", "cast", "primitive", "integer", "float"] license = "MIT OR Apache-2.0" repository = "https://github.com/japaric/cast.rs" [dev-dependencies.quickcheck] -version = "0.9.0" -[build-dependencies.rustc_version] -version = "0.2.3" +version = "1.0.3" [features] -default = ["std"] std = [] -x128 = [] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 6e95860..5776f6d 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,25 +1,18 @@ [package] authors = ["Jorge Aparicio <jorge@japaric.io>"] -build = "build.rs" description = "Ergonomic, checked cast functions for primitive types" documentation = "https://docs.rs/cast" keywords = ["checked", "cast", "primitive", "integer", "float"] license = "MIT OR Apache-2.0" name = "cast" repository = "https://github.com/japaric/cast.rs" -version = "0.2.3" +version = "0.3.0" +edition = "2018" [features] -# Assume we should use `std` unless asked to do otherwise. -default = ["std"] # Enable this to get a std::error::Error impl for convenient use with other # libraries. std = [] -# Enable this for i128/u128 support -x128 = [] - -[build-dependencies] -rustc_version = "0.2.3" [dev-dependencies] -quickcheck = "0.9.0" +quickcheck = "1.0.3" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/cast/cast-0.2.3.crate" + value: "https://static.crates.io/crates/cast/cast-0.3.0.crate" } - version: "0.2.3" + version: "0.3.0" license_type: NOTICE last_upgrade_date { - year: 2020 - month: 12 - day: 21 + year: 2021 + month: 9 + day: 22 } } diff --git a/TEST_MAPPING b/TEST_MAPPING new file mode 100644 index 0000000..209b12d --- /dev/null +++ b/TEST_MAPPING @@ -0,0 +1,27 @@ +// Generated by update_crate_tests.py for tests that depend on this crate. +{ + "imports": [ + { + "path": "external/rust/crates/base64" + }, + { + "path": "external/rust/crates/tinytemplate" + }, + { + "path": "external/rust/crates/tinyvec" + }, + { + "path": "external/rust/crates/unicode-xid" + } + ], + "presubmit": [ + { + "name": "cast_test_src_lib" + } + ], + "presubmit-rust": [ + { + "name": "cast_test_src_lib" + } + ] +} diff --git a/build.rs b/build.rs deleted file mode 100644 index 2aa9f5b..0000000 --- a/build.rs +++ /dev/null @@ -1,8 +0,0 @@ -extern crate rustc_version; - -fn main() { - let vers = rustc_version::version().unwrap(); - if vers.major == 1 && vers.minor >= 26 { - println!("cargo:rustc-cfg=stable_i128") - } -} diff --git a/cargo2android.json b/cargo2android.json new file mode 100644 index 0000000..d36fb44 --- /dev/null +++ b/cargo2android.json @@ -0,0 +1,5 @@ +{ + "device": true, + "run": true, + "tests": true +}
\ No newline at end of file diff --git a/ci/install.sh b/ci/install.sh deleted file mode 100644 index 3c41921..0000000 --- a/ci/install.sh +++ /dev/null @@ -1,9 +0,0 @@ -set -euxo pipefail - -main() { - if [ $TARGET != x86_64-unknown-linux-gnu ]; then - rustup target add $TARGET - fi -} - -main diff --git a/ci/script.sh b/ci/script.sh deleted file mode 100644 index 12b2619..0000000 --- a/ci/script.sh +++ /dev/null @@ -1,43 +0,0 @@ -set -euxo pipefail - -main() { - # not MSRV - if [ $TRAVIS_RUST_VERSION != 1.13.0 ]; then - cargo check --target $TARGET --no-default-features - - cargo test --features x128 --target $TARGET - cargo test --features x128 --target $TARGET --release - else - cargo build --target $TARGET --no-default-features - cargo build --target $TARGET - fi -} - -# fake Travis variables to be able to run this on a local machine -if [ -z ${TRAVIS_BRANCH-} ]; then - TRAVIS_BRANCH=staging -fi - -if [ -z ${TRAVIS_PULL_REQUEST-} ]; then - TRAVIS_PULL_REQUEST=false -fi - -if [ -z ${TRAVIS_RUST_VERSION-} ]; then - case $(rustc -V) in - *nightly*) - TRAVIS_RUST_VERSION=nightly - ;; - *beta*) - TRAVIS_RUST_VERSION=beta - ;; - *) - TRAVIS_RUST_VERSION=stable - ;; - esac -fi - -if [ -z ${TARGET-} ]; then - TARGET=$(rustc -Vv | grep host | cut -d ' ' -f2) -fi - -main @@ -4,8 +4,6 @@ //! Use these functions to perform a cast from any other numeric primitive: //! //! ``` -//! extern crate cast; -//! //! use cast::{u8, u16, Error}; //! //! # fn main() { @@ -28,8 +26,6 @@ //! be in the same scope: //! //! ``` -//! extern crate cast; -//! //! use std::u8; //! use cast::{u8, u16}; //! @@ -47,8 +43,6 @@ //! `cast` static method: //! //! ``` -//! extern crate cast; -//! //! use std::os::raw::c_ulonglong; //! // NOTE avoid shadowing `std::convert::From` - cf. rust-lang/rfcs#1311 //! use cast::From as _0; @@ -63,8 +57,6 @@ //! casted to `u32`. //! //! ``` -//! extern crate cast; -//! //! fn to_u32<T>(x: T) -> u32 //! // reads as: "where u32 can be casted from T with output u32" //! where u32: cast::From<T, Output=u32>, @@ -83,8 +75,9 @@ //! //! ## Minimal Supported Rust Version //! -//! This crate is guaranteed to compile on stable Rust 1.13 and up. It *might* compile on older -//! versions but that may change in any new patch release. +//! This crate is guaranteed to compile *as a dependency* on stable Rust 1.31 and up. +//! It's not guaranteed that `cargo test`-ing this crate follows the MSRV. +//! It *might* compile on older versions but that may change in any new patch release. //! //! ## Building without `std` //! @@ -95,14 +88,11 @@ //! cast = { version = "*", default-features = false } //! ``` -#![deny(missing_docs)] -#![deny(warnings)] #![allow(const_err)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(all(feature = "x128", not(stable_i128)), feature(i128_type, i128))] - -#[cfg(feature = "std")] -extern crate core; +#![deny(missing_docs)] +#![deny(unsafe_code)] +#![deny(warnings)] #[cfg(test)] #[macro_use] @@ -144,7 +134,7 @@ impl Error { } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.description_helper()) } } @@ -162,7 +152,7 @@ pub trait From<Src> { type Output; /// Checked cast from `Src` to `Self` - fn cast(Src) -> Self::Output; + fn cast(_: Src) -> Self::Output; } macro_rules! fns { @@ -181,7 +171,6 @@ macro_rules! fns { fns!(f32, f64, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); -#[cfg(feature = "x128")] fns!(i128, u128); /// `$dst` can hold any value of `$src` @@ -276,7 +265,7 @@ macro_rules! from_signed { /// From a float `$src` to an integer `$dst` macro_rules! from_float { - ($($src:ident, $usrc:ident => $($dst:ident),+);+;) => { + ($($src:ident => $($dst:ident),+);+;) => { $( $( impl From<$src> for $dst { @@ -292,13 +281,19 @@ macro_rules! from_float { src == $src::NEG_INFINITY { Error::Infinite } else if { - // we subtract 1 ULP (unit of least precision) here because some - // lossy conversions like `u64::MAX as f64` round *up* and we want - // to avoid this evaluating to false in that case - use core::mem::transmute; - let max = unsafe { - transmute::<_, $src>(transmute::<_, $usrc>($dst::MAX as $src) - 1) + // this '$dst::BITS' works on 1.31.0 (MSRV) + let dst_bits = core::mem::size_of::<$dst>() as u32 * 8; + let lossless = dst_bits < core::$src::MANTISSA_DIGITS; + + let max = if lossless { + $dst::MAX as $src + } else { + // we subtract 1 ULP (unit of least precision) here because some + // lossy conversions like `u64::MAX as f64` round *up* and we want + // to avoid the check below evaluating to false in that case + $src::from_bits(($dst::MAX as $src).to_bits() - 1) }; + src > max } { Error::Overflow @@ -325,7 +320,6 @@ macro_rules! from_float { /// From a float `$src` to an integer `$dst`, where $dst is large enough to contain /// all values of `$src`. We can't ever overflow here -#[cfg(feature = "x128")] macro_rules! from_float_dst { ($($src:ident => $($dst:ident),+);+;) => { $( @@ -359,7 +353,7 @@ macro_rules! from_float_dst { #[cfg(target_pointer_width = "32")] mod _32 { - use {Error, From}; + use crate::{Error, From}; // Signed promotion! { @@ -410,14 +404,14 @@ mod _32 { } from_float! { - f32, u32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; - f64, u64 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; + f32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; + f64 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; } } #[cfg(target_pointer_width = "64")] mod _64 { - use {Error, From}; + use crate::{Error, From}; // Signed promotion! { @@ -468,14 +462,13 @@ mod _64 { } from_float! { - f32, u32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; - f64, u64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; + f32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; + f64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; } } -#[cfg(feature = "x128")] mod _x128 { - use {Error, From}; + use crate::{Error, From}; // Signed promotion! { @@ -515,13 +508,13 @@ mod _x128 { } // Float - from_float! { - f32, u32 => i128; - f64, u64 => i128, u128; + from_float_dst! { + f32 => u128; } - from_float_dst! { - f32 => u128; + from_float! { + f32 => i128; + f64 => i128, u128; } } diff --git a/src/test.rs b/src/test.rs index 6b619ab..161a022 100644 --- a/src/test.rs +++ b/src/test.rs @@ -6,7 +6,7 @@ macro_rules! promote_and_back { $( mod $src { mod from { - use From; + use crate::From; $( quickcheck! { @@ -24,50 +24,32 @@ macro_rules! promote_and_back { #[cfg(target_pointer_width = "32")] promote_and_back! { - i8 => f32, f64, i16, i32, isize, i64 ; - i16 => f32, f64, i32, isize, i64 ; - i32 => f32, f64, i64 ; - isize => f32, f64, i64 ; - i64 => f32, f64 ; - u8 => f32, f64, i16, i32, isize, i64, u16, u32, usize, u64; - u16 => f32, f64, i32, isize, i64, u32, usize, u64; - u32 => f32, f64, i64, u64; - usize => f32, f64, i64, u64; - u64 => f32, f64 ; + i8 => f32, f64, i16, i32, isize, i64, i128 ; + i16 => f32, f64, i32, isize, i64, i128 ; + i32 => f64, i64, i128 ; + isize => f64, i64, i128 ; + i64 => i128 ; + u8 => f32, f64, i16, i32, isize, i64, i128, u16, u32, usize, u64, u128; + u16 => f32, f64, i32, isize, i64, i128, u32, usize, u64, u128; + u32 => f64, i64, i128, u64, u128; + usize => f64, i64, i128, u64, u128; + u64 => i128, u128; } #[cfg(target_pointer_width = "64")] promote_and_back! { - i8 => f32, f64, i16, i32, i64, isize ; - i16 => f32, f64, i32, i64, isize ; - i32 => f32, f64, i64, isize ; - i64 => f32, f64 ; - isize => f32, f64 ; - u8 => f32, f64, i16, i32, i64, isize, u16, u32, u64, usize; - u16 => f32, f64, i32, i64, isize, u32, u64, usize; - u32 => f32, f64, i64, isize, u64, usize; - u64 => f32, f64 ; - usize => f32, f64 ; + i8 => f32, f64, i16, i32, i64, isize, i128 ; + i16 => f32, f64, i32, i64, isize, i128 ; + i32 => f64, i64, isize, i128 ; + i64 => i128 ; + isize => i128 ; + u8 => f32, f64, i16, i32, i64, isize, i128, u16, u32, u64, usize, u128; + u16 => f32, f64, i32, i64, isize, i128, u32, u64, usize, u128; + u32 => f64, i64, isize, i128, u64, usize, u128; + u64 => i128, u128; + usize => i128, u128; } -// TODO uncomment this once quickcheck supports Arbitrary for i128/u128 -// https://github.com/BurntSushi/quickcheck/issues/162 -/*#[cfg(feature = "x128")] -promote_and_back! { - i8 => i128 ; - i16 => i128 ; - i32 => i128 ; - isize => i128 ; - i64 => i128 ; - i128 => f32, f64 ; - u8 => i128, u128; - u16 => i128, u128; - u32 => i128, u128; - usize => i128, u128; - u64 => i128, u128; - u128 => f32, f64 ; -}*/ - // If it's Ok to cast `src` to `$dst`, it must also be Ok to cast `dst` back to // `$src` macro_rules! symmetric_cast_between { @@ -78,7 +60,7 @@ macro_rules! symmetric_cast_between { mod and { use quickcheck::TestResult; - use From; + use crate::From; $( quickcheck! { @@ -110,27 +92,21 @@ symmetric_cast_between! { #[cfg(target_pointer_width = "64")] symmetric_cast_between! { - u8 => i8 ; - u16 => i8, i16 ; - u32 => i8, i16, i32 ; - u64 => i8, i16, i32, i64, isize; - usize => i8, i16, i32, i64, isize; + u8 => i8 ; + u16 => i8, i16 ; + u32 => i8, i16, i32 ; + u64 => i8, i16, i32, i64, isize ; + usize => i8, i16, i32, i64, isize ; + u128 => i8, i16, i32, i64, isize, i128; } -// TODO uncomment this once quickcheck supports Arbitrary for i128/u128 -// https://github.com/BurntSushi/quickcheck/issues/162 -/*#[cfg(feature = "x128")] -symmetric_cast_between! { - u128 => i8, i16, i32, isize, i64, i128; -}*/ - macro_rules! from_float { ($($src:ident => $($dst:ident),+);+;) => { $( mod $src { mod inf { mod to { - use {Error, From}; + use crate::{Error, From}; $( #[test] @@ -151,7 +127,7 @@ macro_rules! from_float { mod nan { mod to { - use {Error, From}; + use crate::{Error, From}; $( #[test] @@ -171,22 +147,13 @@ macro_rules! from_float { } from_float! { - f32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; - f64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; + f32 => i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize; + f64 => i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize; } -// TODO uncomment this once quickcheck supports Arbitrary for i128/u128 -// https://github.com/BurntSushi/quickcheck/issues/162 -/*#[cfg(feature = "x128")] -from_float! { - f32 => i128, u128; - f64 => i128, u128; -}*/ - #[test] -#[cfg(feature = "x128")] fn test_fl_conversion() { - use u128; + use crate::u128; assert_eq!(u128(42.0f32), Ok(42)); } @@ -219,3 +186,23 @@ fn gh15() { assert_eq!(super::u16(16_f32.exp2()), Err(super::Error::Overflow)); assert_eq!(super::u16(16_f64.exp2()), Err(super::Error::Overflow)); } + +#[test] +fn gh23_lossless_integer_max_min_to_float() { + // f32::MANTISSA_DIGITS = 24 + assert_eq!(Ok(u8::MAX), super::u8(255f32)); + assert_eq!(Ok(u16::MAX), super::u16(65_535f32)); + + // f64::MANTISSA_DIGITS = 53 + assert_eq!(Ok(u8::MAX), super::u8(255f64)); + assert_eq!(Ok(u16::MAX), super::u16(65_535f64)); + assert_eq!(Ok(u32::MAX), super::u32(4_294_967_295f64)); + + // also check negative values (not part of the original bug) + assert_eq!(Ok(i8::MIN), super::i8(-128f32)); + assert_eq!(Ok(i16::MIN), super::i16(-32_768f32)); + + assert_eq!(Ok(i8::MIN), super::i8(-128f64)); + assert_eq!(Ok(i16::MIN), super::i16(-32_768f64)); + assert_eq!(Ok(i32::MIN), super::i32(-2_147_483_648f64)); +} |