diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index a062fbda5bad0..70fa14a0e283a 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4338,6 +4338,44 @@ mod ptr_try_from_impls { rev!(try_from_both_bounded, usize, i128); } +/// The error type returned when a checked float type conversion fails. +#[unstable(feature = "try_from_float", issue = "0")] +#[derive(Debug, Copy, Clone)] +pub struct TryFromFloatError(()); + +impl TryFromFloatError { + #[unstable(feature = "float_error_internals", + reason = "available through Error trait and this method should \ + not be exposed publicly", + issue = "0")] + #[doc(hidden)] + pub fn __description(&self) -> &str { + "lossy float type conversion attempted" + } +} + +#[unstable(feature = "try_from_float", issue = "0")] +impl fmt::Display for TryFromFloatError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.__description().fmt(fmt) + } +} + +#[stable(feature = "try_from_float_impl", since = "1.28.0")] +impl TryFrom for f32 { + type Error = TryFromFloatError; + + #[inline] + fn try_from(x: f64) -> Result { + let y = x as f32; + if y as f64 == x { + Ok(y) + } else { + Err(TryFromFloatError(())) + } + } +} + #[doc(hidden)] trait FromStrRadixHelper: PartialOrd + Copy { fn min_value() -> Self; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 817eea5eaf142..d9baef4ae9b50 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -278,6 +278,13 @@ impl Error for num::TryFromIntError { } } +#[unstable(feature = "try_from_float", issue = "0")] +impl Error for num::TryFromFloatError { + fn description(&self) -> &str { + self.__description() + } +} + #[unstable(feature = "try_from", issue = "33417")] impl Error for array::TryFromSliceError { fn description(&self) -> &str { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d41739ab02c6a..92414a641fd2f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -259,6 +259,7 @@ #![feature(external_doc)] #![feature(fs_read_write)] #![feature(fixed_size_array)] +#![feature(float_error_internals)] #![feature(float_from_str_radix)] #![cfg_attr(stage0, feature(float_internals))] #![feature(fn_traits)] @@ -308,6 +309,7 @@ #![feature(thread_local)] #![feature(toowned_clone_into)] #![feature(try_from)] +#![feature(try_from_float)] #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(untagged_unions)] diff --git a/src/libstd/num.rs b/src/libstd/num.rs index 4b975dd912a1a..e1fcb0aac7cb7 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -18,6 +18,8 @@ #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}; +#[unstable(feature = "try_from_float", issue = "0")] +pub use core::num::TryFromFloatError; #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping;