diff --git a/Cargo.lock b/Cargo.lock index 84f55aa43070..982e91e7d4cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -497,9 +497,12 @@ dependencies = [ [[package]] name = "cast" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" +checksum = "cc38c385bfd7e444464011bb24820f40dd1c76bcdfa1b78611cb7c2e5cafab75" +dependencies = [ + "rustc_version", +] [[package]] name = "cc" diff --git a/third_party/rust/cast/.cargo-checksum.json b/third_party/rust/cast/.cargo-checksum.json index dc2baf66d6b2..4e986cd23bd5 100644 --- a/third_party/rust/cast/.cargo-checksum.json +++ b/third_party/rust/cast/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"b24b688b552ea12f4ef03b2c76e17ecfb8c05104d4f494c47b698fd7d94d3e3a","Cargo.toml":"3908d7c2421a4071d3fdd4a7c7a44c1c8779cf9d229cec307fd1a2b96398aa60","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"005b3f9b4687364514bbaea2a25e96d54ce6a59277d157386e8259cbcae8e095","README.md":"006ae145ee89fa14a9d755b206ec2011a3687408e9d5fe3943f2448767b01d62","ci/install.sh":"f3965bda34345579d0799ca2e581efd7ae51f3191aa9203b018f4ade8b986b15","ci/script.sh":"0f8329c7345731c12f35a392e8deeb2e265b75f107c5aca6eed584096896737f","src/lib.rs":"52418274bc4ec5c59dba1885de7324157e677739a2c9624b5d462d5d4c77b5e3","src/test.rs":"58ea38d755d5eae72b1df29fc602483fef888a111bb2e9c3a219e2b2a1ed222f"},"package":"926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"} \ No newline at end of file +{"files":{"CHANGELOG.md":"e55cdd51726a3865d07424514fdba6b1b465136c7906252da48be5d2e76e52f1","Cargo.toml":"c284d65591f858bdb358246f46638e481cb0e09f8cd59ff5d0e0650f6ed4f6dc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"005b3f9b4687364514bbaea2a25e96d54ce6a59277d157386e8259cbcae8e095","README.md":"006ae145ee89fa14a9d755b206ec2011a3687408e9d5fe3943f2448767b01d62","build.rs":"96d02915f44c85ae32515ae73b217fc24bfd1f4aa124d4e8a0f93828bb2b50b7","ci/install.sh":"e295d97db9e12ac6ee3e523e4597ad58fedcca2b8aa3a21302951ad2327b88a9","ci/script.sh":"964e510d5af745d6b86d68d5b95760db4a94112ace0a1027602e6e8baadec8a5","src/lib.rs":"2c58d1191fa96491fa169ac37a561f7bad4dc8c063c63a3bab88985632aff01c","src/test.rs":"314d5236c0a34068a4e0ba0ec8f3fbfaeac61cae60a9725f2584266d00a863a3"},"package":"cc38c385bfd7e444464011bb24820f40dd1c76bcdfa1b78611cb7c2e5cafab75"} \ No newline at end of file diff --git a/third_party/rust/cast/CHANGELOG.md b/third_party/rust/cast/CHANGELOG.md index d0019641b13a..54f04d36dac7 100644 --- a/third_party/rust/cast/CHANGELOG.md +++ b/third_party/rust/cast/CHANGELOG.md @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [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 +- The `x128` feature now works on *stable* Rust 1.26+ + +### Fixed + +- Overflow and underflow checks when casting a float to an unsigned integer + ## [v0.2.2] - 2017-05-07 ### Fixed @@ -36,7 +55,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Initial release -[Unreleased]: https://github.com/japaric/cast.rs/compare/v0.2.2...HEAD +[Unreleased]: https://github.com/japaric/cast.rs/compare/v0.2.3...HEAD +[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 [v0.2.0]: https://github.com/japaric/cast.rs/compare/v0.1.0...v0.2.0 diff --git a/third_party/rust/cast/Cargo.toml b/third_party/rust/cast/Cargo.toml index 3534ad53a596..c9644e4eccf7 100644 --- a/third_party/rust/cast/Cargo.toml +++ b/third_party/rust/cast/Cargo.toml @@ -1,21 +1,32 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + [package] +edition = "2018" +name = "cast" +version = "0.2.5" authors = ["Jorge Aparicio "] +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.2" +[dev-dependencies.quickcheck] +version = "0.9.0" +[build-dependencies.rustc_version] +version = "0.2.3" [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 = [] - -[dev-dependencies] -quickcheck = "0.4.1" diff --git a/third_party/rust/cast/build.rs b/third_party/rust/cast/build.rs new file mode 100644 index 000000000000..2aa9f5bc8b45 --- /dev/null +++ b/third_party/rust/cast/build.rs @@ -0,0 +1,8 @@ +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/third_party/rust/cast/ci/install.sh b/third_party/rust/cast/ci/install.sh index 9ce763248694..3c41921194d5 100644 --- a/third_party/rust/cast/ci/install.sh +++ b/third_party/rust/cast/ci/install.sh @@ -1,21 +1,9 @@ -set -ex +set -euxo pipefail main() { - curl https://sh.rustup.rs -sSf | \ - sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION - - local latest=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \ - | cut -d/ -f3 \ - | grep -E '^v[0-9.]+$' \ - | sort --version-sort \ - | tail -n1) - - curl -LSfs https://japaric.github.io/trust/install.sh | \ - sh -s -- \ - --force \ - --git japaric/cross \ - --tag $latest \ - --target x86_64-unknown-linux-gnu + if [ $TARGET != x86_64-unknown-linux-gnu ]; then + rustup target add $TARGET + fi } main diff --git a/third_party/rust/cast/ci/script.sh b/third_party/rust/cast/ci/script.sh index 47156383284b..12b2619742d9 100644 --- a/third_party/rust/cast/ci/script.sh +++ b/third_party/rust/cast/ci/script.sh @@ -1,14 +1,43 @@ -set -ex +set -euxo pipefail main() { - cross test --target $TARGET - cross test --target $TARGET --release + # not MSRV + if [ $TRAVIS_RUST_VERSION != 1.13.0 ]; then + cargo check --target $TARGET --no-default-features - [ "$TRAVIS_RUST_VERSION" -eq "nightly" ] && cross test --feature x128 --target $TARGET - [ "$TRAVIS_RUST_VERSION" -eq "nightly" ] && cross test --feature x128 --target $TARGET --release - - cross test --no-default-features --target $TARGET - cross test --no-default-features --target $TARGET --release + 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 diff --git a/third_party/rust/cast/src/lib.rs b/third_party/rust/cast/src/lib.rs index bccb921385e3..58d60efd40a8 100644 --- a/third_party/rust/cast/src/lib.rs +++ b/third_party/rust/cast/src/lib.rs @@ -81,6 +81,11 @@ //! # } //! ``` //! +//! ## 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. +//! //! ## Building without `std` //! //! This crate can be used without Rust's `std` crate by declaring it as @@ -93,20 +98,17 @@ #![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_attr(feature = "x128", feature(i128_type, i128))] -#[cfg(feature = "std")] -extern crate core; #[cfg(test)] #[macro_use] extern crate quickcheck; use core::fmt; -#[cfg(feature="std")] +#[cfg(feature = "std")] use std::error; #[cfg(test)] @@ -141,12 +143,12 @@ 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()) } } -#[cfg(feature="std")] +#[cfg(feature = "std")] impl error::Error for Error { fn description(&self) -> &str { self.description_helper() @@ -159,7 +161,7 @@ pub trait From { type Output; /// Checked cast from `Src` to `Self` - fn cast(Src) -> Self::Output; + fn cast(_: Src) -> Self::Output; } macro_rules! fns { @@ -273,7 +275,7 @@ macro_rules! from_signed { /// From a float `$src` to an integer `$dst` macro_rules! from_float { - ($($src:ident => $($dst:ident),+);+;) => { + ($($src:ident, $usrc:ident => $($dst:ident),+);+;) => { $( $( impl From<$src> for $dst { @@ -288,11 +290,29 @@ macro_rules! from_float { } else if src == $src::INFINITY || 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) + }; + src > max + } { + Error::Overflow + } else if $dst::MIN == 0 { + // when casting to unsigned integer, negative values close to 0 but + // larger than 1.0 should be truncated to 0; this behavior matches + // casting from a float to a signed integer + if src <= -1.0 { + Error::Underflow + } else { + return Ok(src as $dst); + } } else if src < $dst::MIN as $src { Error::Underflow - } else if src > $dst::MAX as $src { - Error::Overflow - } else { + } else { return Ok(src as $dst); }) } @@ -304,12 +324,13 @@ 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),+);+;) => { $( $( impl From<$src> for $dst { - type Output = Result<$dst, Error>; + type Output = Result<$dst, Error>; #[inline] #[allow(unused_comparisons)] @@ -321,7 +342,7 @@ macro_rules! from_float_dst { } else if src == $src::INFINITY || src == $src::NEG_INFINITY { Error::Infinite - } else if ($dst::MIN == 0) && src < 0.0 { + } else if ($dst::MIN == 0) && src <= -1.0 { Error::Underflow } else { return Ok(src as $dst); @@ -337,7 +358,7 @@ macro_rules! from_float_dst { #[cfg(target_pointer_width = "32")] mod _32 { - use {Error, From}; + use crate::{Error, From}; // Signed promotion! { @@ -388,14 +409,14 @@ mod _32 { } from_float! { - f32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; - f64 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; + f32, u32 => i8, i16, i32, isize, i64, u8, u16, u32, usize, u64; + f64, u64 => 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! { @@ -446,14 +467,14 @@ mod _64 { } 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, u32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; + f64, u64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize; } } #[cfg(feature = "x128")] mod _x128 { - use {Error, From}; + use crate::{Error, From}; // Signed promotion! { @@ -494,11 +515,12 @@ mod _x128 { // Float from_float! { - f32 => i128; - f64 => i128, u128; + f32, u32 => i128; + f64, u64 => i128, u128; } + from_float_dst! { - f32 => u128; + f32 => u128; } } diff --git a/third_party/rust/cast/src/test.rs b/third_party/rust/cast/src/test.rs index 8e34f9c4bc8e..da890ed8c29b 100644 --- a/third_party/rust/cast/src/test.rs +++ b/third_party/rust/cast/src/test.rs @@ -6,7 +6,7 @@ macro_rules! promote_and_back { $( mod $src { mod from { - use From; + use crate::From; $( quickcheck! { @@ -78,7 +78,7 @@ macro_rules! symmetric_cast_between { mod and { use quickcheck::TestResult; - use From; + use crate::From; $( quickcheck! { @@ -130,7 +130,7 @@ macro_rules! from_float { mod $src { mod inf { mod to { - use {Error, From}; + use crate::{Error, From}; $( #[test] @@ -151,7 +151,7 @@ macro_rules! from_float { mod nan { mod to { - use {Error, From}; + use crate::{Error, From}; $( #[test] @@ -189,3 +189,33 @@ fn test_fl_conversion() { use u128; assert_eq!(u128(42.0f32), Ok(42)); } + +#[test] +fn gh16() { + assert_eq!(super::u64(-0.01_f64), Ok(0)); + assert_eq!(super::u64(-0.99_f32), Ok(0)); + + assert_eq!(super::u32(-0.99_f64), Ok(0)); + assert_eq!(super::u32(-0.01_f32), Ok(0)); + + assert_eq!(super::u64(0.01_f64), Ok(0)); + assert_eq!(super::u64(0.99_f32), Ok(0)); + + assert_eq!(super::u32(0.99_f64), Ok(0)); + assert_eq!(super::u32(0.01_f32), Ok(0)); +} + +#[test] +fn gh15() { + assert_eq!(super::u32(32_f32.exp2()), Err(super::Error::Overflow)); + assert_eq!(super::u32(32_f64.exp2()), Err(super::Error::Overflow)); + + assert_eq!(super::u64(64_f32.exp2()), Err(super::Error::Overflow)); + assert_eq!(super::u64(64_f64.exp2()), Err(super::Error::Overflow)); + + assert_eq!(super::u8(8_f32.exp2()), Err(super::Error::Overflow)); + assert_eq!(super::u8(8_f64.exp2()), Err(super::Error::Overflow)); + + assert_eq!(super::u16(16_f32.exp2()), Err(super::Error::Overflow)); + assert_eq!(super::u16(16_f64.exp2()), Err(super::Error::Overflow)); +}