Improve Duration::try_from_secs_f32/64 accuracy by directly processing exponent and mantissa
This commit is contained in:
parent
788b1fe5b7
commit
e0bcf771d6
3 changed files with 202 additions and 103 deletions
|
@ -711,14 +711,28 @@ impl Duration {
|
||||||
/// as `f64`.
|
/// as `f64`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
|
/// This constructor will panic if `secs` is negative, overflows `Duration` or not finite.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::time::Duration;
|
/// use std::time::Duration;
|
||||||
///
|
///
|
||||||
/// let dur = Duration::from_secs_f64(2.7);
|
/// let res = Duration::from_secs_f64(0.0);
|
||||||
/// assert_eq!(dur, Duration::new(2, 700_000_000));
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
|
/// let res = Duration::from_secs_f64(1e-20);
|
||||||
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
|
/// let res = Duration::from_secs_f64(4.2e-7);
|
||||||
|
/// assert_eq!(res, Duration::new(0, 420));
|
||||||
|
/// let res = Duration::from_secs_f64(2.7);
|
||||||
|
/// assert_eq!(res, Duration::new(2, 700_000_000));
|
||||||
|
/// let res = Duration::from_secs_f64(3e10);
|
||||||
|
/// assert_eq!(res, Duration::new(30_000_000_000, 0));
|
||||||
|
/// // subnormal float
|
||||||
|
/// let res = Duration::from_secs_f64(f64::from_bits(1));
|
||||||
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
|
/// // conversion uses truncation, not rounding
|
||||||
|
/// let res = Duration::from_secs_f64(0.999e-9);
|
||||||
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -731,55 +745,32 @@ impl Duration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The checked version of [`from_secs_f64`].
|
|
||||||
///
|
|
||||||
/// [`from_secs_f64`]: Duration::from_secs_f64
|
|
||||||
///
|
|
||||||
/// This constructor will return an `Err` if `secs` is not finite, negative or overflows `Duration`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
/// ```
|
|
||||||
/// #![feature(duration_checked_float)]
|
|
||||||
/// use std::time::Duration;
|
|
||||||
///
|
|
||||||
/// let dur = Duration::try_from_secs_f64(2.7);
|
|
||||||
/// assert_eq!(dur, Ok(Duration::new(2, 700_000_000)));
|
|
||||||
///
|
|
||||||
/// let negative = Duration::try_from_secs_f64(-5.0);
|
|
||||||
/// assert!(negative.is_err());
|
|
||||||
/// ```
|
|
||||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
|
||||||
#[inline]
|
|
||||||
pub const fn try_from_secs_f64(secs: f64) -> Result<Duration, FromSecsError> {
|
|
||||||
const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
|
|
||||||
let nanos = secs * (NANOS_PER_SEC as f64);
|
|
||||||
if !nanos.is_finite() {
|
|
||||||
Err(FromSecsError { kind: FromSecsErrorKind::NonFinite })
|
|
||||||
} else if nanos >= MAX_NANOS_F64 {
|
|
||||||
Err(FromSecsError { kind: FromSecsErrorKind::Overflow })
|
|
||||||
} else if nanos < 0.0 {
|
|
||||||
Err(FromSecsError { kind: FromSecsErrorKind::Negative })
|
|
||||||
} else {
|
|
||||||
let nanos = nanos as u128;
|
|
||||||
Ok(Duration {
|
|
||||||
secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
|
|
||||||
nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new `Duration` from the specified number of seconds represented
|
/// Creates a new `Duration` from the specified number of seconds represented
|
||||||
/// as `f32`.
|
/// as `f32`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
|
/// This constructor will panic if `secs` is negative, overflows `Duration` or not finite.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::time::Duration;
|
/// use std::time::Duration;
|
||||||
///
|
///
|
||||||
/// let dur = Duration::from_secs_f32(2.7);
|
/// let res = Duration::from_secs_f32(0.0);
|
||||||
/// assert_eq!(dur, Duration::new(2, 700_000_000));
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
|
/// let res = Duration::from_secs_f32(1e-20);
|
||||||
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
|
/// let res = Duration::from_secs_f32(4.2e-7);
|
||||||
|
/// assert_eq!(res, Duration::new(0, 419));
|
||||||
|
/// let res = Duration::from_secs_f32(2.7);
|
||||||
|
/// assert_eq!(res, Duration::new(2, 700_000_047));
|
||||||
|
/// let res = Duration::from_secs_f32(3e10);
|
||||||
|
/// assert_eq!(res, Duration::new(30_000_001_024, 0));
|
||||||
|
/// // subnormal float
|
||||||
|
/// let res = Duration::from_secs_f32(f32::from_bits(1));
|
||||||
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
|
/// // conversion uses truncation, not rounding
|
||||||
|
/// let res = Duration::from_secs_f32(0.999e-9);
|
||||||
|
/// assert_eq!(res, Duration::new(0, 0));
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -792,47 +783,10 @@ impl Duration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The checked version of [`from_secs_f32`].
|
|
||||||
///
|
|
||||||
/// [`from_secs_f32`]: Duration::from_secs_f32
|
|
||||||
///
|
|
||||||
/// This constructor will return an `Err` if `secs` is not finite, negative or overflows `Duration`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
/// ```
|
|
||||||
/// #![feature(duration_checked_float)]
|
|
||||||
/// use std::time::Duration;
|
|
||||||
///
|
|
||||||
/// let dur = Duration::try_from_secs_f32(2.7);
|
|
||||||
/// assert_eq!(dur, Ok(Duration::new(2, 700_000_000)));
|
|
||||||
///
|
|
||||||
/// let negative = Duration::try_from_secs_f32(-5.0);
|
|
||||||
/// assert!(negative.is_err());
|
|
||||||
/// ```
|
|
||||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
|
||||||
#[inline]
|
|
||||||
pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, FromSecsError> {
|
|
||||||
const MAX_NANOS_F32: f32 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f32;
|
|
||||||
let nanos = secs * (NANOS_PER_SEC as f32);
|
|
||||||
if !nanos.is_finite() {
|
|
||||||
Err(FromSecsError { kind: FromSecsErrorKind::NonFinite })
|
|
||||||
} else if nanos >= MAX_NANOS_F32 {
|
|
||||||
Err(FromSecsError { kind: FromSecsErrorKind::Overflow })
|
|
||||||
} else if nanos < 0.0 {
|
|
||||||
Err(FromSecsError { kind: FromSecsErrorKind::Negative })
|
|
||||||
} else {
|
|
||||||
let nanos = nanos as u128;
|
|
||||||
Ok(Duration {
|
|
||||||
secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
|
|
||||||
nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Multiplies `Duration` by `f64`.
|
/// Multiplies `Duration` by `f64`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This method will panic if result is not finite, negative or overflows `Duration`.
|
/// This method will panic if result is negative, overflows `Duration` or not finite.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -854,17 +808,15 @@ impl Duration {
|
||||||
/// Multiplies `Duration` by `f32`.
|
/// Multiplies `Duration` by `f32`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This method will panic if result is not finite, negative or overflows `Duration`.
|
/// This method will panic if result is negative, overflows `Duration` or not finite.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::time::Duration;
|
/// use std::time::Duration;
|
||||||
///
|
///
|
||||||
/// let dur = Duration::new(2, 700_000_000);
|
/// let dur = Duration::new(2, 700_000_000);
|
||||||
/// // note that due to rounding errors result is slightly different
|
|
||||||
/// // from 8.478 and 847800.0
|
|
||||||
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
|
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
|
||||||
/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
|
/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847800, 0));
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||||
#[must_use = "this returns the result of the operation, \
|
#[must_use = "this returns the result of the operation, \
|
||||||
|
@ -878,7 +830,7 @@ impl Duration {
|
||||||
/// Divide `Duration` by `f64`.
|
/// Divide `Duration` by `f64`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This method will panic if result is not finite, negative or overflows `Duration`.
|
/// This method will panic if result is negative, overflows `Duration` or not finite.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -901,7 +853,7 @@ impl Duration {
|
||||||
/// Divide `Duration` by `f32`.
|
/// Divide `Duration` by `f32`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This method will panic if result is not finite, negative or overflows `Duration`.
|
/// This method will panic if result is negative, overflows `Duration` or not finite.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -910,7 +862,7 @@ impl Duration {
|
||||||
/// let dur = Duration::new(2, 700_000_000);
|
/// let dur = Duration::new(2, 700_000_000);
|
||||||
/// // note that due to rounding errors result is slightly
|
/// // note that due to rounding errors result is slightly
|
||||||
/// // different from 0.859_872_611
|
/// // different from 0.859_872_611
|
||||||
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576));
|
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_579));
|
||||||
/// // note that truncation is used, not rounding
|
/// // note that truncation is used, not rounding
|
||||||
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
|
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -1267,33 +1219,180 @@ impl fmt::Debug for Duration {
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||||
pub struct FromSecsError {
|
pub struct FromFloatSecsError {
|
||||||
kind: FromSecsErrorKind,
|
kind: FromFloatSecsErrorKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSecsError {
|
impl FromFloatSecsError {
|
||||||
const fn description(&self) -> &'static str {
|
const fn description(&self) -> &'static str {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
FromSecsErrorKind::NonFinite => "non-finite value when converting float to duration",
|
FromFloatSecsErrorKind::Negative => {
|
||||||
FromSecsErrorKind::Overflow => "overflow when converting float to duration",
|
"can not convert float seconds to Duration: value is negative"
|
||||||
FromSecsErrorKind::Negative => "negative value when converting float to duration",
|
}
|
||||||
|
FromFloatSecsErrorKind::OverflowOrNan => {
|
||||||
|
"can not convert float seconds to Duration: value is either too big or NaN"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||||
impl fmt::Display for FromSecsError {
|
impl fmt::Display for FromFloatSecsError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Display::fmt(self.description(), f)
|
self.description().fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
enum FromSecsErrorKind {
|
enum FromFloatSecsErrorKind {
|
||||||
// Value is not a finite value (either + or - infinity or NaN).
|
|
||||||
NonFinite,
|
|
||||||
// Value is too large to store in a `Duration`.
|
|
||||||
Overflow,
|
|
||||||
// Value is negative.
|
// Value is negative.
|
||||||
Negative,
|
Negative,
|
||||||
|
// Value is either too big to be represented as `Duration` or `NaN`.
|
||||||
|
OverflowOrNan,
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! try_from_secs {
|
||||||
|
(
|
||||||
|
secs = $secs: expr,
|
||||||
|
mantissa_bits = $mant_bits: literal,
|
||||||
|
exponent_bits = $exp_bits: literal,
|
||||||
|
offset = $offset: literal,
|
||||||
|
bits_ty = $bits_ty:ty,
|
||||||
|
double_ty = $double_ty:ty,
|
||||||
|
) => {{
|
||||||
|
const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
|
||||||
|
const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
|
||||||
|
const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
|
||||||
|
|
||||||
|
if $secs.is_sign_negative() {
|
||||||
|
return Err(FromFloatSecsError { kind: FromFloatSecsErrorKind::Negative });
|
||||||
|
}
|
||||||
|
|
||||||
|
let bits = $secs.to_bits();
|
||||||
|
let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
|
||||||
|
let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
|
||||||
|
|
||||||
|
let (secs, nanos) = if exp < -30 {
|
||||||
|
// the input represents less than 1ns.
|
||||||
|
(0u64, 0u32)
|
||||||
|
} else if exp < 0 {
|
||||||
|
// the input is less than 1 second
|
||||||
|
let t = <$double_ty>::from(mant) << ($offset + exp);
|
||||||
|
let nanos = (u128::from(NANOS_PER_SEC) * u128::from(t)) >> ($mant_bits + $offset);
|
||||||
|
(0, nanos as u32)
|
||||||
|
} else if exp < $mant_bits {
|
||||||
|
let secs = mant >> ($mant_bits - exp);
|
||||||
|
let t = <$double_ty>::from((mant << exp) & MANT_MASK);
|
||||||
|
let nanos = (<$double_ty>::from(NANOS_PER_SEC) * t) >> $mant_bits;
|
||||||
|
(u64::from(secs), nanos as u32)
|
||||||
|
} else if exp < 64 {
|
||||||
|
// the input has no fractional part
|
||||||
|
let secs = u64::from(mant) << (exp - $mant_bits);
|
||||||
|
(secs, 0)
|
||||||
|
} else {
|
||||||
|
return Err(FromFloatSecsError { kind: FromFloatSecsErrorKind::OverflowOrNan });
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Duration { secs, nanos })
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Duration {
|
||||||
|
/// The checked version of [`from_secs_f32`].
|
||||||
|
///
|
||||||
|
/// [`from_secs_f32`]: Duration::from_secs_f32
|
||||||
|
///
|
||||||
|
/// This constructor will return an `Err` if `secs` is negative, overflows `Duration` or not finite.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// #![feature(duration_checked_float)]
|
||||||
|
///
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let res = Duration::try_from_secs_f32(0.0);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
/// let res = Duration::try_from_secs_f32(1e-20);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
/// let res = Duration::try_from_secs_f32(4.2e-7);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 419)));
|
||||||
|
/// let res = Duration::try_from_secs_f32(2.7);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(2, 700_000_047)));
|
||||||
|
/// let res = Duration::try_from_secs_f32(3e10);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(30_000_001_024, 0)));
|
||||||
|
/// // subnormal float:
|
||||||
|
/// let res = Duration::try_from_secs_f32(f32::from_bits(1));
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
/// // conversion uses truncation, not rounding
|
||||||
|
/// let res = Duration::try_from_secs_f32(0.999e-9);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
///
|
||||||
|
/// let res = Duration::try_from_secs_f32(-5.0);
|
||||||
|
/// assert!(res.is_err());
|
||||||
|
/// let res = Duration::try_from_secs_f32(f32::NAN);
|
||||||
|
/// assert!(res.is_err());
|
||||||
|
/// let res = Duration::try_from_secs_f32(2e19);
|
||||||
|
/// assert!(res.is_err());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||||
|
#[inline]
|
||||||
|
pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, FromFloatSecsError> {
|
||||||
|
try_from_secs!(
|
||||||
|
secs = secs,
|
||||||
|
mantissa_bits = 23,
|
||||||
|
exponent_bits = 8,
|
||||||
|
offset = 41,
|
||||||
|
bits_ty = u32,
|
||||||
|
double_ty = u64,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The checked version of [`from_secs_f64`].
|
||||||
|
///
|
||||||
|
/// [`from_secs_f64`]: Duration::from_secs_f64
|
||||||
|
///
|
||||||
|
/// This constructor will return an `Err` if `secs` is negative, overflows `Duration` or not finite.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// #![feature(duration_checked_float)]
|
||||||
|
///
|
||||||
|
/// use std::time::Duration;
|
||||||
|
///
|
||||||
|
/// let res = Duration::try_from_secs_f64(0.0);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
/// let res = Duration::try_from_secs_f64(1e-20);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
/// let res = Duration::try_from_secs_f64(4.2e-7);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 420)));
|
||||||
|
/// let res = Duration::try_from_secs_f64(2.7);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(2, 700_000_000)));
|
||||||
|
/// let res = Duration::try_from_secs_f64(3e10);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(30_000_000_000, 0)));
|
||||||
|
/// // subnormal float
|
||||||
|
/// let res = Duration::try_from_secs_f64(f64::from_bits(1));
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
/// // conversion uses truncation, not rounding
|
||||||
|
/// let res = Duration::try_from_secs_f32(0.999e-9);
|
||||||
|
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||||
|
///
|
||||||
|
/// let res = Duration::try_from_secs_f64(-5.0);
|
||||||
|
/// assert!(res.is_err());
|
||||||
|
/// let res = Duration::try_from_secs_f64(f64::NAN);
|
||||||
|
/// assert!(res.is_err());
|
||||||
|
/// let res = Duration::try_from_secs_f64(2e19);
|
||||||
|
/// assert!(res.is_err());
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||||
|
#[inline]
|
||||||
|
pub const fn try_from_secs_f64(secs: f64) -> Result<Duration, FromFloatSecsError> {
|
||||||
|
try_from_secs!(
|
||||||
|
secs = secs,
|
||||||
|
mantissa_bits = 52,
|
||||||
|
exponent_bits = 11,
|
||||||
|
offset = 44,
|
||||||
|
bits_ty = u64,
|
||||||
|
double_ty = u128,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,7 +602,7 @@ impl Error for char::ParseCharError {
|
||||||
impl Error for alloc::collections::TryReserveError {}
|
impl Error for alloc::collections::TryReserveError {}
|
||||||
|
|
||||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||||
impl Error for time::FromSecsError {}
|
impl Error for time::FromFloatSecsError {}
|
||||||
|
|
||||||
// Copied from `any.rs`.
|
// Copied from `any.rs`.
|
||||||
impl dyn Error + 'static {
|
impl dyn Error + 'static {
|
||||||
|
|
|
@ -45,7 +45,7 @@ use crate::sys_common::FromInner;
|
||||||
pub use core::time::Duration;
|
pub use core::time::Duration;
|
||||||
|
|
||||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||||
pub use core::time::FromSecsError;
|
pub use core::time::FromFloatSecsError;
|
||||||
|
|
||||||
/// A measurement of a monotonically nondecreasing clock.
|
/// A measurement of a monotonically nondecreasing clock.
|
||||||
/// Opaque and useful only with [`Duration`].
|
/// Opaque and useful only with [`Duration`].
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue