mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Auto merge of #72481 - marmeladema:duration-consts-2, r=oli-obk
Constify most non-trait `Duration` methods as described in #72440 The remaining methods could probably be made const once https://github.com/rust-lang/rust/pull/72449 lands with support for `f<32|64>::is_finite()`.
This commit is contained in:
commit
6ee1b62c81
@ -96,6 +96,7 @@
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(doc_cfg)]
|
||||
#![feature(duration_consts_2)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(intrinsics)]
|
||||
|
@ -130,10 +130,12 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
#[inline]
|
||||
#[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
|
||||
pub fn new(secs: u64, nanos: u32) -> Duration {
|
||||
let secs =
|
||||
secs.checked_add((nanos / NANOS_PER_SEC) as u64).expect("overflow in Duration::new");
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn new(secs: u64, nanos: u32) -> Duration {
|
||||
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
|
||||
Some(secs) => secs,
|
||||
None => panic!("overflow in Duration::new"),
|
||||
};
|
||||
let nanos = nanos % NANOS_PER_SEC;
|
||||
Duration { secs, nanos }
|
||||
}
|
||||
@ -433,7 +435,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
|
||||
#[inline]
|
||||
pub fn checked_add(self, rhs: Duration) -> Option<Duration> {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
|
||||
if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
|
||||
let mut nanos = self.nanos + rhs.nanos;
|
||||
if nanos >= NANOS_PER_SEC {
|
||||
@ -468,7 +471,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
|
||||
#[inline]
|
||||
pub fn checked_sub(self, rhs: Duration) -> Option<Duration> {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
|
||||
if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
|
||||
let nanos = if self.nanos >= rhs.nanos {
|
||||
self.nanos - rhs.nanos
|
||||
@ -504,19 +508,19 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
|
||||
#[inline]
|
||||
pub fn checked_mul(self, rhs: u32) -> Option<Duration> {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
|
||||
// Multiply nanoseconds as u64, because it cannot overflow that way.
|
||||
let total_nanos = self.nanos as u64 * rhs as u64;
|
||||
let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
|
||||
let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
|
||||
if let Some(secs) =
|
||||
self.secs.checked_mul(rhs as u64).and_then(|s| s.checked_add(extra_secs))
|
||||
{
|
||||
debug_assert!(nanos < NANOS_PER_SEC);
|
||||
Some(Duration { secs, nanos })
|
||||
} else {
|
||||
None
|
||||
if let Some(s) = self.secs.checked_mul(rhs as u64) {
|
||||
if let Some(secs) = s.checked_add(extra_secs) {
|
||||
debug_assert!(nanos < NANOS_PER_SEC);
|
||||
return Some(Duration { secs, nanos });
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
|
||||
@ -537,7 +541,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
|
||||
#[inline]
|
||||
pub fn checked_div(self, rhs: u32) -> Option<Duration> {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
|
||||
if rhs != 0 {
|
||||
let secs = self.secs / (rhs as u64);
|
||||
let carry = self.secs - secs * (rhs as u64);
|
||||
@ -563,7 +568,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn as_secs_f64(&self) -> f64 {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn as_secs_f64(&self) -> f64 {
|
||||
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
|
||||
}
|
||||
|
||||
@ -580,7 +586,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn as_secs_f32(&self) -> f32 {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn as_secs_f32(&self) -> f32 {
|
||||
(self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
|
||||
}
|
||||
|
||||
@ -747,7 +754,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[unstable(feature = "div_duration", issue = "63139")]
|
||||
#[inline]
|
||||
pub fn div_duration_f64(self, rhs: Duration) -> f64 {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
|
||||
self.as_secs_f64() / rhs.as_secs_f64()
|
||||
}
|
||||
|
||||
@ -764,7 +772,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[unstable(feature = "div_duration", issue = "63139")]
|
||||
#[inline]
|
||||
pub fn div_duration_f32(self, rhs: Duration) -> f32 {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
|
||||
self.as_secs_f32() / rhs.as_secs_f32()
|
||||
}
|
||||
}
|
||||
|
57
src/test/ui/consts/duration-consts-2.rs
Normal file
57
src/test/ui/consts/duration-consts-2.rs
Normal file
@ -0,0 +1,57 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_panic)]
|
||||
#![feature(duration_consts_2)]
|
||||
#![feature(div_duration)]
|
||||
|
||||
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_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
|
||||
assert_eq!(MAX_ADD_ZERO, Some(MAX));
|
||||
|
||||
const MAX_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
|
||||
assert_eq!(MAX_ADD_ONE, None);
|
||||
|
||||
const ONE_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
|
||||
assert_eq!(ONE_SUB_ONE, Some(ZERO));
|
||||
|
||||
const ZERO_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
|
||||
assert_eq!(ZERO_SUB_ONE, None);
|
||||
|
||||
const ONE_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
|
||||
assert_eq!(ONE_MUL_ONE, Some(ONE));
|
||||
|
||||
const MAX_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
|
||||
assert_eq!(MAX_MUL_TWO, None);
|
||||
|
||||
const ONE_DIV_ONE : Option<Duration> = ONE.checked_div(1);
|
||||
assert_eq!(ONE_DIV_ONE, Some(ONE));
|
||||
|
||||
const ONE_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
|
||||
assert_eq!(ONE_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);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
duration();
|
||||
}
|
Loading…
Reference in New Issue
Block a user