Skip to content

Commit 6ee1b62

Browse files
committed
Auto merge of rust-lang#72481 - marmeladema:duration-consts-2, r=oli-obk
Constify most non-trait `Duration` methods as described in rust-lang#72440 The remaining methods could probably be made const once rust-lang#72449 lands with support for `f<32|64>::is_finite()`.
2 parents 125c58c + 4a96800 commit 6ee1b62

File tree

3 files changed

+86
-19
lines changed

3 files changed

+86
-19
lines changed

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
#![feature(custom_inner_attributes)]
9797
#![feature(decl_macro)]
9898
#![feature(doc_cfg)]
99+
#![feature(duration_consts_2)]
99100
#![feature(extern_types)]
100101
#![feature(fundamental)]
101102
#![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
}
@@ -433,7 +435,8 @@ impl Duration {
433435
/// ```
434436
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
435437
#[inline]
436-
pub fn checked_add(self, rhs: Duration) -> Option<Duration> {
438+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
439+
pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
437440
if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
438441
let mut nanos = self.nanos + rhs.nanos;
439442
if nanos >= NANOS_PER_SEC {
@@ -468,7 +471,8 @@ impl Duration {
468471
/// ```
469472
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
470473
#[inline]
471-
pub fn checked_sub(self, rhs: Duration) -> Option<Duration> {
474+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
475+
pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
472476
if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
473477
let nanos = if self.nanos >= rhs.nanos {
474478
self.nanos - rhs.nanos
@@ -504,19 +508,19 @@ impl Duration {
504508
/// ```
505509
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
506510
#[inline]
507-
pub fn checked_mul(self, rhs: u32) -> Option<Duration> {
511+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
512+
pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
508513
// Multiply nanoseconds as u64, because it cannot overflow that way.
509514
let total_nanos = self.nanos as u64 * rhs as u64;
510515
let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
511516
let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
512-
if let Some(secs) =
513-
self.secs.checked_mul(rhs as u64).and_then(|s| s.checked_add(extra_secs))
514-
{
515-
debug_assert!(nanos < NANOS_PER_SEC);
516-
Some(Duration { secs, nanos })
517-
} else {
518-
None
517+
if let Some(s) = self.secs.checked_mul(rhs as u64) {
518+
if let Some(secs) = s.checked_add(extra_secs) {
519+
debug_assert!(nanos < NANOS_PER_SEC);
520+
return Some(Duration { secs, nanos });
521+
}
519522
}
523+
None
520524
}
521525

522526
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
@@ -537,7 +541,8 @@ impl Duration {
537541
/// ```
538542
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
539543
#[inline]
540-
pub fn checked_div(self, rhs: u32) -> Option<Duration> {
544+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
545+
pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
541546
if rhs != 0 {
542547
let secs = self.secs / (rhs as u64);
543548
let carry = self.secs - secs * (rhs as u64);
@@ -563,7 +568,8 @@ impl Duration {
563568
/// ```
564569
#[stable(feature = "duration_float", since = "1.38.0")]
565570
#[inline]
566-
pub fn as_secs_f64(&self) -> f64 {
571+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
572+
pub const fn as_secs_f64(&self) -> f64 {
567573
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
568574
}
569575

@@ -580,7 +586,8 @@ impl Duration {
580586
/// ```
581587
#[stable(feature = "duration_float", since = "1.38.0")]
582588
#[inline]
583-
pub fn as_secs_f32(&self) -> f32 {
589+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
590+
pub const fn as_secs_f32(&self) -> f32 {
584591
(self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
585592
}
586593

@@ -747,7 +754,8 @@ impl Duration {
747754
/// ```
748755
#[unstable(feature = "div_duration", issue = "63139")]
749756
#[inline]
750-
pub fn div_duration_f64(self, rhs: Duration) -> f64 {
757+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
758+
pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
751759
self.as_secs_f64() / rhs.as_secs_f64()
752760
}
753761

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

0 commit comments

Comments
 (0)