-
Notifications
You must be signed in to change notification settings - Fork 16
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
Instant::cmp doesnt comply with Ord requirements #36
Comments
Hi, thanks for reporting. While it does try to handle wrap-arounds The recommendation I can give is to use a storage type that makes the I think this implicit requirement in |
In the mean time I also saw #35. Which happens to be similar to what hapend to me. I used I understand the intention of the wrapping behavior. However this still breaks the contract of So I think it's just not possible to both support the wrapping behavior of From a practical point of view: If the underlying datatype is large enough that wraparounds don't happen, the wrapping behavior in What about implementing |
The wrapping behavior is the same as with e.g. an
Makes sense,
This is true, however I have not found a way to do this without traits, e.g. a
I'm not sure how this would be done in practice. |
Is it really the same situation as For So |
This could be a valid approach to implement |
Another option could be to hide the That would be a breaking change, so perhaps it should only be announced in the docs and then implemented in the next major version? |
Yeah it's not straight forward on how to solve this. I merged your comment update as the first thing. The thing is, as I see it (and designed it) is that Hence I'm not that keen on changing, or hiding, this part of the API. |
To stretch the analogy of Fortunately, this is not really Unfortunately, I don't see a good way to prevent such bugs, short of the two suggested changes: Either modifying the behavior of (That's why I suggested to hide it behind a feature flag: Chances are, before adding a feature flag, a careful programmer would check the documentation of that flag for its meaning. Though I must admit that this isn't a silver bullet either, as the flag may have been activated by some other crate, so the developer may not even notice that it is set.) |
What I think is that Also maybe only implementing |
That marker trait sounds like a good idea. However, deciding that automatically depending on T, NOM and DENOM needs |
See korken89/fugit#36. Here, we know that the underlying u64 won't overflow, so const_cmp is fine.
See korken89/fugit#36. Here, we know that the underlying u64 won't overflow, so const_cmp is fine.
Unfortunately not in stable Rust. |
See korken89/fugit#36. Here, we know that the underlying u64 won't overflow, so const_cmp is fine.
See korken89/fugit#36. Here, we know that the underlying u64 won't overflow, so const_cmp is fine.
The implementation
impl<const NOM: u32, const DENOM: u32> Ord for Instant<u64, NOM, DENOM>
(and same withu32
) doesn't comply with the specified requirements for implementations ofOrd
.Ord
requires the comparison to be transitive, ie. a < b and b < c implies a < c. (see https://doc.rust-lang.org/std/cmp/trait.Ord.html#corollaries)However the current implementation tries to handle wrap-around of the underlying ticks counter:
https://github.com/korken89/fugit/blob/master/src/instant.rs#L55-L70. That breaks the mentioned requirement.
So either the implementation should be changed, or Instant should not implement
Ord
(and neitherPartialOrd
).I noticed this when trying to find the minimum in a list of Instants, and getting inconsistent results.
The text was updated successfully, but these errors were encountered: