Make all methods of `Duration` const

Make the following methods of `Duration` unstable const under `duration_const_2`:
 - `from_secs_f64`
 - `from_secs_f32`
 - `mul_f64`
 - `mul_f32`
 - `div_f64`
 - `div_f32`

This results in all methods of `Duration` being (unstable) const.

Also adds tests for these methods in a const context, moved the test to `library` as part of #76268.

Possible because of #72449, which made the relevant `f32` and `f64` methods const.

Tracking issue: #72440
This commit is contained in:
Christiaan Dirkx 2020-09-04 20:17:06 +02:00
parent 2d6cbd21b2
commit 73e0a56dde
4 changed files with 116 additions and 73 deletions

View File

@ -693,7 +693,8 @@ impl Duration {
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn from_secs_f64(secs: f64) -> Duration {
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn from_secs_f64(secs: f64) -> Duration {
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() {
@ -727,7 +728,8 @@ impl Duration {
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn from_secs_f32(secs: f32) -> Duration {
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn from_secs_f32(secs: f32) -> Duration {
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() {
@ -761,7 +763,8 @@ impl Duration {
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn mul_f64(self, rhs: f64) -> Duration {
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn mul_f64(self, rhs: f64) -> Duration {
Duration::from_secs_f64(rhs * self.as_secs_f64())
}
@ -782,7 +785,8 @@ impl Duration {
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn mul_f32(self, rhs: f32) -> Duration {
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn mul_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(rhs * self.as_secs_f32())
}
@ -802,7 +806,8 @@ impl Duration {
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn div_f64(self, rhs: f64) -> Duration {
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn div_f64(self, rhs: f64) -> Duration {
Duration::from_secs_f64(self.as_secs_f64() / rhs)
}
@ -824,7 +829,8 @@ impl Duration {
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[inline]
pub fn div_f32(self, rhs: f32) -> Duration {
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn div_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(self.as_secs_f32() / rhs)
}

View File

@ -10,8 +10,11 @@
#![feature(core_private_diy_float)]
#![feature(debug_non_exhaustive)]
#![feature(dec2flt)]
#![feature(div_duration)]
#![feature(duration_consts_2)]
#![feature(duration_constants)]
#![feature(duration_saturating_ops)]
#![feature(duration_zero)]
#![feature(exact_size_is_empty)]
#![feature(fixed_size_array)]
#![feature(flt2dec)]

View File

@ -321,3 +321,104 @@ fn debug_formatting_precision_high() {
assert_eq!(format!("{:.10?}", Duration::new(4, 001_000_000)), "4.0010000000s");
assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s");
}
#[test]
fn duration_const() {
// test that the methods of `Duration` are usable in a const context
const DURATION: Duration = Duration::new(0, 123_456_789);
const SUB_SEC_MILLIS: u32 = DURATION.subsec_millis();
assert_eq!(SUB_SEC_MILLIS, 123);
const SUB_SEC_MICROS: u32 = DURATION.subsec_micros();
assert_eq!(SUB_SEC_MICROS, 123_456);
const SUB_SEC_NANOS: u32 = DURATION.subsec_nanos();
assert_eq!(SUB_SEC_NANOS, 123_456_789);
const ZERO: Duration = Duration::zero();
assert_eq!(ZERO, Duration::new(0, 0));
const IS_ZERO: bool = ZERO.is_zero();
assert!(IS_ZERO);
const ONE: Duration = Duration::new(1, 0);
const SECONDS: u64 = ONE.as_secs();
assert_eq!(SECONDS, 1);
const FROM_SECONDS: Duration = Duration::from_secs(1);
assert_eq!(FROM_SECONDS, ONE);
const SECONDS_F32: f32 = ONE.as_secs_f32();
assert_eq!(SECONDS_F32, 1.0);
const FROM_SECONDS_F32: Duration = Duration::from_secs_f32(1.0);
assert_eq!(FROM_SECONDS_F32, ONE);
const SECONDS_F64: f64 = ONE.as_secs_f64();
assert_eq!(SECONDS_F64, 1.0);
const FROM_SECONDS_F64: Duration = Duration::from_secs_f64(1.0);
assert_eq!(FROM_SECONDS_F64, ONE);
const MILLIS: u128 = ONE.as_millis();
assert_eq!(MILLIS, 1_000);
const FROM_MILLIS: Duration = Duration::from_millis(1_000);
assert_eq!(FROM_MILLIS, ONE);
const MICROS: u128 = ONE.as_micros();
assert_eq!(MICROS, 1_000_000);
const FROM_MICROS: Duration = Duration::from_micros(1_000_000);
assert_eq!(FROM_MICROS, ONE);
const NANOS: u128 = ONE.as_nanos();
assert_eq!(NANOS, 1_000_000_000);
const FROM_NANOS: Duration = Duration::from_nanos(1_000_000_000);
assert_eq!(FROM_NANOS, ONE);
const MAX: Duration = Duration::new(u64::MAX, 999_999_999);
const CHECKED_ADD: Option<Duration> = MAX.checked_add(ONE);
assert_eq!(CHECKED_ADD, None);
const CHECKED_SUB: Option<Duration> = ZERO.checked_sub(ONE);
assert_eq!(CHECKED_SUB, None);
const CHECKED_MUL: Option<Duration> = ONE.checked_mul(1);
assert_eq!(CHECKED_MUL, Some(ONE));
const MUL_F32: Duration = ONE.mul_f32(1.0);
assert_eq!(MUL_F32, ONE);
const MUL_F64: Duration = ONE.mul_f64(1.0);
assert_eq!(MUL_F64, ONE);
const CHECKED_DIV: Option<Duration> = ONE.checked_div(1);
assert_eq!(CHECKED_DIV, Some(ONE));
const DIV_F32: Duration = ONE.div_f32(1.0);
assert_eq!(DIV_F32, ONE);
const DIV_F64: Duration = ONE.div_f64(1.0);
assert_eq!(DIV_F64, ONE);
const DIV_DURATION_F32: f32 = ONE.div_duration_f32(ONE);
assert_eq!(DIV_DURATION_F32, 1.0);
const DIV_DURATION_F64: f64 = ONE.div_duration_f64(ONE);
assert_eq!(DIV_DURATION_F64, 1.0);
const SATURATING_ADD: Duration = MAX.saturating_add(ONE);
assert_eq!(SATURATING_ADD, MAX);
const SATURATING_SUB: Duration = ZERO.saturating_sub(ONE);
assert_eq!(SATURATING_SUB, ZERO);
const SATURATING_MUL: Duration = MAX.saturating_mul(2);
assert_eq!(SATURATING_MUL, MAX);
}

View File

@ -1,67 +0,0 @@
// run-pass
#![feature(const_panic)]
#![feature(duration_consts_2)]
#![feature(div_duration)]
#![feature(duration_saturating_ops)]
use std::time::Duration;
fn duration() {
const ZERO : Duration = Duration::new(0, 0);
assert_eq!(ZERO, Duration::from_secs(0));
const ONE : Duration = Duration::new(0, 1);
assert_eq!(ONE, Duration::from_nanos(1));
const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1);
const MAX_CHECKED_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
assert_eq!(MAX_CHECKED_ADD_ZERO, Some(MAX));
const MAX_CHECKED_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
assert_eq!(MAX_CHECKED_ADD_ONE, None);
const ONE_CHECKED_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
assert_eq!(ONE_CHECKED_SUB_ONE, Some(ZERO));
const ZERO_CHECKED_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
assert_eq!(ZERO_CHECKED_SUB_ONE, None);
const ONE_CHECKED_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
assert_eq!(ONE_CHECKED_MUL_ONE, Some(ONE));
const MAX_CHECKED_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
assert_eq!(MAX_CHECKED_MUL_TWO, None);
const ONE_CHECKED_DIV_ONE : Option<Duration> = ONE.checked_div(1);
assert_eq!(ONE_CHECKED_DIV_ONE, Some(ONE));
const ONE_CHECKED_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
assert_eq!(ONE_CHECKED_DIV_ZERO, None);
const MAX_AS_F32 : f32 = MAX.as_secs_f32();
assert_eq!(MAX_AS_F32, 18446744000000000000.0_f32);
const MAX_AS_F64 : f64 = MAX.as_secs_f64();
assert_eq!(MAX_AS_F64, 18446744073709552000.0_f64);
const ONE_AS_F32 : f32 = ONE.div_duration_f32(ONE);
assert_eq!(ONE_AS_F32, 1.0_f32);
const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE);
assert_eq!(ONE_AS_F64, 1.0_f64);
const MAX_SATURATING_ADD_ONE : Duration = MAX.saturating_add(ONE);
assert_eq!(MAX_SATURATING_ADD_ONE, MAX);
const ZERO_SATURATING_SUB_ONE : Duration = ZERO.saturating_sub(ONE);
assert_eq!(ZERO_SATURATING_SUB_ONE, ZERO);
const MAX_SATURATING_MUL_TWO : Duration = MAX.saturating_mul(2);
assert_eq!(MAX_SATURATING_MUL_TWO, MAX);
}
fn main() {
duration();
}