Skip to content

Commit 7527409

Browse files
committed
Constify most non-trait Duration methods as described in #72440
1 parent 91fb72a commit 7527409

File tree

3 files changed

+87
-19
lines changed

3 files changed

+87
-19
lines changed

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
#![feature(custom_inner_attributes)]
9595
#![feature(decl_macro)]
9696
#![feature(doc_cfg)]
97+
#![feature(duration_consts_2)]
9798
#![feature(extern_types)]
9899
#![feature(fundamental)]
99100
#![feature(intrinsics)]

src/libcore/time.rs

+28-19
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,12 @@ impl Duration {
130130
/// ```
131131
#[stable(feature = "duration", since = "1.3.0")]
132132
#[inline]
133-
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
134-
pub fn new(secs: u64, nanos: u32) -> Duration {
135-
let secs =
136-
secs.checked_add((nanos / NANOS_PER_SEC) as u64).expect("overflow in Duration::new");
133+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
134+
pub const fn new(secs: u64, nanos: u32) -> Duration {
135+
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
136+
Some(secs) => secs,
137+
None => panic!("overflow in Duration::new"),
138+
};
137139
let nanos = nanos % NANOS_PER_SEC;
138140
Duration { secs, nanos }
139141
}
@@ -393,7 +395,8 @@ impl Duration {
393395
/// ```
394396
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
395397
#[inline]
396-
pub fn checked_add(self, rhs: Duration) -> Option<Duration> {
398+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
399+
pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
397400
if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
398401
let mut nanos = self.nanos + rhs.nanos;
399402
if nanos >= NANOS_PER_SEC {
@@ -428,7 +431,8 @@ impl Duration {
428431
/// ```
429432
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
430433
#[inline]
431-
pub fn checked_sub(self, rhs: Duration) -> Option<Duration> {
434+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
435+
pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
432436
if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
433437
let nanos = if self.nanos >= rhs.nanos {
434438
self.nanos - rhs.nanos
@@ -464,19 +468,19 @@ impl Duration {
464468
/// ```
465469
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
466470
#[inline]
467-
pub fn checked_mul(self, rhs: u32) -> Option<Duration> {
471+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
472+
pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
468473
// Multiply nanoseconds as u64, because it cannot overflow that way.
469474
let total_nanos = self.nanos as u64 * rhs as u64;
470475
let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
471476
let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
472-
if let Some(secs) =
473-
self.secs.checked_mul(rhs as u64).and_then(|s| s.checked_add(extra_secs))
474-
{
475-
debug_assert!(nanos < NANOS_PER_SEC);
476-
Some(Duration { secs, nanos })
477-
} else {
478-
None
477+
if let Some(s) = self.secs.checked_mul(rhs as u64) {
478+
if let Some(secs) = s.checked_add(extra_secs) {
479+
debug_assert!(nanos < NANOS_PER_SEC);
480+
return Some(Duration { secs, nanos });
481+
}
479482
}
483+
None
480484
}
481485

482486
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
@@ -497,7 +501,8 @@ impl Duration {
497501
/// ```
498502
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
499503
#[inline]
500-
pub fn checked_div(self, rhs: u32) -> Option<Duration> {
504+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
505+
pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
501506
if rhs != 0 {
502507
let secs = self.secs / (rhs as u64);
503508
let carry = self.secs - secs * (rhs as u64);
@@ -523,7 +528,8 @@ impl Duration {
523528
/// ```
524529
#[stable(feature = "duration_float", since = "1.38.0")]
525530
#[inline]
526-
pub fn as_secs_f64(&self) -> f64 {
531+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
532+
pub const fn as_secs_f64(&self) -> f64 {
527533
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
528534
}
529535

@@ -540,7 +546,8 @@ impl Duration {
540546
/// ```
541547
#[stable(feature = "duration_float", since = "1.38.0")]
542548
#[inline]
543-
pub fn as_secs_f32(&self) -> f32 {
549+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
550+
pub const fn as_secs_f32(&self) -> f32 {
544551
(self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
545552
}
546553

@@ -707,7 +714,8 @@ impl Duration {
707714
/// ```
708715
#[unstable(feature = "div_duration", issue = "63139")]
709716
#[inline]
710-
pub fn div_duration_f64(self, rhs: Duration) -> f64 {
717+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
718+
pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
711719
self.as_secs_f64() / rhs.as_secs_f64()
712720
}
713721

@@ -724,7 +732,8 @@ impl Duration {
724732
/// ```
725733
#[unstable(feature = "div_duration", issue = "63139")]
726734
#[inline]
727-
pub fn div_duration_f32(self, rhs: Duration) -> f32 {
735+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
736+
pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
728737
self.as_secs_f32() / rhs.as_secs_f32()
729738
}
730739
}
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// run-pass
2+
3+
#![feature(const_panic)]
4+
#![feature(const_if_match)]
5+
#![feature(duration_consts_2)]
6+
#![feature(div_duration)]
7+
8+
use std::time::Duration;
9+
10+
fn duration() {
11+
const ZERO : Duration = Duration::new(0, 0);
12+
assert_eq!(ZERO, Duration::from_secs(0));
13+
14+
const ONE : Duration = Duration::new(0, 1);
15+
assert_eq!(ONE, Duration::from_nanos(1));
16+
17+
const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1);
18+
19+
const MAX_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
20+
assert_eq!(MAX_ADD_ZERO, Some(MAX));
21+
22+
const MAX_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
23+
assert_eq!(MAX_ADD_ONE, None);
24+
25+
const ONE_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
26+
assert_eq!(ONE_SUB_ONE, Some(ZERO));
27+
28+
const ZERO_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
29+
assert_eq!(ZERO_SUB_ONE, None);
30+
31+
const ONE_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
32+
assert_eq!(ONE_MUL_ONE, Some(ONE));
33+
34+
const MAX_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
35+
assert_eq!(MAX_MUL_TWO, None);
36+
37+
const ONE_DIV_ONE : Option<Duration> = ONE.checked_div(1);
38+
assert_eq!(ONE_DIV_ONE, Some(ONE));
39+
40+
const ONE_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
41+
assert_eq!(ONE_DIV_ZERO, None);
42+
43+
const MAX_AS_F32 : f32 = MAX.as_secs_f32();
44+
assert_eq!(MAX_AS_F32, u64::MAX as f32 + 0.000_000_000_1);
45+
46+
const MAX_AS_F64 : f64 = MAX.as_secs_f64();
47+
assert_eq!(MAX_AS_F64, u64::MAX as f64 + 0.000_000_000_1);
48+
49+
const ONE_AS_F32 : f32 = ONE.div_duration_f32(ONE);
50+
assert_eq!(ONE_AS_F32, 1.0_f32);
51+
52+
const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE);
53+
assert_eq!(ONE_AS_F64, 1.0_f64);
54+
}
55+
56+
fn main() {
57+
duration();
58+
}

0 commit comments

Comments
 (0)