mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 14:02:57 +00:00
Remove the unstable Float trait
Following up to #49896 and #50629. Fixes #32110. E0689 is weird.
This commit is contained in:
parent
ba1363ffe1
commit
b825477154
@ -33,7 +33,7 @@ use ops::{Add, Mul, Div, Neg};
|
||||
use fmt::{Debug, LowerExp};
|
||||
use num::diy_float::Fp;
|
||||
use num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
|
||||
use num::Float;
|
||||
use num::FpCategory;
|
||||
use num::dec2flt::num::{self, Big};
|
||||
use num::dec2flt::table;
|
||||
|
||||
@ -54,24 +54,29 @@ impl Unpacked {
|
||||
/// See the parent module's doc comment for why this is necessary.
|
||||
///
|
||||
/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
|
||||
/// Inherits from `Float` because there is some overlap, but all the reused methods are trivial.
|
||||
pub trait RawFloat
|
||||
: Float
|
||||
+ Copy
|
||||
: Copy
|
||||
+ Debug
|
||||
+ LowerExp
|
||||
+ Mul<Output=Self>
|
||||
+ Div<Output=Self>
|
||||
+ Neg<Output=Self>
|
||||
where
|
||||
Self: Float<Bits = <Self as RawFloat>::RawBits>
|
||||
{
|
||||
const INFINITY: Self;
|
||||
const NAN: Self;
|
||||
const ZERO: Self;
|
||||
|
||||
/// Same as `Float::Bits` with extra traits.
|
||||
type RawBits: Add<Output = Self::RawBits> + From<u8> + TryFrom<u64>;
|
||||
/// Type used by `to_bits` and `from_bits`.
|
||||
type Bits: Add<Output = Self::Bits> + From<u8> + TryFrom<u64>;
|
||||
|
||||
/// Raw transmutation to integer.
|
||||
fn to_bits(self) -> Self::Bits;
|
||||
|
||||
/// Raw transmutation from integer.
|
||||
fn from_bits(v: Self::Bits) -> Self;
|
||||
|
||||
/// Returns the category that this number falls into.
|
||||
fn classify(self) -> FpCategory;
|
||||
|
||||
/// Returns the mantissa, exponent and sign as integers.
|
||||
fn integer_decode(self) -> (u64, i16, i8);
|
||||
@ -153,7 +158,7 @@ macro_rules! other_constants {
|
||||
}
|
||||
|
||||
impl RawFloat for f32 {
|
||||
type RawBits = u32;
|
||||
type Bits = u32;
|
||||
|
||||
const SIG_BITS: u8 = 24;
|
||||
const EXP_BITS: u8 = 8;
|
||||
@ -192,11 +197,15 @@ impl RawFloat for f32 {
|
||||
fn short_fast_pow10(e: usize) -> Self {
|
||||
table::F32_SHORT_POWERS[e]
|
||||
}
|
||||
|
||||
fn classify(self) -> FpCategory { self.classify() }
|
||||
fn to_bits(self) -> Self::Bits { self.to_bits() }
|
||||
fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) }
|
||||
}
|
||||
|
||||
|
||||
impl RawFloat for f64 {
|
||||
type RawBits = u64;
|
||||
type Bits = u64;
|
||||
|
||||
const SIG_BITS: u8 = 53;
|
||||
const EXP_BITS: u8 = 11;
|
||||
@ -235,6 +244,10 @@ impl RawFloat for f64 {
|
||||
fn short_fast_pow10(e: usize) -> Self {
|
||||
table::F64_SHORT_POWERS[e]
|
||||
}
|
||||
|
||||
fn classify(self) -> FpCategory { self.classify() }
|
||||
fn to_bits(self) -> Self::Bits { self.to_bits() }
|
||||
fn from_bits(v: Self::Bits) -> Self { Self::from_bits(v) }
|
||||
}
|
||||
|
||||
/// Convert an Fp to the closest machine float type.
|
||||
|
@ -18,9 +18,7 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use mem;
|
||||
use num::Float;
|
||||
use num::FpCategory;
|
||||
use num::FpCategory as Fp;
|
||||
|
||||
/// The radix or base of the internal representation of `f32`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -149,136 +147,9 @@ pub mod consts {
|
||||
pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32;
|
||||
}
|
||||
|
||||
#[unstable(feature = "core_float",
|
||||
reason = "stable interface is via `impl f{32,64}` in later crates",
|
||||
issue = "32110")]
|
||||
impl Float for f32 {
|
||||
type Bits = u32;
|
||||
|
||||
/// Returns `true` if the number is NaN.
|
||||
#[inline]
|
||||
fn is_nan(self) -> bool {
|
||||
self != self
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is infinite.
|
||||
#[inline]
|
||||
fn is_infinite(self) -> bool {
|
||||
self == INFINITY || self == NEG_INFINITY
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither infinite or NaN.
|
||||
#[inline]
|
||||
fn is_finite(self) -> bool {
|
||||
!(self.is_nan() || self.is_infinite())
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite, subnormal or NaN.
|
||||
#[inline]
|
||||
fn is_normal(self) -> bool {
|
||||
self.classify() == Fp::Normal
|
||||
}
|
||||
|
||||
/// Returns the floating point category of the number. If only one property
|
||||
/// is going to be tested, it is generally faster to use the specific
|
||||
/// predicate instead.
|
||||
fn classify(self) -> Fp {
|
||||
const EXP_MASK: u32 = 0x7f800000;
|
||||
const MAN_MASK: u32 = 0x007fffff;
|
||||
|
||||
let bits = self.to_bits();
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
(0, 0) => Fp::Zero,
|
||||
(_, 0) => Fp::Subnormal,
|
||||
(0, EXP_MASK) => Fp::Infinite,
|
||||
(_, EXP_MASK) => Fp::Nan,
|
||||
_ => Fp::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
#[inline]
|
||||
fn is_sign_positive(self) -> bool {
|
||||
!self.is_sign_negative()
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
#[inline]
|
||||
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
|
||||
}
|
||||
|
||||
/// Returns the reciprocal (multiplicative inverse) of the number.
|
||||
#[inline]
|
||||
fn recip(self) -> f32 {
|
||||
1.0 / self
|
||||
}
|
||||
|
||||
/// Converts to degrees, assuming the number is in radians.
|
||||
#[inline]
|
||||
fn to_degrees(self) -> f32 {
|
||||
// Use a constant for better precision.
|
||||
const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
|
||||
self * PIS_IN_180
|
||||
}
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees.
|
||||
#[inline]
|
||||
fn to_radians(self) -> f32 {
|
||||
let value: f32 = consts::PI;
|
||||
self * (value / 180.0f32)
|
||||
}
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
#[inline]
|
||||
fn max(self, other: f32) -> f32 {
|
||||
// IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if self.is_nan() || self < other { other } else { self }) * 1.0
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
#[inline]
|
||||
fn min(self, other: f32) -> f32 {
|
||||
// IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if other.is_nan() || self < other { self } else { other }) * 1.0
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u32`.
|
||||
#[inline]
|
||||
fn to_bits(self) -> u32 {
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u32`.
|
||||
#[inline]
|
||||
fn from_bits(v: u32) -> Self {
|
||||
// It turns out the safety issues with sNaN were overblown! Hooray!
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: remove (inline) this macro and the Float trait
|
||||
// when updating to a bootstrap compiler that has the new lang items.
|
||||
#[unstable(feature = "core_float", issue = "32110")]
|
||||
macro_rules! f32_core_methods { () => {
|
||||
#[lang = "f32"]
|
||||
#[cfg(not(test))]
|
||||
impl f32 {
|
||||
/// Returns `true` if this value is `NaN` and false otherwise.
|
||||
///
|
||||
/// ```
|
||||
@ -292,7 +163,9 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_nan(self) -> bool { Float::is_nan(self) }
|
||||
pub fn is_nan(self) -> bool {
|
||||
self != self
|
||||
}
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
@ -313,7 +186,9 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_infinite(self) -> bool { Float::is_infinite(self) }
|
||||
pub fn is_infinite(self) -> bool {
|
||||
self == INFINITY || self == NEG_INFINITY
|
||||
}
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor `NaN`.
|
||||
///
|
||||
@ -333,7 +208,9 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_finite(self) -> bool { Float::is_finite(self) }
|
||||
pub fn is_finite(self) -> bool {
|
||||
!(self.is_nan() || self.is_infinite())
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
@ -358,7 +235,9 @@ macro_rules! f32_core_methods { () => {
|
||||
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_normal(self) -> bool { Float::is_normal(self) }
|
||||
pub fn is_normal(self) -> bool {
|
||||
self.classify() == FpCategory::Normal
|
||||
}
|
||||
|
||||
/// Returns the floating point category of the number. If only one property
|
||||
/// is going to be tested, it is generally faster to use the specific
|
||||
@ -375,8 +254,19 @@ macro_rules! f32_core_methods { () => {
|
||||
/// assert_eq!(inf.classify(), FpCategory::Infinite);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn classify(self) -> FpCategory { Float::classify(self) }
|
||||
pub fn classify(self) -> FpCategory {
|
||||
const EXP_MASK: u32 = 0x7f800000;
|
||||
const MAN_MASK: u32 = 0x007fffff;
|
||||
|
||||
let bits = self.to_bits();
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
(0, 0) => FpCategory::Zero,
|
||||
(_, 0) => FpCategory::Subnormal,
|
||||
(0, EXP_MASK) => FpCategory::Infinite,
|
||||
(_, EXP_MASK) => FpCategory::Nan,
|
||||
_ => FpCategory::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
@ -390,7 +280,9 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) }
|
||||
pub fn is_sign_positive(self) -> bool {
|
||||
!self.is_sign_negative()
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
@ -404,7 +296,11 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) }
|
||||
pub 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
|
||||
}
|
||||
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
@ -418,7 +314,9 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn recip(self) -> f32 { Float::recip(self) }
|
||||
pub fn recip(self) -> f32 {
|
||||
1.0 / self
|
||||
}
|
||||
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
@ -433,7 +331,11 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
|
||||
#[inline]
|
||||
pub fn to_degrees(self) -> f32 { Float::to_degrees(self) }
|
||||
pub fn to_degrees(self) -> f32 {
|
||||
// Use a constant for better precision.
|
||||
const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
|
||||
self * PIS_IN_180
|
||||
}
|
||||
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
@ -448,7 +350,10 @@ macro_rules! f32_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
|
||||
#[inline]
|
||||
pub fn to_radians(self) -> f32 { Float::to_radians(self) }
|
||||
pub fn to_radians(self) -> f32 {
|
||||
let value: f32 = consts::PI;
|
||||
self * (value / 180.0f32)
|
||||
}
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
@ -463,7 +368,15 @@ macro_rules! f32_core_methods { () => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn max(self, other: f32) -> f32 {
|
||||
Float::max(self, other)
|
||||
// IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if self.is_nan() || self < other { other } else { self }) * 1.0
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
@ -479,7 +392,15 @@ macro_rules! f32_core_methods { () => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn min(self, other: f32) -> f32 {
|
||||
Float::min(self, other)
|
||||
// IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if other.is_nan() || self < other { self } else { other }) * 1.0
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u32`.
|
||||
@ -502,7 +423,7 @@ macro_rules! f32_core_methods { () => {
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn to_bits(self) -> u32 {
|
||||
Float::to_bits(self)
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u32`.
|
||||
@ -546,12 +467,7 @@ macro_rules! f32_core_methods { () => {
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn from_bits(v: u32) -> Self {
|
||||
Float::from_bits(v)
|
||||
// It turns out the safety issues with sNaN were overblown! Hooray!
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
}}
|
||||
|
||||
#[lang = "f32"]
|
||||
#[cfg(not(test))]
|
||||
impl f32 {
|
||||
f32_core_methods!();
|
||||
}
|
||||
|
@ -18,9 +18,7 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use mem;
|
||||
use num::Float;
|
||||
use num::FpCategory;
|
||||
use num::FpCategory as Fp;
|
||||
|
||||
/// The radix or base of the internal representation of `f64`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -149,135 +147,9 @@ pub mod consts {
|
||||
pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64;
|
||||
}
|
||||
|
||||
#[unstable(feature = "core_float",
|
||||
reason = "stable interface is via `impl f{32,64}` in later crates",
|
||||
issue = "32110")]
|
||||
impl Float for f64 {
|
||||
type Bits = u64;
|
||||
|
||||
/// Returns `true` if the number is NaN.
|
||||
#[inline]
|
||||
fn is_nan(self) -> bool {
|
||||
self != self
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is infinite.
|
||||
#[inline]
|
||||
fn is_infinite(self) -> bool {
|
||||
self == INFINITY || self == NEG_INFINITY
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither infinite or NaN.
|
||||
#[inline]
|
||||
fn is_finite(self) -> bool {
|
||||
!(self.is_nan() || self.is_infinite())
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite, subnormal or NaN.
|
||||
#[inline]
|
||||
fn is_normal(self) -> bool {
|
||||
self.classify() == Fp::Normal
|
||||
}
|
||||
|
||||
/// Returns the floating point category of the number. If only one property
|
||||
/// is going to be tested, it is generally faster to use the specific
|
||||
/// predicate instead.
|
||||
fn classify(self) -> Fp {
|
||||
const EXP_MASK: u64 = 0x7ff0000000000000;
|
||||
const MAN_MASK: u64 = 0x000fffffffffffff;
|
||||
|
||||
let bits = self.to_bits();
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
(0, 0) => Fp::Zero,
|
||||
(_, 0) => Fp::Subnormal,
|
||||
(0, EXP_MASK) => Fp::Infinite,
|
||||
(_, EXP_MASK) => Fp::Nan,
|
||||
_ => Fp::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
#[inline]
|
||||
fn is_sign_positive(self) -> bool {
|
||||
!self.is_sign_negative()
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
#[inline]
|
||||
fn is_sign_negative(self) -> bool {
|
||||
self.to_bits() & 0x8000_0000_0000_0000 != 0
|
||||
}
|
||||
|
||||
/// Returns the reciprocal (multiplicative inverse) of the number.
|
||||
#[inline]
|
||||
fn recip(self) -> f64 {
|
||||
1.0 / self
|
||||
}
|
||||
|
||||
/// Converts to degrees, assuming the number is in radians.
|
||||
#[inline]
|
||||
fn to_degrees(self) -> f64 {
|
||||
// The division here is correctly rounded with respect to the true
|
||||
// value of 180/π. (This differs from f32, where a constant must be
|
||||
// used to ensure a correctly rounded result.)
|
||||
self * (180.0f64 / consts::PI)
|
||||
}
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees.
|
||||
#[inline]
|
||||
fn to_radians(self) -> f64 {
|
||||
let value: f64 = consts::PI;
|
||||
self * (value / 180.0)
|
||||
}
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
#[inline]
|
||||
fn max(self, other: f64) -> f64 {
|
||||
// IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if self.is_nan() || self < other { other } else { self }) * 1.0
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
#[inline]
|
||||
fn min(self, other: f64) -> f64 {
|
||||
// IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if other.is_nan() || self < other { self } else { other }) * 1.0
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u64`.
|
||||
#[inline]
|
||||
fn to_bits(self) -> u64 {
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u64`.
|
||||
#[inline]
|
||||
fn from_bits(v: u64) -> Self {
|
||||
// It turns out the safety issues with sNaN were overblown! Hooray!
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: remove (inline) this macro and the Float trait
|
||||
// when updating to a bootstrap compiler that has the new lang items.
|
||||
#[unstable(feature = "core_float", issue = "32110")]
|
||||
macro_rules! f64_core_methods { () => {
|
||||
#[lang = "f64"]
|
||||
#[cfg(not(test))]
|
||||
impl f64 {
|
||||
/// Returns `true` if this value is `NaN` and false otherwise.
|
||||
///
|
||||
/// ```
|
||||
@ -291,7 +163,9 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_nan(self) -> bool { Float::is_nan(self) }
|
||||
pub fn is_nan(self) -> bool {
|
||||
self != self
|
||||
}
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
@ -312,7 +186,9 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_infinite(self) -> bool { Float::is_infinite(self) }
|
||||
pub fn is_infinite(self) -> bool {
|
||||
self == INFINITY || self == NEG_INFINITY
|
||||
}
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor `NaN`.
|
||||
///
|
||||
@ -332,7 +208,9 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_finite(self) -> bool { Float::is_finite(self) }
|
||||
pub fn is_finite(self) -> bool {
|
||||
!(self.is_nan() || self.is_infinite())
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
@ -357,7 +235,9 @@ macro_rules! f64_core_methods { () => {
|
||||
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_normal(self) -> bool { Float::is_normal(self) }
|
||||
pub fn is_normal(self) -> bool {
|
||||
self.classify() == FpCategory::Normal
|
||||
}
|
||||
|
||||
/// Returns the floating point category of the number. If only one property
|
||||
/// is going to be tested, it is generally faster to use the specific
|
||||
@ -374,8 +254,19 @@ macro_rules! f64_core_methods { () => {
|
||||
/// assert_eq!(inf.classify(), FpCategory::Infinite);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn classify(self) -> FpCategory { Float::classify(self) }
|
||||
pub fn classify(self) -> FpCategory {
|
||||
const EXP_MASK: u64 = 0x7ff0000000000000;
|
||||
const MAN_MASK: u64 = 0x000fffffffffffff;
|
||||
|
||||
let bits = self.to_bits();
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
(0, 0) => FpCategory::Zero,
|
||||
(_, 0) => FpCategory::Subnormal,
|
||||
(0, EXP_MASK) => FpCategory::Infinite,
|
||||
(_, EXP_MASK) => FpCategory::Nan,
|
||||
_ => FpCategory::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
@ -389,13 +280,17 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) }
|
||||
pub fn is_sign_positive(self) -> bool {
|
||||
!self.is_sign_negative()
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub fn is_positive(self) -> bool { Float::is_sign_positive(self) }
|
||||
pub fn is_positive(self) -> bool {
|
||||
self.is_sign_positive()
|
||||
}
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
@ -409,13 +304,17 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) }
|
||||
pub fn is_sign_negative(self) -> bool {
|
||||
self.to_bits() & 0x8000_0000_0000_0000 != 0
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub fn is_negative(self) -> bool { Float::is_sign_negative(self) }
|
||||
pub fn is_negative(self) -> bool {
|
||||
self.is_sign_negative()
|
||||
}
|
||||
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
@ -427,7 +326,9 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn recip(self) -> f64 { Float::recip(self) }
|
||||
pub fn recip(self) -> f64 {
|
||||
1.0 / self
|
||||
}
|
||||
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
@ -442,7 +343,12 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn to_degrees(self) -> f64 { Float::to_degrees(self) }
|
||||
pub fn to_degrees(self) -> f64 {
|
||||
// The division here is correctly rounded with respect to the true
|
||||
// value of 180/π. (This differs from f32, where a constant must be
|
||||
// used to ensure a correctly rounded result.)
|
||||
self * (180.0f64 / consts::PI)
|
||||
}
|
||||
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
@ -457,7 +363,10 @@ macro_rules! f64_core_methods { () => {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn to_radians(self) -> f64 { Float::to_radians(self) }
|
||||
pub fn to_radians(self) -> f64 {
|
||||
let value: f64 = consts::PI;
|
||||
self * (value / 180.0)
|
||||
}
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
@ -472,7 +381,15 @@ macro_rules! f64_core_methods { () => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn max(self, other: f64) -> f64 {
|
||||
Float::max(self, other)
|
||||
// IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if self.is_nan() || self < other { other } else { self }) * 1.0
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
@ -488,7 +405,15 @@ macro_rules! f64_core_methods { () => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn min(self, other: f64) -> f64 {
|
||||
Float::min(self, other)
|
||||
// IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
|
||||
// canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
|
||||
// is either x or y, canonicalized (this means results might differ among implementations).
|
||||
// When either x or y is a signalingNaN, then the result is according to 6.2.
|
||||
//
|
||||
// Since we do not support sNaN in Rust yet, we do not need to handle them.
|
||||
// FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
|
||||
// multiplying by 1.0. Should switch to the `canonicalize` when it works.
|
||||
(if other.is_nan() || self < other { self } else { other }) * 1.0
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u64`.
|
||||
@ -511,7 +436,7 @@ macro_rules! f64_core_methods { () => {
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn to_bits(self) -> u64 {
|
||||
Float::to_bits(self)
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u64`.
|
||||
@ -555,12 +480,7 @@ macro_rules! f64_core_methods { () => {
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn from_bits(v: u64) -> Self {
|
||||
Float::from_bits(v)
|
||||
// It turns out the safety issues with sNaN were overblown! Hooray!
|
||||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
}}
|
||||
|
||||
#[lang = "f64"]
|
||||
#[cfg(not(test))]
|
||||
impl f64 {
|
||||
f64_core_methods!();
|
||||
}
|
||||
|
@ -4080,61 +4080,6 @@ pub enum FpCategory {
|
||||
Normal,
|
||||
}
|
||||
|
||||
// Technically private and only exposed for coretests:
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "float_internals",
|
||||
reason = "internal routines only exposed for testing",
|
||||
issue = "0")]
|
||||
pub trait Float: Sized {
|
||||
/// Type used by `to_bits` and `from_bits`.
|
||||
type Bits;
|
||||
|
||||
/// Returns `true` if this value is NaN and false otherwise.
|
||||
fn is_nan(self) -> bool;
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
fn is_infinite(self) -> bool;
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor NaN.
|
||||
fn is_finite(self) -> bool;
|
||||
|
||||
/// Returns `true` if this number is neither zero, infinite, denormal, or NaN.
|
||||
fn is_normal(self) -> bool;
|
||||
|
||||
/// Returns the category that this number falls into.
|
||||
fn classify(self) -> FpCategory;
|
||||
|
||||
/// Returns `true` if `self` is positive, including `+0.0` and
|
||||
/// `Float::infinity()`.
|
||||
fn is_sign_positive(self) -> bool;
|
||||
|
||||
/// Returns `true` if `self` is negative, including `-0.0` and
|
||||
/// `Float::neg_infinity()`.
|
||||
fn is_sign_negative(self) -> bool;
|
||||
|
||||
/// Take the reciprocal (inverse) of a number, `1/x`.
|
||||
fn recip(self) -> Self;
|
||||
|
||||
/// Convert radians to degrees.
|
||||
fn to_degrees(self) -> Self;
|
||||
|
||||
/// Convert degrees to radians.
|
||||
fn to_radians(self) -> Self;
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
fn max(self, other: Self) -> Self;
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
fn min(self, other: Self) -> Self;
|
||||
|
||||
/// Raw transmutation to integer.
|
||||
fn to_bits(self) -> Self::Bits;
|
||||
|
||||
/// Raw transmutation from integer.
|
||||
fn from_bits(v: Self::Bits) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! from_str_radix_int_impl {
|
||||
($($t:ty)*) => {$(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -508,51 +508,50 @@ assume_usize_width! {
|
||||
|
||||
macro_rules! test_float {
|
||||
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => { mod $modname {
|
||||
use core::num::Float;
|
||||
// FIXME(nagisa): these tests should test for sign of -0.0
|
||||
#[test]
|
||||
fn min() {
|
||||
assert_eq!(0.0.min(0.0), 0.0);
|
||||
assert_eq!((-0.0).min(-0.0), -0.0);
|
||||
assert_eq!(9.0.min(9.0), 9.0);
|
||||
assert_eq!((-9.0).min(0.0), -9.0);
|
||||
assert_eq!(0.0.min(9.0), 0.0);
|
||||
assert_eq!((-0.0).min(-9.0), -9.0);
|
||||
assert_eq!($inf.min(9.0), 9.0);
|
||||
assert_eq!(9.0.min($inf), 9.0);
|
||||
assert_eq!($inf.min(-9.0), -9.0);
|
||||
assert_eq!((-9.0).min($inf), -9.0);
|
||||
assert_eq!($neginf.min(9.0), $neginf);
|
||||
assert_eq!(9.0.min($neginf), $neginf);
|
||||
assert_eq!($neginf.min(-9.0), $neginf);
|
||||
assert_eq!((-9.0).min($neginf), $neginf);
|
||||
assert_eq!($nan.min(9.0), 9.0);
|
||||
assert_eq!($nan.min(-9.0), -9.0);
|
||||
assert_eq!(9.0.min($nan), 9.0);
|
||||
assert_eq!((-9.0).min($nan), -9.0);
|
||||
assert!($nan.min($nan).is_nan());
|
||||
assert_eq!((0.0 as $fty).min(0.0), 0.0);
|
||||
assert_eq!((-0.0 as $fty).min(-0.0), -0.0);
|
||||
assert_eq!((9.0 as $fty).min(9.0), 9.0);
|
||||
assert_eq!((-9.0 as $fty).min(0.0), -9.0);
|
||||
assert_eq!((0.0 as $fty).min(9.0), 0.0);
|
||||
assert_eq!((-0.0 as $fty).min(-9.0), -9.0);
|
||||
assert_eq!(($inf as $fty).min(9.0), 9.0);
|
||||
assert_eq!((9.0 as $fty).min($inf), 9.0);
|
||||
assert_eq!(($inf as $fty).min(-9.0), -9.0);
|
||||
assert_eq!((-9.0 as $fty).min($inf), -9.0);
|
||||
assert_eq!(($neginf as $fty).min(9.0), $neginf);
|
||||
assert_eq!((9.0 as $fty).min($neginf), $neginf);
|
||||
assert_eq!(($neginf as $fty).min(-9.0), $neginf);
|
||||
assert_eq!((-9.0 as $fty).min($neginf), $neginf);
|
||||
assert_eq!(($nan as $fty).min(9.0), 9.0);
|
||||
assert_eq!(($nan as $fty).min(-9.0), -9.0);
|
||||
assert_eq!((9.0 as $fty).min($nan), 9.0);
|
||||
assert_eq!((-9.0 as $fty).min($nan), -9.0);
|
||||
assert!(($nan as $fty).min($nan).is_nan());
|
||||
}
|
||||
#[test]
|
||||
fn max() {
|
||||
assert_eq!(0.0.max(0.0), 0.0);
|
||||
assert_eq!((-0.0).max(-0.0), -0.0);
|
||||
assert_eq!(9.0.max(9.0), 9.0);
|
||||
assert_eq!((-9.0).max(0.0), 0.0);
|
||||
assert_eq!(0.0.max(9.0), 9.0);
|
||||
assert_eq!((-0.0).max(-9.0), -0.0);
|
||||
assert_eq!($inf.max(9.0), $inf);
|
||||
assert_eq!(9.0.max($inf), $inf);
|
||||
assert_eq!($inf.max(-9.0), $inf);
|
||||
assert_eq!((-9.0).max($inf), $inf);
|
||||
assert_eq!($neginf.max(9.0), 9.0);
|
||||
assert_eq!(9.0.max($neginf), 9.0);
|
||||
assert_eq!($neginf.max(-9.0), -9.0);
|
||||
assert_eq!((-9.0).max($neginf), -9.0);
|
||||
assert_eq!($nan.max(9.0), 9.0);
|
||||
assert_eq!($nan.max(-9.0), -9.0);
|
||||
assert_eq!(9.0.max($nan), 9.0);
|
||||
assert_eq!((-9.0).max($nan), -9.0);
|
||||
assert!($nan.max($nan).is_nan());
|
||||
assert_eq!((0.0 as $fty).max(0.0), 0.0);
|
||||
assert_eq!((-0.0 as $fty).max(-0.0), -0.0);
|
||||
assert_eq!((9.0 as $fty).max(9.0), 9.0);
|
||||
assert_eq!((-9.0 as $fty).max(0.0), 0.0);
|
||||
assert_eq!((0.0 as $fty).max(9.0), 9.0);
|
||||
assert_eq!((-0.0 as $fty).max(-9.0), -0.0);
|
||||
assert_eq!(($inf as $fty).max(9.0), $inf);
|
||||
assert_eq!((9.0 as $fty).max($inf), $inf);
|
||||
assert_eq!(($inf as $fty).max(-9.0), $inf);
|
||||
assert_eq!((-9.0 as $fty).max($inf), $inf);
|
||||
assert_eq!(($neginf as $fty).max(9.0), 9.0);
|
||||
assert_eq!((9.0 as $fty).max($neginf), 9.0);
|
||||
assert_eq!(($neginf as $fty).max(-9.0), -9.0);
|
||||
assert_eq!((-9.0 as $fty).max($neginf), -9.0);
|
||||
assert_eq!(($nan as $fty).max(9.0), 9.0);
|
||||
assert_eq!(($nan as $fty).max(-9.0), -9.0);
|
||||
assert_eq!((9.0 as $fty).max($nan), 9.0);
|
||||
assert_eq!((-9.0 as $fty).max($nan), -9.0);
|
||||
assert!(($nan as $fty).max($nan).is_nan());
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
@ -4552,23 +4552,25 @@ but the type of the numeric value or binding could not be identified.
|
||||
The error happens on numeric literals:
|
||||
|
||||
```compile_fail,E0689
|
||||
2.0.recip();
|
||||
2.0.neg();
|
||||
```
|
||||
|
||||
and on numeric bindings without an identified concrete type:
|
||||
|
||||
```compile_fail,E0689
|
||||
let x = 2.0;
|
||||
x.recip(); // same error as above
|
||||
x.neg(); // same error as above
|
||||
```
|
||||
|
||||
Because of this, you must give the numeric literal or binding a type:
|
||||
|
||||
```
|
||||
let _ = 2.0_f32.recip();
|
||||
use std::ops::Neg;
|
||||
|
||||
let _ = 2.0_f32.neg();
|
||||
let x: f32 = 2.0;
|
||||
let _ = x.recip();
|
||||
let _ = (2.0 as f32).recip();
|
||||
let _ = x.neg();
|
||||
let _ = (2.0 as f32).neg();
|
||||
```
|
||||
"##,
|
||||
|
||||
|
@ -48,13 +48,13 @@ macro_rules! fake_anon_field_expr {
|
||||
|
||||
macro_rules! real_method_stmt {
|
||||
() => {
|
||||
2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
2.0.neg() //~ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! real_method_expr {
|
||||
() => {
|
||||
2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
2.0.neg() //~ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,17 +25,17 @@ LL | (1).0 //~ ERROR doesn't have fields
|
||||
LL | fake_anon_field_stmt!();
|
||||
| ------------------------ in this macro invocation
|
||||
|
||||
error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
|
||||
error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:51:15
|
||||
|
|
||||
LL | 2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
| ^^^^^
|
||||
LL | 2.0.neg() //~ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
| ^^^
|
||||
...
|
||||
LL | real_method_stmt!();
|
||||
| -------------------- in this macro invocation
|
||||
help: you must specify a concrete type for this numeric value, like `f32`
|
||||
|
|
||||
LL | 2.0_f32.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
LL | 2.0_f32.neg() //~ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0599]: no method named `fake` found for type `{integer}` in the current scope
|
||||
@ -65,17 +65,17 @@ LL | (1).0 //~ ERROR doesn't have fields
|
||||
LL | let _ = fake_anon_field_expr!();
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
|
||||
error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:57:15
|
||||
|
|
||||
LL | 2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
| ^^^^^
|
||||
LL | 2.0.neg() //~ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
| ^^^
|
||||
...
|
||||
LL | let _ = real_method_expr!();
|
||||
| ------------------- in this macro invocation
|
||||
help: you must specify a concrete type for this numeric value, like `f32`
|
||||
|
|
||||
LL | 2.0_f32.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
LL | 2.0_f32.neg() //~ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
@ -9,10 +9,10 @@
|
||||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
let x = 2.0.recip();
|
||||
//~^ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
let x = 2.0.neg();
|
||||
//~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
let y = 2.0;
|
||||
let x = y.recip();
|
||||
//~^ ERROR can't call method `recip` on ambiguous numeric type `{float}`
|
||||
let x = y.neg();
|
||||
//~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
|
||||
error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
|
||||
--> $DIR/method-on-ambiguous-numeric-type.rs:12:17
|
||||
|
|
||||
LL | let x = 2.0.recip();
|
||||
| ^^^^^
|
||||
LL | let x = 2.0.neg();
|
||||
| ^^^
|
||||
help: you must specify a concrete type for this numeric value, like `f32`
|
||||
|
|
||||
LL | let x = 2.0_f32.recip();
|
||||
LL | let x = 2.0_f32.neg();
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
|
||||
error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
|
||||
--> $DIR/method-on-ambiguous-numeric-type.rs:15:15
|
||||
|
|
||||
LL | let x = y.recip();
|
||||
| ^^^^^
|
||||
LL | let x = y.neg();
|
||||
| ^^^
|
||||
help: you must specify a type for this binding, like `f32`
|
||||
|
|
||||
LL | let y: f32 = 2.0;
|
||||
|
Loading…
Reference in New Issue
Block a user