Skip to content

Commit

Permalink
Make all methods of Duration const
Browse files Browse the repository at this point in the history
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
  • Loading branch information
CDirkx committed Sep 12, 2020
1 parent 2d6cbd2 commit 73e0a56
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 73 deletions.
18 changes: 12 additions & 6 deletions library/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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())
}

Expand All @@ -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())
}

Expand All @@ -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)
}

Expand All @@ -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)
}

Expand Down
3 changes: 3 additions & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
101 changes: 101 additions & 0 deletions library/core/tests/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
67 changes: 0 additions & 67 deletions src/test/ui/consts/duration-consts-2.rs

This file was deleted.

0 comments on commit 73e0a56

Please sign in to comment.