From d72d5f48c2c534de7382a601e4619de923b7f6a9 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 21 Oct 2020 17:56:09 -0700 Subject: [PATCH 1/4] Dogfood Duration API in std::time tests This expands time's test suite to use more and in more places the range of methods and constants added to Duration in recent proposals for the sake of testing more API surface area and improving legibility. --- library/core/tests/time.rs | 90 +++++++++++++++++------------------ library/std/src/lib.rs | 1 + library/std/src/time/tests.rs | 32 ++++++------- 3 files changed, 62 insertions(+), 61 deletions(-) diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index 7c43885040b3e..6508e78429c0e 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -108,24 +108,26 @@ fn sub() { #[test] fn checked_sub() { - let zero = Duration::new(0, 0); - let one_nano = Duration::new(0, 1); - let one_sec = Duration::new(1, 0); - assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1))); - assert_eq!(one_sec.checked_sub(one_nano), Some(Duration::new(0, 999_999_999))); - assert_eq!(zero.checked_sub(one_nano), None); - assert_eq!(zero.checked_sub(one_sec), None); + let zero = Duration::zero(); + assert_eq!(Duration::NANOSECOND.checked_sub(zero), Some(Duration::NANOSECOND)); + assert_eq!( + Duration::SECOND.checked_sub(Duration::NANOSECOND), + Some(Duration::new(0, 999_999_999)) + ); + assert_eq!(zero.checked_sub(Duration::NANOSECOND), None); + assert_eq!(zero.checked_sub(Duration::SECOND), None); } #[test] fn saturating_sub() { let zero = Duration::new(0, 0); - let one_nano = Duration::new(0, 1); - let one_sec = Duration::new(1, 0); - assert_eq!(one_nano.saturating_sub(zero), Duration::new(0, 1)); - assert_eq!(one_sec.saturating_sub(one_nano), Duration::new(0, 999_999_999)); - assert_eq!(zero.saturating_sub(one_nano), Duration::MIN); - assert_eq!(zero.saturating_sub(one_sec), Duration::MIN); + assert_eq!(Duration::NANOSECOND.saturating_sub(zero), Duration::NANOSECOND); + assert_eq!( + Duration::SECOND.saturating_sub(Duration::NANOSECOND), + Duration::new(0, 999_999_999) + ); + assert_eq!(zero.saturating_sub(Duration::NANOSECOND), Duration::MIN); + assert_eq!(zero.saturating_sub(Duration::SECOND), Duration::MIN); } #[test] @@ -343,80 +345,78 @@ fn duration_const() { const IS_ZERO: bool = ZERO.is_zero(); assert!(IS_ZERO); - const ONE: Duration = Duration::new(1, 0); - - const SECONDS: u64 = ONE.as_secs(); + const SECONDS: u64 = Duration::SECOND.as_secs(); assert_eq!(SECONDS, 1); const FROM_SECONDS: Duration = Duration::from_secs(1); - assert_eq!(FROM_SECONDS, ONE); + assert_eq!(FROM_SECONDS, Duration::SECOND); - const SECONDS_F32: f32 = ONE.as_secs_f32(); + const SECONDS_F32: f32 = Duration::SECOND.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); + assert_eq!(FROM_SECONDS_F32, Duration::SECOND); - const SECONDS_F64: f64 = ONE.as_secs_f64(); + const SECONDS_F64: f64 = Duration::SECOND.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); + assert_eq!(FROM_SECONDS_F64, Duration::SECOND); - const MILLIS: u128 = ONE.as_millis(); + const MILLIS: u128 = Duration::SECOND.as_millis(); assert_eq!(MILLIS, 1_000); const FROM_MILLIS: Duration = Duration::from_millis(1_000); - assert_eq!(FROM_MILLIS, ONE); + assert_eq!(FROM_MILLIS, Duration::SECOND); - const MICROS: u128 = ONE.as_micros(); + const MICROS: u128 = Duration::SECOND.as_micros(); assert_eq!(MICROS, 1_000_000); const FROM_MICROS: Duration = Duration::from_micros(1_000_000); - assert_eq!(FROM_MICROS, ONE); + assert_eq!(FROM_MICROS, Duration::SECOND); - const NANOS: u128 = ONE.as_nanos(); + const NANOS: u128 = Duration::SECOND.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); + assert_eq!(FROM_NANOS, Duration::SECOND); const MAX: Duration = Duration::new(u64::MAX, 999_999_999); - const CHECKED_ADD: Option = MAX.checked_add(ONE); + const CHECKED_ADD: Option = MAX.checked_add(Duration::SECOND); assert_eq!(CHECKED_ADD, None); - const CHECKED_SUB: Option = ZERO.checked_sub(ONE); + const CHECKED_SUB: Option = ZERO.checked_sub(Duration::SECOND); assert_eq!(CHECKED_SUB, None); - const CHECKED_MUL: Option = ONE.checked_mul(1); - assert_eq!(CHECKED_MUL, Some(ONE)); + const CHECKED_MUL: Option = Duration::SECOND.checked_mul(1); + assert_eq!(CHECKED_MUL, Some(Duration::SECOND)); - const MUL_F32: Duration = ONE.mul_f32(1.0); - assert_eq!(MUL_F32, ONE); + const MUL_F32: Duration = Duration::SECOND.mul_f32(1.0); + assert_eq!(MUL_F32, Duration::SECOND); - const MUL_F64: Duration = ONE.mul_f64(1.0); - assert_eq!(MUL_F64, ONE); + const MUL_F64: Duration = Duration::SECOND.mul_f64(1.0); + assert_eq!(MUL_F64, Duration::SECOND); - const CHECKED_DIV: Option = ONE.checked_div(1); - assert_eq!(CHECKED_DIV, Some(ONE)); + const CHECKED_DIV: Option = Duration::SECOND.checked_div(1); + assert_eq!(CHECKED_DIV, Some(Duration::SECOND)); - const DIV_F32: Duration = ONE.div_f32(1.0); - assert_eq!(DIV_F32, ONE); + const DIV_F32: Duration = Duration::SECOND.div_f32(1.0); + assert_eq!(DIV_F32, Duration::SECOND); - const DIV_F64: Duration = ONE.div_f64(1.0); - assert_eq!(DIV_F64, ONE); + const DIV_F64: Duration = Duration::SECOND.div_f64(1.0); + assert_eq!(DIV_F64, Duration::SECOND); - const DIV_DURATION_F32: f32 = ONE.div_duration_f32(ONE); + const DIV_DURATION_F32: f32 = Duration::SECOND.div_duration_f32(Duration::SECOND); assert_eq!(DIV_DURATION_F32, 1.0); - const DIV_DURATION_F64: f64 = ONE.div_duration_f64(ONE); + const DIV_DURATION_F64: f64 = Duration::SECOND.div_duration_f64(Duration::SECOND); assert_eq!(DIV_DURATION_F64, 1.0); - const SATURATING_ADD: Duration = MAX.saturating_add(ONE); + const SATURATING_ADD: Duration = MAX.saturating_add(Duration::SECOND); assert_eq!(SATURATING_ADD, MAX); - const SATURATING_SUB: Duration = ZERO.saturating_sub(ONE); + const SATURATING_SUB: Duration = ZERO.saturating_sub(Duration::SECOND); assert_eq!(SATURATING_SUB, ZERO); const SATURATING_MUL: Duration = MAX.saturating_mul(2); diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 30e7a7f3c3b10..881e387c7c81d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -255,6 +255,7 @@ #![feature(doc_spotlight)] #![feature(dropck_eyepatch)] #![feature(duration_constants)] +#![feature(duration_zero)] #![feature(exact_size_is_empty)] #![feature(exhaustive_patterns)] #![feature(extend_one)] diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs index 783bf49f31544..44c06bac9507c 100644 --- a/library/std/src/time/tests.rs +++ b/library/std/src/time/tests.rs @@ -5,7 +5,7 @@ macro_rules! assert_almost_eq { let (a, b) = ($a, $b); if a != b { let (a, b) = if a > b { (a, b) } else { (b, a) }; - assert!(a - Duration::new(0, 1000) <= b, "{:?} is not almost equal to {:?}", a, b); + assert!(a - Duration::from_micros(1) <= b, "{:?} is not almost equal to {:?}", a, b); } }}; } @@ -34,7 +34,7 @@ fn instant_math() { assert_almost_eq!(b - dur, a); assert_almost_eq!(a + dur, b); - let second = Duration::new(1, 0); + let second = Duration::SECOND; assert_almost_eq!(a - second + second, a); assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); @@ -65,24 +65,24 @@ fn instant_math_is_associative() { #[should_panic] fn instant_duration_since_panic() { let a = Instant::now(); - (a - Duration::new(1, 0)).duration_since(a); + (a - Duration::SECOND).duration_since(a); } #[test] fn instant_checked_duration_since_nopanic() { let now = Instant::now(); - let earlier = now - Duration::new(1, 0); - let later = now + Duration::new(1, 0); + let earlier = now - Duration::SECOND; + let later = now + Duration::SECOND; assert_eq!(earlier.checked_duration_since(now), None); - assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0))); - assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0))); + assert_eq!(later.checked_duration_since(now), Some(Duration::SECOND)); + assert_eq!(now.checked_duration_since(now), Some(Duration::zero())); } #[test] fn instant_saturating_duration_since_nopanic() { let a = Instant::now(); - let ret = (a - Duration::new(1, 0)).saturating_duration_since(a); - assert_eq!(ret, Duration::new(0, 0)); + let ret = (a - Duration::SECOND).saturating_duration_since(a); + assert_eq!(ret, Duration::zero()); } #[test] @@ -90,7 +90,7 @@ fn system_time_math() { let a = SystemTime::now(); let b = SystemTime::now(); match b.duration_since(a) { - Ok(dur) if dur == Duration::new(0, 0) => { + Ok(dur) if dur == Duration::zero() => { assert_almost_eq!(a, b); } Ok(dur) => { @@ -106,16 +106,16 @@ fn system_time_math() { } } - let second = Duration::new(1, 0); + let second = Duration::SECOND; assert_almost_eq!(a.duration_since(a - second).unwrap(), second); assert_almost_eq!(a.duration_since(a + second).unwrap_err().duration(), second); assert_almost_eq!(a - second + second, a); assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); + let one_second_from_epoch = UNIX_EPOCH + Duration::SECOND; let one_second_from_epoch2 = - UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); + UNIX_EPOCH + Duration::from_millis(500) + Duration::from_millis(500); assert_eq!(one_second_from_epoch, one_second_from_epoch2); // checked_add_duration will not panic on overflow @@ -141,12 +141,12 @@ fn system_time_elapsed() { #[test] fn since_epoch() { let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let a = ts.duration_since(UNIX_EPOCH + Duration::SECOND).unwrap(); let b = ts.duration_since(UNIX_EPOCH).unwrap(); assert!(b > a); - assert_eq!(b - a, Duration::new(1, 0)); + assert_eq!(b - a, Duration::SECOND); - let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30; + let thirty_years = Duration::SECOND * 60 * 60 * 24 * 365 * 30; // Right now for CI this test is run in an emulator, and apparently the // aarch64 emulator's sense of time is that we're still living in the From ef027a1eed4cc8d34d1a4bf9222369e7fef48e93 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 21 Oct 2020 18:18:18 -0700 Subject: [PATCH 2/4] Duration::zero() -> Duration::ZERO Duration::ZERO composes better with match and various other things, at the cost of an occasional parens, and results in less work for the optimizer, so let's use that instead. --- library/core/src/time.rs | 35 ++++++++++++++++------------------- library/core/tests/time.rs | 25 ++++++++++--------------- library/std/src/time/tests.rs | 6 +++--- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 6dc542dee58e6..cc9afaff888ae 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -108,6 +108,21 @@ impl Duration { #[unstable(feature = "duration_constants", issue = "57391")] pub const NANOSECOND: Duration = Duration::from_nanos(1); + /// A duration of zero time. + /// + /// # Examples + /// + /// ``` + /// #![feature(duration_zero)] + /// use std::time::Duration; + /// + /// let duration = Duration::ZERO; + /// assert!(duration.is_zero()); + /// assert_eq!(duration.as_nanos(), 0); + /// ``` + #[unstable(feature = "duration_zero", issue = "73544")] + pub const ZERO: Duration = Duration::from_nanos(0); + /// The minimum duration. /// /// # Examples @@ -166,24 +181,6 @@ impl Duration { Duration { secs, nanos } } - /// Creates a new `Duration` that spans no time. - /// - /// # Examples - /// - /// ``` - /// #![feature(duration_zero)] - /// use std::time::Duration; - /// - /// let duration = Duration::zero(); - /// assert!(duration.is_zero()); - /// assert_eq!(duration.as_nanos(), 0); - /// ``` - #[unstable(feature = "duration_zero", issue = "73544")] - #[inline] - pub const fn zero() -> Duration { - Duration { secs: 0, nanos: 0 } - } - /// Creates a new `Duration` from the specified number of whole seconds. /// /// # Examples @@ -277,7 +274,7 @@ impl Duration { /// #![feature(duration_zero)] /// use std::time::Duration; /// - /// assert!(Duration::zero().is_zero()); + /// assert!(Duration::ZERO.is_zero()); /// assert!(Duration::new(0, 0).is_zero()); /// assert!(Duration::from_nanos(0).is_zero()); /// assert!(Duration::from_secs(0).is_zero()); diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index 6508e78429c0e..dffbdd0372c15 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -108,26 +108,24 @@ fn sub() { #[test] fn checked_sub() { - let zero = Duration::zero(); - assert_eq!(Duration::NANOSECOND.checked_sub(zero), Some(Duration::NANOSECOND)); + assert_eq!(Duration::NANOSECOND.checked_sub(Duration::ZERO), Some(Duration::NANOSECOND)); assert_eq!( Duration::SECOND.checked_sub(Duration::NANOSECOND), Some(Duration::new(0, 999_999_999)) ); - assert_eq!(zero.checked_sub(Duration::NANOSECOND), None); - assert_eq!(zero.checked_sub(Duration::SECOND), None); + assert_eq!(Duration::ZERO.checked_sub(Duration::NANOSECOND), None); + assert_eq!(Duration::ZERO.checked_sub(Duration::SECOND), None); } #[test] fn saturating_sub() { - let zero = Duration::new(0, 0); - assert_eq!(Duration::NANOSECOND.saturating_sub(zero), Duration::NANOSECOND); + assert_eq!(Duration::NANOSECOND.saturating_sub(Duration::ZERO), Duration::NANOSECOND); assert_eq!( Duration::SECOND.saturating_sub(Duration::NANOSECOND), Duration::new(0, 999_999_999) ); - assert_eq!(zero.saturating_sub(Duration::NANOSECOND), Duration::MIN); - assert_eq!(zero.saturating_sub(Duration::SECOND), Duration::MIN); + assert_eq!(Duration::ZERO.saturating_sub(Duration::NANOSECOND), Duration::MIN); + assert_eq!(Duration::ZERO.saturating_sub(Duration::SECOND), Duration::MIN); } #[test] @@ -339,10 +337,7 @@ fn duration_const() { 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(); + const IS_ZERO: bool = Duration::ZERO.is_zero(); assert!(IS_ZERO); const SECONDS: u64 = Duration::SECOND.as_secs(); @@ -386,7 +381,7 @@ fn duration_const() { const CHECKED_ADD: Option = MAX.checked_add(Duration::SECOND); assert_eq!(CHECKED_ADD, None); - const CHECKED_SUB: Option = ZERO.checked_sub(Duration::SECOND); + const CHECKED_SUB: Option = (Duration::ZERO).checked_sub(Duration::SECOND); assert_eq!(CHECKED_SUB, None); const CHECKED_MUL: Option = Duration::SECOND.checked_mul(1); @@ -416,8 +411,8 @@ fn duration_const() { const SATURATING_ADD: Duration = MAX.saturating_add(Duration::SECOND); assert_eq!(SATURATING_ADD, MAX); - const SATURATING_SUB: Duration = ZERO.saturating_sub(Duration::SECOND); - assert_eq!(SATURATING_SUB, ZERO); + const SATURATING_SUB: Duration = (Duration::ZERO).saturating_sub(Duration::SECOND); + assert_eq!(SATURATING_SUB, Duration::ZERO); const SATURATING_MUL: Duration = MAX.saturating_mul(2); assert_eq!(SATURATING_MUL, MAX); diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs index 44c06bac9507c..20c813fdc70ff 100644 --- a/library/std/src/time/tests.rs +++ b/library/std/src/time/tests.rs @@ -75,14 +75,14 @@ fn instant_checked_duration_since_nopanic() { let later = now + Duration::SECOND; assert_eq!(earlier.checked_duration_since(now), None); assert_eq!(later.checked_duration_since(now), Some(Duration::SECOND)); - assert_eq!(now.checked_duration_since(now), Some(Duration::zero())); + assert_eq!(now.checked_duration_since(now), Some(Duration::ZERO)); } #[test] fn instant_saturating_duration_since_nopanic() { let a = Instant::now(); let ret = (a - Duration::SECOND).saturating_duration_since(a); - assert_eq!(ret, Duration::zero()); + assert_eq!(ret, Duration::ZERO); } #[test] @@ -90,7 +90,7 @@ fn system_time_math() { let a = SystemTime::now(); let b = SystemTime::now(); match b.duration_since(a) { - Ok(dur) if dur == Duration::zero() => { + Ok(Duration::ZERO) => { assert_almost_eq!(a, b); } Ok(dur) => { From af4d1786e70e441e0998a80d5db0f2f197ea2cf1 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 27 Oct 2020 13:43:21 -0700 Subject: [PATCH 3/4] Fixup tests: Duration::MIN -> ::ZERO --- library/core/tests/time.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index dffbdd0372c15..f14639e0d589f 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -124,8 +124,8 @@ fn saturating_sub() { Duration::SECOND.saturating_sub(Duration::NANOSECOND), Duration::new(0, 999_999_999) ); - assert_eq!(Duration::ZERO.saturating_sub(Duration::NANOSECOND), Duration::MIN); - assert_eq!(Duration::ZERO.saturating_sub(Duration::SECOND), Duration::MIN); + assert_eq!(Duration::ZERO.saturating_sub(Duration::NANOSECOND), Duration::ZERO); + assert_eq!(Duration::ZERO.saturating_sub(Duration::SECOND), Duration::ZERO); } #[test] @@ -381,7 +381,7 @@ fn duration_const() { const CHECKED_ADD: Option = MAX.checked_add(Duration::SECOND); assert_eq!(CHECKED_ADD, None); - const CHECKED_SUB: Option = (Duration::ZERO).checked_sub(Duration::SECOND); + const CHECKED_SUB: Option = Duration::ZERO.checked_sub(Duration::SECOND); assert_eq!(CHECKED_SUB, None); const CHECKED_MUL: Option = Duration::SECOND.checked_mul(1); @@ -411,7 +411,7 @@ fn duration_const() { const SATURATING_ADD: Duration = MAX.saturating_add(Duration::SECOND); assert_eq!(SATURATING_ADD, MAX); - const SATURATING_SUB: Duration = (Duration::ZERO).saturating_sub(Duration::SECOND); + const SATURATING_SUB: Duration = Duration::ZERO.saturating_sub(Duration::SECOND); assert_eq!(SATURATING_SUB, Duration::ZERO); const SATURATING_MUL: Duration = MAX.saturating_mul(2); From 82f3a236cdb80f65cd5b89a1cb015f95184bf66a Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 27 Oct 2020 14:06:55 -0700 Subject: [PATCH 4/4] Remove Duration::MIN entirely Duration::ZERO supercedes it in effect. --- library/core/src/time.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index cc9afaff888ae..88b4e2a2436e7 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -123,19 +123,6 @@ impl Duration { #[unstable(feature = "duration_zero", issue = "73544")] pub const ZERO: Duration = Duration::from_nanos(0); - /// The minimum duration. - /// - /// # Examples - /// - /// ``` - /// #![feature(duration_constants)] - /// use std::time::Duration; - /// - /// assert_eq!(Duration::MIN, Duration::new(0, 0)); - /// ``` - #[unstable(feature = "duration_constants", issue = "57391")] - pub const MIN: Duration = Duration::from_nanos(0); - /// The maximum duration. /// /// It is roughly equal to a duration of 584,942,417,355 years. @@ -533,18 +520,18 @@ impl Duration { } } - /// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::MIN`] + /// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::ZERO`] /// if the result would be negative or if overflow occurred. /// /// # Examples /// /// ``` /// #![feature(duration_saturating_ops)] - /// #![feature(duration_constants)] + /// #![feature(duration_zero)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1)); - /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::MIN); + /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO); /// ``` #[unstable(feature = "duration_saturating_ops", issue = "76416")] #[inline] @@ -552,7 +539,7 @@ impl Duration { pub const fn saturating_sub(self, rhs: Duration) -> Duration { match self.checked_sub(rhs) { Some(res) => res, - None => Duration::MIN, + None => Duration::ZERO, } }