Skip to content

Move std::time::Instant to core - #159421

Open
bushrat011899 wants to merge 2 commits into
rust-lang:mainfrom
bushrat011899:core_time_instant
Open

Move std::time::Instant to core#159421
bushrat011899 wants to merge 2 commits into
rust-lang:mainfrom
bushrat011899:core_time_instant

Conversation

@bushrat011899

@bushrat011899 bushrat011899 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

ACP: None (happy to create one if requested!)
Tracking Issue: None
Feature Gate: core_time_instant

Background

Instant is currently provided by std as it has a platform specific internal representation. However, this representation is currently unavailable to users. That is, there is no method to convert to an from a system-specific value. As such, users do not actually benefit from this platform dependent representation. Further, since the type is defined in std and entirely opaque, libraries such as web-time must recreate the Instant API to act as a polyfill. Even though wasm32-unknown-unknown has access to std, its now() implementation is a panic-stub, so this library is virtually required when writing Rust for the browser.

This reliance on a 3rd party polyfill is frustrating for end users. As an example, wasm32v1-none is currently incompatible with the polyfill due to its lack of no_std support.

Solution

Instead, I propose standardising on Duration as the canonical internal representation of an Instant. As is already the case, the meaning of the internal value is undefined. Users do not have safe access to this value and are provided no guarantees around its reference point.

With a standard representation, Instant can then be moved to core::time, allowing no_std libraries access to the type. Creating a value of type Instant is still restricted to std in safe Rust. This is done by leaving now() and elapsed() in std as incoherent methods.

To allow 3rd party libraries such as web-time to be substantially simplified, I am also proposing Instant be a repr(transparent) type, which will allow using transmute to convert between a Duration and Instant without causing UB. This will allow polyfills for Instant to simply provide now() and elapsed() as trait extension methods on the core type. In the future, these could be brought into core as well using EII.

Platform Specific Changes

  • On Windows, Instant would consider anything within an epsilon() to be equivalent. Instead of checking against epsilon at comparison, I round the internal Duration to the next multiple of epsilon at creation. I believe this should give the same effect in mitigating measurement noise.
  • For Unix, Hermit, and Solid, Instant now has an layout equivalent to Duration. All other platforms were already a wrapper around Duration.

Notes

  • No AI tooling of any kind was used during the creation of this PR.
  • Creating based on my own personal frustrations with working on time for crates like Bevy and Wgpu. Would love feedback from the Libs team to see if this is something that could be generally supported!
  • I have not (yet) created an ACP or RFC as a PR is simple enough for this change that I thought it would be more useful to just review the change directly. Happy to create one if requested!
  • The ability to create an Instant through transmutation would likely resolve Add explicit or zero constructor for std::time::Instant #40910, and be substantially helpful for libraries such as mock_instant. This isn't the reason for my effort, but it is worth noting.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 17, 2026
@rustbot

rustbot commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

r? @JohnTitor

rustbot has assigned @JohnTitor.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ChrisDenton, libs
  • @ChrisDenton, libs expanded to 13 candidates
  • Random selection from 6 candidates

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bushrat011899
bushrat011899 force-pushed the core_time_instant branch 2 times, most recently from 849aedc to 678fff5 Compare July 17, 2026 09:47
@rust-log-analyzer

This comment has been minimized.

///
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[rustc_has_incoherent_inherent_impls]
#[repr(transparent)]

@bjorn3 bjorn3 Jul 17, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#[repr(transparent)]
#[repr(transparent)]
#[rustc_pub_transparent]

and missing docs about this. In any case I think having to transmute is a hack.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Didn't know about that attribute, added!

It's definitely hacky. My rationale is this is something unsafe and to be discouraged. Having an unsafe function to do the conversion would make it more readily visible (e.g., in docs.rs and code suggestions).

I would also like to note that public transparency can be removed from this PR and still provide utility. Crates like Winit include Instant in their public API but only the user ever supplies the value. Having Instant in libcore would allow such crates to avoid feature gating.

@bjorn3

bjorn3 commented Jul 17, 2026

Copy link
Copy Markdown
Member

How would you handle mixing of web-time with std::time::Instant::now() on a future web target where std::time::Instant::now() works? web-time and std::time::Instant::now() may disagree about both the epoch and the clock source in that case.

Leave `now()` and `elapsed()` as incoherent methods in `std`. The new `Instant` is now always a transparent wrapper around `Duration`, which allows 3rd party libraries to provide `Instant` functionality on `no_std` platforms. This also allows `no_std` libraries to refer to `Instant` without a feature gate.
Co-Authored-By: bjorn3 <17426603+bjorn3@users.noreply.github.com>
@joboet

joboet commented Jul 17, 2026

Copy link
Copy Markdown
Member

For reference, the internal representation of Instant is likely to change in #158368.

@bushrat011899

Copy link
Copy Markdown
Contributor Author

How would you handle mixing of web-time with std::time::Instant::now() on a future web target where std::time::Instant::now() works? web-time and std::time::Instant::now() may disagree about both the epoch and the clock source in that case.

Definitely messy. Even without the hypothetical target, I think it'd be likely that crates like web-time would offer now and elapsed under a different name anyway, since you'd need to avoid accidentally calling the panic-stub on wasm32-unknown-unknown. Perhaps a safety invariant could be that every Instant value must be from the same clock and reference point? That would prohibit libraries from offering safe now and elapsed implementations unless they know that no other reference/clock is used.

For reference, the internal representation of Instant is likely to change in #158368.

Was unaware of this PR! I checked through the open issues for anything like this but I clearly should've checked the PRs too. Regardless of the specific internal representation, having the type declared in core would be excellent. I'll mark this PR as blocked since the signed Duration representation definitely makes more sense, and it looks like that PR is generally well received and likely to land.

@rustbot blocked

@rustbot rustbot added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 17, 2026
@ChayimFriedman2

Copy link
Copy Markdown
Contributor

There are two unrelated things here. Exposing the internal structure of an Instant (which, from what I see, is not even done here, even though it's the stated goal), and putting it in core. This PR confuses between them even though they should really be discussed separately (for instance, the PR title is "Move std::time::Instant to core" but its description actually talks about how Instant being opaque is a problem). Even if we decide to make Instant non-opaque (a really non-trivial decision; it's documented to be opaque - you didn't even remove that!), whether we should put it in core is a separate matter and should be discussed separately.

@rust-bors

rust-bors Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #161338) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-blocked Status: Blocked on something else such as an RFC or other implementation work. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add explicit or zero constructor for std::time::Instant

7 participants