diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 7294adaccd3..99f8cc66638 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -73,6 +73,7 @@ #![feature(const_discriminant)] #![feature(const_checked_int_methods)] #![feature(const_euclidean_int_methods)] +#![feature(const_float_classify)] #![feature(const_float_bits_conv)] #![feature(const_overflowing_int_methods)] #![feature(const_int_unchecked_arith)] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 2d2d99ef6ee..043f0b14f24 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -381,8 +381,9 @@ impl f32 { /// assert!(!f.is_nan()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_nan(self) -> bool { + pub const fn is_nan(self) -> bool { self != self } @@ -390,7 +391,8 @@ impl f32 { // concerns about portability, so this implementation is for // private use internally. #[inline] - fn abs_private(self) -> f32 { + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] + const fn abs_private(self) -> f32 { f32::from_bits(self.to_bits() & 0x7fff_ffff) } @@ -410,8 +412,9 @@ impl f32 { /// assert!(neg_inf.is_infinite()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_infinite(self) -> bool { + pub const fn is_infinite(self) -> bool { self.abs_private() == Self::INFINITY } @@ -430,8 +433,9 @@ impl f32 { /// assert!(!neg_inf.is_finite()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_finite(self) -> bool { + pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. self.abs_private() < Self::INFINITY @@ -457,9 +461,10 @@ impl f32 { /// ``` /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_normal(self) -> bool { - self.classify() == FpCategory::Normal + pub const fn is_normal(self) -> bool { + matches!(self.classify(), FpCategory::Normal) } /// Returns the floating point category of the number. If only one property @@ -476,7 +481,8 @@ impl f32 { /// assert_eq!(inf.classify(), FpCategory::Infinite); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn classify(self) -> FpCategory { + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] + pub const fn classify(self) -> FpCategory { const EXP_MASK: u32 = 0x7f800000; const MAN_MASK: u32 = 0x007fffff; @@ -501,8 +507,9 @@ impl f32 { /// assert!(!g.is_sign_positive()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_sign_positive(self) -> bool { + pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() } @@ -517,8 +524,9 @@ impl f32 { /// assert!(g.is_sign_negative()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_sign_negative(self) -> bool { + pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. self.to_bits() & 0x8000_0000 != 0 diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 82ea82fe2be..24624b88d59 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -380,8 +380,9 @@ impl f64 { /// assert!(!f.is_nan()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_nan(self) -> bool { + pub const fn is_nan(self) -> bool { self != self } @@ -389,7 +390,8 @@ impl f64 { // concerns about portability, so this implementation is for // private use internally. #[inline] - fn abs_private(self) -> f64 { + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] + const fn abs_private(self) -> f64 { f64::from_bits(self.to_bits() & 0x7fff_ffff_ffff_ffff) } @@ -409,8 +411,9 @@ impl f64 { /// assert!(neg_inf.is_infinite()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_infinite(self) -> bool { + pub const fn is_infinite(self) -> bool { self.abs_private() == Self::INFINITY } @@ -429,8 +432,9 @@ impl f64 { /// assert!(!neg_inf.is_finite()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_finite(self) -> bool { + pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. self.abs_private() < Self::INFINITY @@ -456,9 +460,10 @@ impl f64 { /// ``` /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_normal(self) -> bool { - self.classify() == FpCategory::Normal + pub const fn is_normal(self) -> bool { + matches!(self.classify(), FpCategory::Normal) } /// Returns the floating point category of the number. If only one property @@ -475,7 +480,8 @@ impl f64 { /// assert_eq!(inf.classify(), FpCategory::Infinite); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn classify(self) -> FpCategory { + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] + pub const fn classify(self) -> FpCategory { const EXP_MASK: u64 = 0x7ff0000000000000; const MAN_MASK: u64 = 0x000fffffffffffff; @@ -500,8 +506,9 @@ impl f64 { /// assert!(!g.is_sign_positive()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_sign_positive(self) -> bool { + pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() } @@ -524,8 +531,9 @@ impl f64 { /// assert!(g.is_sign_negative()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")] #[inline] - pub fn is_sign_negative(self) -> bool { + pub const fn is_sign_negative(self) -> bool { self.to_bits() & 0x8000_0000_0000_0000 != 0 }