Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement Mul<u64> and Div<u64> for Duration #32515
Conversation
rust-highfive
assigned
alexcrichton
Mar 26, 2016
This comment has been minimized.
This comment has been minimized.
|
(rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
|
Hm the breakage with unsuffixed literals indeed seems like a non-starter here. I wonder if it'd be worth investigating the underlying type inference bug? |
This comment has been minimized.
This comment has been minimized.
|
Not sure it's a bug strictly - there's no precedence on which integer type a literal should be if multiple apply and none are |
This comment has been minimized.
This comment has been minimized.
|
Can you fix the inference regression by implementing the ops for It seems to work (adds a warning though). |
This comment has been minimized.
This comment has been minimized.
|
I'd be a bit uncomfortable with that - |
This comment has been minimized.
This comment has been minimized.
|
@sfackler is correct that this isn't a bug. We made the decision to allow "input" types to a trait (like type parameters) influence type inference, which is often helpful, but can be brittle when you add new impls. It's possible that default type parameter fallback could help here, but I don't immediately see a route. This is a kind of API evolution we certainly should allow, but the interconnecting pieces are really tricky (and the future of even default param fallback is in question). So (1) I will take this example into consideration on the lang design front and (2) meanwhile, we should figure out a different route to gain this functionality. |
This comment has been minimized.
This comment has been minimized.
|
Bah oh well. An idea, though, perhaps? impl<T: Into<u64>> Mul<T> for Duration {
// ...
}Now that we have a number of |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I tried plugging that into my test above, it doesn't really solve the problem. |
aturon
added
the
T-libs
label
Mar 28, 2016
This comment has been minimized.
This comment has been minimized.
|
The libs team discussed this PR during triage and the decision was to merge with an inherent method of a name other than |
sfackler
force-pushed the
sfackler:duration-u64
branch
from
30974c5
to
fb574b2
Mar 31, 2016
This comment has been minimized.
This comment has been minimized.
|
I updated the PR to move these to |
ranma42
reviewed
Mar 31, 2016
| #[unstable(feature = "duration_u64", reason = "newly added", issue = "0")] | ||
| pub fn div_u64(&self, rhs: u64) -> Duration { | ||
| let secs = self.secs / rhs; | ||
| let carry = self.secs - secs * rhs; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
AFAIK it requires either a muldiv-like operation (which would be the best option at least on x86), or Looks like one use case for rust-lang/rfcs#1504 |
This comment has been minimized.
This comment has been minimized.
|
@sfackler maybe this function can help? |
This comment has been minimized.
This comment has been minimized.
|
Ooh, nice, that looks like exactly what's needed! I'll update tonight. |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
Hm can you clarify? The operation we want is
Which when substituted looks like:
Given that, where does |
This comment has been minimized.
This comment has been minimized.
|
The docs on mul_div_u64 state that it "Computes (value * numer) / denom without overflow, as long as both (numer*denom) and the overall result fit into i64 (which is the case for our time conversions)", since |
This comment has been minimized.
This comment has been minimized.
|
Ok, well I'm basically lost in the weeds of what's going on, is this blocked on landing until that's fixed? |
This comment has been minimized.
This comment has been minimized.
|
I think the best approach would probably be to add some intrinsics to have LLVM generate u64 * u64 -> u128 and u128 / u64 -> u64 logic for us. Doing it correctly by hand is really complex in the general case: https://github.com/sdroege/rust-muldiv/blob/master/src/u64_muldiv.rs but really simple on common architectures: https://github.com/sdroege/rust-muldiv/blob/master/src/u64_muldiv_x86_64.rs |
This comment has been minimized.
This comment has been minimized.
|
I created a time2 crate that adds these methods and a few others - https://github.com/sfackler/rust-time2. I think it makes more sense for it to bake out there for now and then move a larger set of functionality in later. |
sfackler commentedMar 26, 2016
This probably can't merge as-is because it breaks any code that
multiplies or divides a Duration by an unsuffixed literal :(
However, these operations are useful in many contexts (e.g. data
transfer estimation) where a u32 isn't big enough and the logic is
pretty complex, especially for multiplication. Hopefully we can expose
these in some way?
cc @rust-lang/libs
Any ideas on where to go with this functionality, @aturon?