-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve std::time::Instant
documentation - OS behavior
#79881
Comments
To address the first issue, we could start with this: /// let big_chunk_of_time = 20_000_000_000;
/// let duration = Duration::new(big_chunk_of_time, 0);
The original Alternatively, we could try to calculate something possibly closer to the point of overflow on macOS. If the internal /// let millenia_in_secs = 31_557_600_000;
/// let duration = Duration::new(millenia_in_secs, 0);
Which actually turns out to be larger than the previous value, but However the value within All three task items could perhaps be resolved with something like this perhaps: /// # OS-specific behaviors
///
/// An `Instant` is a wrapper around system-specific types. It may behave
/// differently depending upon the underlying operating system. Additionally
/// the inconsistency in internal type attributes and representation results in
/// differences in the size of duration than can be added without the
/// calculation overflowing. For example, the following snippet works fine on
/// Linux but panics on macOS:
///
/// ```no_run
/// use std::time::{Instant, Duration};
///
/// let now = Instant::now();
/// let millenia_in_secs = 31_557_600_000;
/// let duration = Duration::new(millenia_in_secs, 0);
/// println!("{:?}", now + duration);
/// ```
///
/// For cross-platform code, you may find that you can comfortably add
/// durations up to around one hundred years. Pinning down exact numbers is
/// made complicated by underlying hardware specific attributes.
Perhaps a fourth task item could be to ensure that there's a test that enforces that durations up to 100 years can be added successfully on all platforms? |
This feels like it would be somewhat out of our control if it were to change, and also doesn't seem like a very useful thing to require for At least, it's not something that it feels like we'd want to make tradeoffs in favor of, nor is it one we'd want to be in the business of guaranteeing going forwards, I think. On macOS we're at the mercy of the mach_absolute_time timebase (which apple has made very clear that people should be handling correctly, as it's going to change), on Windows by the QPF result, etc. It seems like it would be a pretty unfortunate situation if we had to use a less ideal measurement for Instant in the future because we promised a particular range of values will work, and the better timestamp can't represent that range. [0]: The only time I can think of it coming up is if the code wants to express a notion like "infinitely far in the future", which perhaps is an argument that it should be expressible some other way. |
@thomcc, I completely agree that adding such large time durations is probably not going to be done in practice. In terms of the test, I was not suggesting that we provide any guarantee as you describe, I was suggesting that we provide a suggestion of what might be possible as per the last block of text I wrote, and use the test as a canary to warn us if the situation ever changes, such that we can know to update the documentation (and test) accordingly. Edit: I mean this was what I meant to suggest. |
The following piece of documentation from
std::time::Instant
, which comes from PR #72836 via issue #48980, does not make sufficient sense and is not sufficiently helpful:The parameters to
Duration::new()
are the number of seconds and the number of nanoseconds. Here we seem to be giving a quantity in nanoseconds as the number of seconds, and with that quantity representing... well, from the namemax_nanoseconds
and calculation, the maximum number of seconds that can fit into au64
if it later it is to be converted to au64
quantity of nanoseconds without overflowing... huh :S The reviewers of PR #72836 seem to have overlooked this problem.This text and example are there due to the fact that the internal attributes of
Instant
differ per different platforms, and so a largeDuration
added to anInstant
on one platform might work, while on another it might overflow and thus panic.Here it follows that
u64::MAX / 1_000_000_000
as the number of seconds in aDuration
just happens to be too large for addition to anInstant
on some platforms - macOS. The problem with the example fundamentally is the misleading variable name and possibly poor choice of chosen value.One further problem with the text is that although it is helpful in pointing out that there is a difference in behaviour, it leaves the reader to have to guess at what the cause of the different behaviour is, and it does not give any indication of what range of values can typically be added to it without encountering failure.
I don't know why
Instant
has been designed to use different underlying attributes rather than something consistent which would avoid it suffering from this unfortunate inconsistency, but I'll leave that for separate discussion / resolution, which already seems to have gone no-where in #48980, though #44394 forSystemTime
is still open.Tasks to address this issue:
The text was updated successfully, but these errors were encountered: