Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions library/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,39 @@ impl Duration {
Duration { secs, nanos: subsec_nanos }
}

/// Creates a new Duration from the specified number of nanoseconds.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Creates a new Duration from the specified number of nanoseconds.
/// Creates a new `Duration` from the specified number of nanoseconds.

///
/// # Panics
///
/// Panics if the given number of nanoseconds is greater than what Duration can handle,
/// which is `(u64::MAX * NANOS_PER_SEC) + NANOS_PER_SEC - 1`
Comment on lines +315 to +316
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Panics if the given number of nanoseconds is greater than what Duration can handle,
/// which is `(u64::MAX * NANOS_PER_SEC) + NANOS_PER_SEC - 1`
/// Panics if the given number of nanoseconds is greater than [`Duration::MAX`].

Technically we say this can vary by platform, so we don't need to give specifics.

/// Use this function if you need to specify time greater than what can fit in u64
/// (around 584 years).
Comment on lines +317 to +318
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Use this function if you need to specify time greater than what can fit in u64
/// (around 584 years).

I think this is reasonably straightforward

///
/// # Examples
///
/// ```
/// #![feature(duration_from_nanos_u128)]
/// use std::time::Duration;
/// let time_in_nanos = 2u128.pow(64);
/// let duration = Duration::from_nanos_u128(time_in_nanos);
/// ```
#[unstable(feature = "duration_from_nanos_u128", issue = "139201")]
#[must_use]
#[inline]
pub const fn from_nanos_u128(nanos: u128) -> Duration {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn from_nanos_u128(nanos: u128) -> Duration {
#[track_caller]
pub const fn from_nanos_u128(nanos: u128) -> Duration {

Makes the panic message show where this was called, rather than reporting std's time.rs as the panic location

const NANOS_PER_SEC: u128 = self::NANOS_PER_SEC as u128;
let secs: u128 = nanos / NANOS_PER_SEC;
if secs > u64::MAX as u128 {
panic!("overflow in duration in Duration::from_nanos_u128");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
panic!("overflow in duration in Duration::from_nanos_u128");
panic!("overflow in `Duration::from_nanos_u128`");

}
let subsec_nanos = (nanos % NANOS_PER_SEC) as u32;
// SAFETY: x % 1_000_000_000 < 1_000_000_000 also, subsec_nanos >= 0 since u128 >=0 and u32 >=0
let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) };

Duration { secs: secs as u64, nanos: subsec_nanos }
}

/// Creates a new `Duration` from the specified number of weeks.
///
/// # Panics
Expand Down
15 changes: 15 additions & 0 deletions library/coretests/tests/time.rs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to add #![feature(duration_from_nanos_u128)] to coretests/tests/lib.rs, even for testing the unstable feature needs to be enabled (this is your CI failure)

Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ fn from_weeks_overflow() {
let _ = Duration::from_weeks(overflow);
}

#[test]
#[should_panic]
fn from_nanos_u128_overflow() {
let overflow = (u64::MAX * NANOS_PER_SEC) + (NANOS_PER_SEC - 1) + 1;
let _ = Duration::from_nanos_u128(overflow);
}

#[test]
fn constructor_weeks() {
assert_eq!(Duration::from_weeks(1), Duration::from_secs(7 * 24 * 60 * 60));
Expand Down Expand Up @@ -81,6 +88,8 @@ fn secs() {
assert_eq!(Duration::from_micros(1_000_001).as_secs(), 1);
assert_eq!(Duration::from_nanos(999_999_999).as_secs(), 0);
assert_eq!(Duration::from_nanos(1_000_000_001).as_secs(), 1);
assert_eq!(Duration::from_nanos_u128(999_999_999).as_secs(), 0);
assert_eq!(Duration::from_nanos_u128(1_000_000_001).as_secs(), 1);
}

#[test]
Expand All @@ -95,6 +104,8 @@ fn millis() {
assert_eq!(Duration::from_micros(1_001_000).subsec_millis(), 1);
assert_eq!(Duration::from_nanos(999_999_999).subsec_millis(), 999);
assert_eq!(Duration::from_nanos(1_001_000_000).subsec_millis(), 1);
assert_eq!(Duration::from_nanos_u128(999_999_999).subsec_millis(), 999);
assert_eq!(Duration::from_nanos_u128(1_001_000_001).subsec_millis(), 1);
}

#[test]
Expand All @@ -109,6 +120,8 @@ fn micros() {
assert_eq!(Duration::from_micros(1_000_001).subsec_micros(), 1);
assert_eq!(Duration::from_nanos(999_999_999).subsec_micros(), 999_999);
assert_eq!(Duration::from_nanos(1_000_001_000).subsec_micros(), 1);
assert_eq!(Duration::from_nanos_u128(999_999_999).subsec_micros(), 999_999);
assert_eq!(Duration::from_nanos_u128(1_000_001_000).subsec_micros(), 1);
}

#[test]
Expand All @@ -123,6 +136,8 @@ fn nanos() {
assert_eq!(Duration::from_micros(1_000_001).subsec_nanos(), 1000);
assert_eq!(Duration::from_nanos(999_999_999).subsec_nanos(), 999_999_999);
assert_eq!(Duration::from_nanos(1_000_000_001).subsec_nanos(), 1);
assert_eq!(Duration::from_nanos_u128(999_999_999).subsec_nanos(), 999_999_999);
assert_eq!(Duration::from_nanos_u128(1_000_000_001).subsec_nanos(), 1);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a test to duration_const below (look for const NANOS)

#[test]
Expand Down
Loading