-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking issue for duration_constants #57391
Comments
Currently these constants are free constants in the |
@SimonSapin We should definitely do that! Another related constant is Then, in 1.28.0, it was added again as associated constant Following that precedent, I'd infer associated constants would probably be more idiomatic here. |
…iated, r=oli-obk Turn duration consts into associated consts As suggested in rust-lang#57391 (comment), I'm moving `Duration` constants (`SECOND`, `MILLISECOND` and so on; currently behind unstable `duration_constants` feature) into the `impl Duration` block. cc @frewsxcv @SimonSapin
…iated, r=oli-obk Turn duration consts into associated consts As suggested in rust-lang#57391 (comment), I'm moving `Duration` constants (`SECOND`, `MILLISECOND` and so on; currently behind unstable `duration_constants` feature) into the `impl Duration` block. cc @frewsxcv @SimonSapin
…iated, r=oli-obk Turn duration consts into associated consts As suggested in rust-lang#57391 (comment), I'm moving `Duration` constants (`SECOND`, `MILLISECOND` and so on; currently behind unstable `duration_constants` feature) into the `impl Duration` block. cc @frewsxcv @SimonSapin
…iated, r=oli-obk Turn duration consts into associated consts As suggested in rust-lang#57391 (comment), I'm moving `Duration` constants (`SECOND`, `MILLISECOND` and so on; currently behind unstable `duration_constants` feature) into the `impl Duration` block. cc @frewsxcv @SimonSapin
…iated, r=oli-obk Turn duration consts into associated consts As suggested in rust-lang#57391 (comment), I'm moving `Duration` constants (`SECOND`, `MILLISECOND` and so on; currently behind unstable `duration_constants` feature) into the `impl Duration` block. cc @frewsxcv @SimonSapin
@SimonSapin I think we're ready for FCP to merge now. |
Updated the issue description. @rfcbot fcp merge |
Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
@rfcbot concern missed the point As I understand it, the point of duration constants when they were suggested in #51610 (comment) was to enable pithy code like: thread::sleep(2 * SECOND); As currently implemented, this would not be supported because associated constants cannot currently be imported. error[E0432]: unresolved import `std::time::Duration`
--> src/main.rs:3:16
|
3 | use std::time::Duration::SECOND;
| ^^^^^^^^ not a module `Duration` So what we have is: thread::sleep(2 * Duration::SECOND); which may not be sufficiently better than: thread::sleep(Duration::from_secs(2)); Would it make sense to revisit whether module level constants would be better? Or is there work in progress on making associated constants importable? |
@rfcbot concern consider unit structs This looks weird: thread::sleep(SECOND); In practice hopefully people would realize to write: thread::sleep(1 * SECOND); I haven't thought through this fully, but maybe it would be better to define units as unit structs rather than constants of type Duration? thread::sleep(Second); // does not compile
thread::sleep(1 * Second); Worth it, or too confusing? |
@rfcbot concern clippy It would be nice if Clippy didn't lint 1 * Duration::CONSTANT at stabilization. warning: the operation is ineffective. Consider reducing it to `Duration::SECOND`
--> src/main.rs:7:19
|
7 | thread::sleep(1 * Duration::SECOND);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(clippy::identity_op)] on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#identity_op |
Another thought, but not a blocker: const TIMEOUT: Duration = Duration::from_secs(5); I hope that eventually N * Duration can be const. Does anyone know if there is any hope of this being supported, given that there is a trait method call involved? const TIMEOUT: Duration = 5 * Duration::SECOND; error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> src/main.rs:6:27
|
6 | const TIMEOUT: Duration = 5 * Duration::SECOND;
| ^^^^^^^^^^^^^^^^^^^^ |
Oh, I didn't realize that! :(
Another possibility is to have both, just like there is Also yes, I don't see a reason why associated constants shouldn't be importable.
Interesting idea... this way we would distinguish durations from units. I'm not against, but also find it a little magical. |
@rfcbot resolve consider unit structs Too confusing. @rfcbot resolve clippy I filed rust-lang/rust-clippy#3866 to follow up in Clippy. This does not need to block stabilization. @rfcbot resolve missed the point I don't want to block on this if others feel that these constants are a better idiom than Duration::from_N. I would ask that we please not stabilize under the hope that they become directly importable. If we stabilize, it should be because we believe the constants are good to have even if importing them never ends up happening. What do you think @stjepang? The most recent I could find on importing associated items is this i.r-l.o comment by @petrochenkov and it does not sound imminent. I would slightly favor moving these out to @rfcbot concern documentation One thing I would still like to block on is better documentation before I would be comfortable with these appearing in release notes. The current example code for these constants looks like: use std::time::Duration;
assert_eq!(Duration::SECOND, Duration::from_secs(1)); Example code is supposed to communicate why someone would want to use a thing, not only how to refer to it. These examples only show how to import and refer to the constant but not why anyone would want to do that. |
Not being able to import associated constants is a real bummer. Still, I prefer In the ideal world, we'd probably only have importable associated constants. But it's interesting how there is some precedent for redundancy in other similar cases: I think I'd be fine with both
And what about const methods like
Would you be okay with copying examples from constructor methods? For example, we could steal the example from use std::time::Duration;
let duration = 2569 * Duration::MILLISECOND;
assert_eq!(2, duration.as_secs());
assert_eq!(569_000_000, duration.subsec_nanos()); |
I think we should use associated constants and deprecate redundancies. Assuming that associated constant imports will work of course. I always found absence of I think if we'll get a working import of associated constants we can remove integer modules altogether in a backwards-compatible way. Float modules unfortunately contain |
If I may bring up a bikeshed, considering that the |
I was trying this out today, and was confused for a bit that use std::time;
futures_timer::wait_for(30 * time::SECONDS).await;
for instant in futures_timer::repeat(5 * time::MINUTES).await {
println!("the time is {}", instant);
} Having these live on use std::time;
futures_timer::wait_for(30 * time::Duration::SECONDS).await;
for instant in futures_timer::repeat(5 * time::Duration::MINUTES).await {
println!("the time is {}", instant);
} I guess importing use std::time::{UNIX_EPOCH, Duration};
futures_timer::wait_for(30 * Duration::SECONDS).await;
for now in futures_timer::repeat(5 * Duration::MINUTES).await {
println!("{} hours since the unix epoch", now - UNIX_EPOCH);
} As others have said before, a function would be about as long to write as the current exports, and feel far more familiar. But I do think there's a lot of value in having these constants exist, if they are placed in a slightly more accessible location. I hope sharing my experience here is useful. Thanks! edit: I've written a blog post about this https://blog.yoshuawuyts.com/std-time/ |
I wouldn't expect there to need to be a prelude because of this new trait (I'm in the preludes-are-bad camp). It can just be a trait import. I also think that since the trait would have the methods called on integers (and such), the fuller name is required to be clearer. Otherwise, what is // name TBD
trait TimeUnits {
fn seconds(&self) -> Duration;
fn milliseconds(&self) -> Duration;
// etc
} Then it's usage could look like this: use std::time::{Instant, TimeUnits as _};
sleep(100.milliseconds());
let deadline = Instant::now() + 5.seconds(); |
@BurntSushi @faern @stepancheg See rust-lang/rfcs#2700 for similar discussions about associated constants. |
I agree with @leoyvens. |
Cancelling because this stalled out, but a significant amount of design discussion happened after the first FCP proposal. It would be good if someone could put together a recap of the alternatives and tradeoffs and based on that propose how it's best to move forward @rfcbot fcp cancel |
@dtolnay proposal cancelled. |
Yes, this would be much more appropriate than the current documentation. |
It would be awesome if one could "bundle" together definitions so that using one brings the other into scope for the expression where it's used. For example, if one used |
The Currently the docs specify that it will be equal to zero and "roughly 584,942,417,355 years". I would find it very surprising if the value of such a constant would change between Rust versions. The integer equivalents, So we must either be fine with having constants that change value between Rust versions. Or we must accept the current definition of |
In #78216 I introduced Duration::ZERO, which resolves that for Duration::MIN by being a logical constant and not a repr-sensitive constant, and accordingly removed Duration::MIN. That is one way to simplify an API and its concerns, I suppose. I do not believe Duration::MAX should be under this feature flag because while it is a constant it has a very different purpose and that is a reasonable concern that is directly related to its intention (saturating ops) and is completely different from most of the concerns here. I also do not have a good answer for what to do with it aside from that reshuffling, however. |
It has not promised such, and I think it shouldn't, for reasons like e.g. the Y2K problem, a bursting dam of technical debt which required thousands of hours of labor to address. So I believe Duration::MAX should remain "implementation defined". An associated constant is associated, as such, with the implementation of the type, which in this case is likely to be platform and even literally time-sensitive. I believe, however, for a given platform, MAX should not decrease, and for all platforms in a given set, MAX should encompass at least some range of time T. |
I opened PR #84120 to stabilize |
To address @faern's wise remarks, I added some documentation to #84120 to this effect. In particular, |
…ax, r=m-ou-se Stabilize Duration::MAX Following the suggested direction from rust-lang#76416 (comment), this PR proposes that `Duration::MAX` should have been part of the `duration_saturating_ops` feature flag all along, having been 0. heavily referenced by that feature flag 1. an odd duck next to most of `duration_constants`, as I expressed in rust-lang#57391 (comment) 2. introduced in rust-lang#76114 which added `duration_saturating_ops` and accordingly should be folded into `duration_saturating_ops` and therefore stabilized. r? `@m-ou-se`
I was amazed by how long this has been opened. There are two possibilities -Close the issue as why even bother with (Duration::SECOND) when we already have (Duration::from_secs(n)) *Just a mere opinion at worst, Duration is not in scope instead of At best |
Implemented in #57375
The text was updated successfully, but these errors were encountered: