diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 7c3c384ea93b7..4e6b6f04e9e92 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -96,8 +96,9 @@ issue = "0")] use prelude::v1::*; -use num::ParseFloatError as PFE; -use num::FloatErrorKind; +use fmt; +use str::FromStr; + use self::parse::{parse_decimal, Decimal, Sign}; use self::parse::ParseResult::{self, Valid, ShortcutToInf, ShortcutToZero}; use self::num::digits_to_big; @@ -110,14 +111,87 @@ mod num; pub mod rawfp; pub mod parse; -/// Entry point for decimal-to-f32 conversion. -pub fn to_f32(s: &str) -> Result { - dec2flt(s) +macro_rules! from_str_float_impl { + ($t:ty, $func:ident) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl FromStr for $t { + type Err = ParseFloatError; + + /// Converts a string in base 10 to a float. + /// Accepts an optional decimal exponent. + /// + /// This function accepts strings such as + /// + /// * '3.14' + /// * '-3.14' + /// * '2.5E10', or equivalently, '2.5e10' + /// * '2.5E-10' + /// * '.' (understood as 0) + /// * '5.' + /// * '.5', or, equivalently, '0.5' + /// * 'inf', '-inf', 'NaN' + /// + /// Leading and trailing whitespace represent an error. + /// + /// # Arguments + /// + /// * src - A string + /// + /// # Return value + /// + /// `Err(ParseFloatError)` if the string did not represent a valid + /// number. Otherwise, `Ok(n)` where `n` is the floating-point + /// number represented by `src`. + #[inline] + fn from_str(src: &str) -> Result { + dec2flt(src) + } + } + } +} +from_str_float_impl!(f32, to_f32); +from_str_float_impl!(f64, to_f64); + +/// An error which can be returned when parsing a float. +#[derive(Debug, Clone, PartialEq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct ParseFloatError { + kind: FloatErrorKind +} + +#[derive(Debug, Clone, PartialEq)] +enum FloatErrorKind { + Empty, + Invalid, +} + +impl ParseFloatError { + #[unstable(feature = "int_error_internals", + reason = "available through Error trait and this method should \ + not be exposed publicly", + issue = "0")] + #[doc(hidden)] + pub fn __description(&self) -> &str { + match self.kind { + FloatErrorKind::Empty => "cannot parse float from empty string", + FloatErrorKind::Invalid => "invalid float literal", + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for ParseFloatError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.__description().fmt(f) + } +} + +pub fn pfe_empty() -> ParseFloatError { + ParseFloatError { kind: FloatErrorKind::Empty } } -/// Entry point for decimal-to-f64 conversion. -pub fn to_f64(s: &str) -> Result { - dec2flt(s) +pub fn pfe_invalid() -> ParseFloatError { + ParseFloatError { kind: FloatErrorKind::Invalid } } /// Split decimal string into sign and the rest, without inspecting or validating the rest. @@ -131,9 +205,9 @@ fn extract_sign(s: &str) -> (Sign, &str) { } /// Convert a decimal string into a floating point number. -fn dec2flt(s: &str) -> Result { +fn dec2flt(s: &str) -> Result { if s.is_empty() { - return Err(PFE { __kind: FloatErrorKind::Empty }); + return Err(pfe_empty()) } let (sign, s) = extract_sign(s); let flt = match parse_decimal(s) { @@ -143,7 +217,7 @@ fn dec2flt(s: &str) -> Result { ParseResult::Invalid => match s { "inf" => T::infinity(), "NaN" => T::nan(), - _ => { return Err(PFE { __kind: FloatErrorKind::Invalid }); } + _ => { return Err(pfe_invalid()); } } }; @@ -155,7 +229,7 @@ fn dec2flt(s: &str) -> Result { /// The main workhorse for the decimal-to-float conversion: Orchestrate all the preprocessing /// and figure out which algorithm should do the actual conversion. -fn convert(mut decimal: Decimal) -> Result { +fn convert(mut decimal: Decimal) -> Result { simplify(&mut decimal); if let Some(x) = trivial_cases(&decimal) { return Ok(x); @@ -172,7 +246,7 @@ fn convert(mut decimal: Decimal) -> Result { // If we exceed this, perhaps while calculating `f * 10^e` in Algorithm R or Algorithm M, // we'll crash. So we error out before getting too close, with a generous safety margin. if max_digits > 375 { - return Err(PFE { __kind: FloatErrorKind::Invalid }); + return Err(pfe_invalid()); } let f = digits_to_big(decimal.integral, decimal.fractional); diff --git a/src/libcore/num/float_macros.rs b/src/libcore/num/float_macros.rs index e3fa7047ec88c..88c3b756793a2 100644 --- a/src/libcore/num/float_macros.rs +++ b/src/libcore/num/float_macros.rs @@ -23,8 +23,7 @@ macro_rules! from_str_radix_float_impl { ($T:ty) => { fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseFloatError> { - use num::FloatErrorKind::*; - use num::ParseFloatError as PFE; + use num::dec2flt::{pfe_empty, pfe_invalid}; // Special values match src { @@ -35,8 +34,8 @@ macro_rules! from_str_radix_float_impl { } let (is_positive, src) = match src.slice_shift_char() { - None => return Err(PFE { __kind: Empty }), - Some(('-', "")) => return Err(PFE { __kind: Empty }), + None => return Err(pfe_empty()), + Some(('-', "")) => return Err(pfe_empty()), Some(('-', src)) => (false, src), Some((_, _)) => (true, src), }; @@ -88,7 +87,7 @@ macro_rules! from_str_radix_float_impl { break; // start of fractional part }, _ => { - return Err(PFE { __kind: Invalid }); + return Err(pfe_invalid()) }, }, } @@ -122,7 +121,7 @@ macro_rules! from_str_radix_float_impl { break; // start of exponent }, _ => { - return Err(PFE { __kind: Invalid }); + return Err(pfe_invalid()) }, }, } @@ -135,7 +134,7 @@ macro_rules! from_str_radix_float_impl { let base = match c { 'E' | 'e' if radix == 10 => 10.0, 'P' | 'p' if radix == 16 => 2.0, - _ => return Err(PFE { __kind: Invalid }), + _ => return Err(pfe_invalid()), }; // Parse the exponent as decimal integer @@ -144,13 +143,13 @@ macro_rules! from_str_radix_float_impl { Some(('-', src)) => (false, src.parse::()), Some(('+', src)) => (true, src.parse::()), Some((_, _)) => (true, src.parse::()), - None => return Err(PFE { __kind: Invalid }), + None => return Err(pfe_invalid()), }; match (is_positive, exp) { (true, Ok(exp)) => base.powi(exp as i32), (false, Ok(exp)) => 1.0 / base.powi(exp as i32), - (_, Err(_)) => return Err(PFE { __kind: Invalid }), + (_, Err(_)) => return Err(pfe_invalid()), } }, None => 1.0, // no exponent diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 086437445dec7..8770f46bc8ec9 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1365,47 +1365,6 @@ pub trait Float: Sized { fn to_radians(self) -> Self; } -macro_rules! from_str_float_impl { - ($t:ty, $func:ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl FromStr for $t { - type Err = ParseFloatError; - - /// Converts a string in base 10 to a float. - /// Accepts an optional decimal exponent. - /// - /// This function accepts strings such as - /// - /// * '3.14' - /// * '-3.14' - /// * '2.5E10', or equivalently, '2.5e10' - /// * '2.5E-10' - /// * '.' (understood as 0) - /// * '5.' - /// * '.5', or, equivalently, '0.5' - /// * 'inf', '-inf', 'NaN' - /// - /// Leading and trailing whitespace represent an error. - /// - /// # Arguments - /// - /// * src - A string - /// - /// # Return value - /// - /// `Err(ParseFloatError)` if the string did not represent a valid - /// number. Otherwise, `Ok(n)` where `n` is the floating-point - /// number represented by `src`. - #[inline] - fn from_str(src: &str) -> Result { - dec2flt::$func(src) - } - } - } -} -from_str_float_impl!(f32, to_f32); -from_str_float_impl!(f64, to_f64); - macro_rules! from_str_radix_int_impl { ($($t:ty)*) => {$( #[stable(feature = "rust1", since = "1.0.0")] @@ -1548,40 +1507,4 @@ impl fmt::Display for ParseIntError { } } -/// An error which can be returned when parsing a float. -#[derive(Debug, Clone, PartialEq)] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct ParseFloatError { - #[doc(hidden)] - #[unstable(feature = "float_error_internals", - reason = "should not be exposed publicly", - issue = "0")] - pub __kind: FloatErrorKind -} - -#[derive(Debug, Clone, PartialEq)] -#[unstable(feature = "float_error_internals", - reason = "should not be exposed publicly", - issue = "0")] -#[doc(hidden)] -pub enum FloatErrorKind { - Empty, - Invalid, -} - -impl ParseFloatError { - #[doc(hidden)] - pub fn __description(&self) -> &str { - match self.__kind { - FloatErrorKind::Empty => "cannot parse float from empty string", - FloatErrorKind::Invalid => "invalid float literal", - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Display for ParseFloatError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.__description().fmt(f) - } -} +pub use num::dec2flt::ParseFloatError; diff --git a/src/libcoretest/atomic.rs b/src/libcoretest/atomic.rs index c50f18c235233..b6bb5fddf4a4b 100644 --- a/src/libcoretest/atomic.rs +++ b/src/libcoretest/atomic.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::atomic::*; -use core::atomic::Ordering::SeqCst; +use core::sync::atomic::*; +use core::sync::atomic::Ordering::SeqCst; #[test] fn bool_() { diff --git a/src/libcoretest/num/dec2flt/mod.rs b/src/libcoretest/num/dec2flt/mod.rs index b7ef956055e29..131cf62957537 100644 --- a/src/libcoretest/num/dec2flt/mod.rs +++ b/src/libcoretest/num/dec2flt/mod.rs @@ -12,7 +12,6 @@ use std::{i64, f32, f64}; use test; -use core::num::dec2flt::{to_f32, to_f64}; mod parse; mod rawfp; @@ -27,11 +26,11 @@ macro_rules! test_literal { let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)]; for input in inputs { if input != "inf" { - assert_eq!(to_f64(input), Ok(x64)); - assert_eq!(to_f32(input), Ok(x32)); + assert_eq!(input.parse(), Ok(x64)); + assert_eq!(input.parse(), Ok(x32)); let neg_input = &format!("-{}", input); - assert_eq!(to_f64(neg_input), Ok(-x64)); - assert_eq!(to_f32(neg_input), Ok(-x32)); + assert_eq!(neg_input.parse(), Ok(-x64)); + assert_eq!(neg_input.parse(), Ok(-x32)); } } }) @@ -99,83 +98,83 @@ fn fast_path_correct() { #[test] fn lonely_dot() { - assert_eq!(to_f64("."), Ok(0.0)); + assert_eq!(".".parse(), Ok(0.0)); } #[test] fn nan() { - assert!(to_f64("NaN").unwrap().is_nan()); - assert!(to_f32("NaN").unwrap().is_nan()); + assert!("NaN".parse::().unwrap().is_nan()); + assert!("NaN".parse::().unwrap().is_nan()); } #[test] fn inf() { - assert_eq!(to_f64("inf"), Ok(f64::INFINITY)); - assert_eq!(to_f64("-inf"), Ok(f64::NEG_INFINITY)); - assert_eq!(to_f32("inf"), Ok(f32::INFINITY)); - assert_eq!(to_f32("-inf"), Ok(f32::NEG_INFINITY)); + assert_eq!("inf".parse(), Ok(f64::INFINITY)); + assert_eq!("-inf".parse(), Ok(f64::NEG_INFINITY)); + assert_eq!("inf".parse(), Ok(f32::INFINITY)); + assert_eq!("-inf".parse(), Ok(f32::NEG_INFINITY)); } #[test] fn massive_exponent() { let max = i64::MAX; - assert_eq!(to_f64(&format!("1e{}000", max)), Ok(f64::INFINITY)); - assert_eq!(to_f64(&format!("1e-{}000", max)), Ok(0.0)); - assert_eq!(to_f64(&format!("1e{}000", max)), Ok(f64::INFINITY)); + assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY)); + assert_eq!(format!("1e-{}000", max).parse(), Ok(0.0)); + assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY)); } #[bench] fn bench_0(b: &mut test::Bencher) { - b.iter(|| to_f64("0.0")); + b.iter(|| "0.0".parse::()); } #[bench] fn bench_42(b: &mut test::Bencher) { - b.iter(|| to_f64("42")); + b.iter(|| "42".parse::()); } #[bench] fn bench_huge_int(b: &mut test::Bencher) { // 2^128 - 1 - b.iter(|| to_f64("170141183460469231731687303715884105727")); + b.iter(|| "170141183460469231731687303715884105727".parse::()); } #[bench] fn bench_short_decimal(b: &mut test::Bencher) { - b.iter(|| to_f64("1234.5678")); + b.iter(|| "1234.5678".parse::()); } #[bench] fn bench_pi_long(b: &mut test::Bencher) { - b.iter(|| to_f64("3.14159265358979323846264338327950288")); + b.iter(|| "3.14159265358979323846264338327950288".parse::()); } #[bench] fn bench_pi_short(b: &mut test::Bencher) { - b.iter(|| to_f64("3.141592653589793")) + b.iter(|| "3.141592653589793".parse::()) } #[bench] fn bench_1e150(b: &mut test::Bencher) { - b.iter(|| to_f64("1e150")); + b.iter(|| "1e150".parse::()); } #[bench] fn bench_long_decimal_and_exp(b: &mut test::Bencher) { - b.iter(|| to_f64("727501488517303786137132964064381141071e-123")); + b.iter(|| "727501488517303786137132964064381141071e-123".parse::()); } #[bench] fn bench_min_subnormal(b: &mut test::Bencher) { - b.iter(|| to_f64("5e-324")); + b.iter(|| "5e-324".parse::()); } #[bench] fn bench_min_normal(b: &mut test::Bencher) { - b.iter(|| to_f64("2.2250738585072014e-308")); + b.iter(|| "2.2250738585072014e-308".parse::()); } #[bench] fn bench_max(b: &mut test::Bencher) { - b.iter(|| to_f64("1.7976931348623157e308")); + b.iter(|| "1.7976931348623157e308".parse::()); } diff --git a/src/libcoretest/num/uint_macros.rs b/src/libcoretest/num/uint_macros.rs index 6238c6d43e353..25591db64d907 100644 --- a/src/libcoretest/num/uint_macros.rs +++ b/src/libcoretest/num/uint_macros.rs @@ -14,7 +14,7 @@ mod tests { use core::$T_i::*; use num; use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not}; - use std::str; + use std::str::FromStr; #[test] fn test_overflows() { @@ -152,5 +152,5 @@ mod tests { assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>); assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>); } - +} )} diff --git a/src/test/compile-fail/issue-1920-1.rs b/src/test/compile-fail/issue-1920-1.rs index c26c5ff8421d9..8c75d4680faeb 100644 --- a/src/test/compile-fail/issue-1920-1.rs +++ b/src/test/compile-fail/issue-1920-1.rs @@ -17,6 +17,6 @@ mod foo { fn assert_clone() where T : Clone { } fn main() { - assert_clone::(); + assert_clone::(); //~^ ERROR the trait `foo::core::clone::Clone` is not implemented for the type `foo::core:: -} \ No newline at end of file +} diff --git a/src/test/compile-fail/issue-1920-2.rs b/src/test/compile-fail/issue-1920-2.rs index 63cfcbdd8c700..57eb82a156bbf 100644 --- a/src/test/compile-fail/issue-1920-2.rs +++ b/src/test/compile-fail/issue-1920-2.rs @@ -15,6 +15,6 @@ extern crate core as bar; fn assert_clone() where T : Clone { } fn main() { - assert_clone::(); - //~^ ERROR the trait `bar::clone::Clone` is not implemented for the type `bar::atomic:: -} \ No newline at end of file + assert_clone::(); + //~^ ERROR the trait `bar::clone::Clone` is not implemented for the type `bar::sync::atomic:: +} diff --git a/src/test/compile-fail/issue-1920-3.rs b/src/test/compile-fail/issue-1920-3.rs index 619c8c3f3a4f0..0ef7747c8a84f 100644 --- a/src/test/compile-fail/issue-1920-3.rs +++ b/src/test/compile-fail/issue-1920-3.rs @@ -19,6 +19,6 @@ extern crate core; fn assert_clone() where T : Clone { } fn main() { - assert_clone::(); - //~^ ERROR the trait `core::clone::Clone` is not implemented for the type `core::atomic:: -} \ No newline at end of file + assert_clone::(); + //~^ ERROR the trait `core::clone::Clone` is not implemented for the type `core::sync::atomic:: +}