Skip to content

Commit

Permalink
Auto merge of rust-lang#130157 - eduardosm:stabilize-const_float_clas…
Browse files Browse the repository at this point in the history
…sify, r=RalfJung

Stabilize `const_float_classify`

Tracking issue: rust-lang#72505

Also reverts rust-lang#114486

Closes rust-lang#72505

Stabilized const API:

```rust
impl f32 {
    pub const fn is_nan(self) -> bool;
    pub const fn is_infinite(self) -> bool;
    pub const fn is_finite(self) -> bool;
    pub const fn is_subnormal(self) -> bool;
    pub const fn is_normal(self) -> bool;
    pub const fn classify(self) -> FpCategory;
    pub const fn is_sign_positive(self) -> bool;
    pub const fn is_sign_negative(self) -> bool;
}

impl f64 {
    pub const fn is_nan(self) -> bool;
    pub const fn is_infinite(self) -> bool;
    pub const fn is_finite(self) -> bool;
    pub const fn is_subnormal(self) -> bool;
    pub const fn is_normal(self) -> bool;
    pub const fn classify(self) -> FpCategory;
    pub const fn is_sign_positive(self) -> bool;
    pub const fn is_sign_negative(self) -> bool;
}
```

cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
  • Loading branch information
bors committed Oct 4, 2024
2 parents 1bd16cd + 1128894 commit eb2806b
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 31 deletions.
1 change: 0 additions & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@
#![feature(const_char_encode_utf8)]
#![feature(const_eval_select)]
#![feature(const_exact_div)]
#![feature(const_float_classify)]
#![feature(const_fmt_arguments_new)]
#![feature(const_hash)]
#![feature(const_heap)]
Expand Down
12 changes: 6 additions & 6 deletions core/src/num/f128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ impl f128 {
// concerns about portability, so this implementation is for
// private use internally.
#[inline]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
pub(crate) const fn abs_private(self) -> f128 {
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
unsafe {
Expand Down Expand Up @@ -319,7 +319,7 @@ impl f128 {
#[inline]
#[must_use]
#[unstable(feature = "f128", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
pub const fn is_infinite(self) -> bool {
(self == f128::INFINITY) | (self == f128::NEG_INFINITY)
}
Expand All @@ -346,7 +346,7 @@ impl f128 {
#[inline]
#[must_use]
#[unstable(feature = "f128", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
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.
Expand Down Expand Up @@ -380,7 +380,7 @@ impl f128 {
#[inline]
#[must_use]
#[unstable(feature = "f128", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
pub const fn is_subnormal(self) -> bool {
matches!(self.classify(), FpCategory::Subnormal)
}
Expand Down Expand Up @@ -412,7 +412,7 @@ impl f128 {
#[inline]
#[must_use]
#[unstable(feature = "f128", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
pub const fn is_normal(self) -> bool {
matches!(self.classify(), FpCategory::Normal)
}
Expand All @@ -437,7 +437,7 @@ impl f128 {
/// ```
#[inline]
#[unstable(feature = "f128", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
pub const fn classify(self) -> FpCategory {
let bits = self.to_bits();
match (bits & Self::MAN_MASK, bits & Self::EXP_MASK) {
Expand Down
12 changes: 6 additions & 6 deletions core/src/num/f16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ impl f16 {
// concerns about portability, so this implementation is for
// private use internally.
#[inline]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
pub(crate) const fn abs_private(self) -> f16 {
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
unsafe { mem::transmute::<u16, f16>(mem::transmute::<f16, u16>(self) & !Self::SIGN_MASK) }
Expand Down Expand Up @@ -310,7 +310,7 @@ impl f16 {
#[inline]
#[must_use]
#[unstable(feature = "f16", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
pub const fn is_infinite(self) -> bool {
(self == f16::INFINITY) | (self == f16::NEG_INFINITY)
}
Expand All @@ -336,7 +336,7 @@ impl f16 {
#[inline]
#[must_use]
#[unstable(feature = "f16", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
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.
Expand Down Expand Up @@ -368,7 +368,7 @@ impl f16 {
#[inline]
#[must_use]
#[unstable(feature = "f16", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
pub const fn is_subnormal(self) -> bool {
matches!(self.classify(), FpCategory::Subnormal)
}
Expand Down Expand Up @@ -398,7 +398,7 @@ impl f16 {
#[inline]
#[must_use]
#[unstable(feature = "f16", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
pub const fn is_normal(self) -> bool {
matches!(self.classify(), FpCategory::Normal)
}
Expand All @@ -422,7 +422,7 @@ impl f16 {
/// ```
#[inline]
#[unstable(feature = "f16", issue = "116909")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
pub const fn classify(self) -> FpCategory {
let b = self.to_bits();
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
Expand Down
17 changes: 8 additions & 9 deletions core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ impl f32 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :)
pub const fn is_nan(self) -> bool {
Expand All @@ -528,7 +528,6 @@ impl f32 {
// concerns about portability, so this implementation is for
// private use internally.
#[inline]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
pub(crate) const fn abs_private(self) -> f32 {
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
unsafe { mem::transmute::<u32, f32>(mem::transmute::<f32, u32>(self) & !Self::SIGN_MASK) }
Expand All @@ -551,7 +550,7 @@ impl f32 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_infinite(self) -> bool {
// Getting clever with transmutation can result in incorrect answers on some FPUs
Expand All @@ -576,7 +575,7 @@ impl f32 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_finite(self) -> bool {
// There's no need to handle NaN separately: if self is NaN,
Expand Down Expand Up @@ -604,7 +603,7 @@ impl f32 {
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
#[must_use]
#[stable(feature = "is_subnormal", since = "1.53.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_subnormal(self) -> bool {
matches!(self.classify(), FpCategory::Subnormal)
Expand All @@ -631,7 +630,7 @@ impl f32 {
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_normal(self) -> bool {
matches!(self.classify(), FpCategory::Normal)
Expand All @@ -651,7 +650,7 @@ impl f32 {
/// assert_eq!(inf.classify(), FpCategory::Infinite);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
pub const fn classify(self) -> FpCategory {
// We used to have complicated logic here that avoids the simple bit-based tests to work
// around buggy codegen for x87 targets (see
Expand Down Expand Up @@ -687,7 +686,7 @@ impl f32 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_sign_positive(self) -> bool {
!self.is_sign_negative()
Expand All @@ -712,7 +711,7 @@ impl f32 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_sign_negative(self) -> bool {
// IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
Expand Down
17 changes: 8 additions & 9 deletions core/src/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ impl f64 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :)
pub const fn is_nan(self) -> bool {
Expand All @@ -527,7 +527,6 @@ impl f64 {
// concerns about portability, so this implementation is for
// private use internally.
#[inline]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
pub(crate) const fn abs_private(self) -> f64 {
// SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
unsafe { mem::transmute::<u64, f64>(mem::transmute::<f64, u64>(self) & !Self::SIGN_MASK) }
Expand All @@ -550,7 +549,7 @@ impl f64 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_infinite(self) -> bool {
// Getting clever with transmutation can result in incorrect answers on some FPUs
Expand All @@ -575,7 +574,7 @@ impl f64 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_finite(self) -> bool {
// There's no need to handle NaN separately: if self is NaN,
Expand Down Expand Up @@ -603,7 +602,7 @@ impl f64 {
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
#[must_use]
#[stable(feature = "is_subnormal", since = "1.53.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_subnormal(self) -> bool {
matches!(self.classify(), FpCategory::Subnormal)
Expand All @@ -630,7 +629,7 @@ impl f64 {
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_normal(self) -> bool {
matches!(self.classify(), FpCategory::Normal)
Expand All @@ -650,7 +649,7 @@ impl f64 {
/// assert_eq!(inf.classify(), FpCategory::Infinite);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
pub const fn classify(self) -> FpCategory {
// We used to have complicated logic here that avoids the simple bit-based tests to work
// around buggy codegen for x87 targets (see
Expand Down Expand Up @@ -686,7 +685,7 @@ impl f64 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_sign_positive(self) -> bool {
!self.is_sign_negative()
Expand Down Expand Up @@ -720,7 +719,7 @@ impl f64 {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
#[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub const fn is_sign_negative(self) -> bool {
// IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
Expand Down

0 comments on commit eb2806b

Please sign in to comment.