-
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
Add max and min to Ord #42496
Add max and min to Ord #42496
Conversation
Pursuant to issue #25663, this commit adds the max and min functions to the Ord trait, enabling items that implement Ord to use UFCS (ex. 1.max(2)) instead of the longer std::cmp::max(1,2) format.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @aturon (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
/// ``` | ||
#[unstable(feature = "ord_max_min", issue = "25663")] | ||
fn max(self, other: Self) -> Self | ||
where Self: Sized { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is the best place to discuss this, but I think both of these could take (&self, other: &Self)
and allow us to relax the Self: Sized
bound -- getting an ordering doesn't require by-value access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chose to use by-value access because that's the same as what the std::cmp::max|min
code below this does, and this PR is essentially moving those fns into Ord
.
Plus, this isn't getting an Ordering
the way cmp above is, but moving/copying both values in, comparing them, and then returning one. I think if I took (&self, other: &Self)
, I'd have to return a &Self
, which would violate the API defined by std::cmp::max|min
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to keep them for now, but wanted to bring it up since maybe others will want to change it "while we're at it."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an issue with it either way, I was just keeping things similar to what already existed since that results in less surprises.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that T
is a more helpful return type than &T
.
Also, #25663 (comment) argues for consistency with the inherent impl on fN:
I often write performance-sensitive graphics code, which I prototype on floats for ease of writing, and then where appropriate change to use integers for speed/memory efficiency. 90% of calculations just work, and max is one of the warts that doesn't.
Shame that a.min(&b)
fails to compile instead of auto-deref'ing to (&a).min(&b)
, as it'd be an elegant way to use the impl<T:Ord> Ord for &T
where borrow comparison is desirable...
Aturon's on vacation this week, sorry this fell through the cracks last week! Let's try... r? @BurntSushi |
LGTM! Thank you! @bors r+ |
📌 Commit a32ffc6 has been approved by |
⌛ Testing commit a32ffc6 with merge 378887b... |
💔 Test failed - status-travis |
@bors retry
|
…=BurntSushi Add max and min to Ord Pursuant to issue rust-lang#25663, this PR adds max and min methods with default implementations to std::cmp::Ord. It also modifies std::cmp::max|min to internally alias to Ord::max|min, so that any overrides of the default implementations are automatically used by std::cmp::max|min. Closes rust-lang#25663
☔ The latest upstream changes (presumably #42644) made this pull request unmergeable. Please resolve the merge conflicts. |
The current Rust nightly introduced a breaking change [1] that is causing the build to fail for the nightly channel. The affected crate, petgraph, has been updated [2] so it now compiles on nightly again, but unfortunately I cannot use the latest version of that crate, because it is a transitive dependency, and the crate which depends on it depends on a version that Cargo considers semver-incompatible with the fixed crate. The crate which depends on the crate broken by Rust nightly is lalrpop, and a new version of it has been released that depends on a newer version of petgraph which *is* semver-compatible with the fixed release. However, upgrading to a newer version of lalrpop is also not possible, because it requires a newer version of Rust. (Even after I contributed a fix for that, and despite the changelog claiming to support Rust 1.13 now, it is still broken on 1.13 because of the lalrpop-snap crate.) So now I am in a situation where I either have to drop support for Rust 1.13 and upgrade dependencies, or drop support for nightly Rust. The least invasive change to my code at this point, is to drop support for the nightly channel. Unfortunately that is only a temporary solution, because the breakage is going to make it into beta and then stable. But I am working on a hand-written parser anyway which will replace lalrpop, so that dependency, and the dependency on petgraph, can hopefully be dropped soon. That would maintain compatibility with Rust 1.13, and restore compatibility with nightly at the same time. A third option would be to ask the petgraph maintainers to release a patch release of the older version that lalrpop depends on, which was broken by Rust nightly. But for now the easiest thing for me to do to get the build green, is to drop support for nightly Rust. [1]: rust-lang/rust#42496 [2]: petgraph/petgraph#153
This had causes quite a few regressions in code. Do we still want this in this form? |
Is there a tracking issue for these regressions? There do seem to be a fair number of them. cc @rust-lang/libs |
@BurntSushi I don't know of any tracking issue for regressions. Looks like there are 7 linking to this issue, with only 2 still open. I consider this an acceptable count, given that this was permissible breakage. |
This did I think cause more regressions than we thought was going to happen. In that sense I wouldn't be opposed if it was proposed to be reverted, but I also don't think I'd advocate for reverting this. |
rust-lang/rust#42496 means that 0.4.4 no longer compiles with the most recently released rust toolchain. This was fixed in petgraph/petgraph#154 which is in 0.4.5.
Lower the priority of unstable methods when picking a candidate. Previously, when searching for the impl of a method, we do not consider the stability of the impl. This leads to lots of insta-inference-regressions due to method ambiguity when a popular name is chosen. This has happened multiple times in Rust's history e.g. * `f64::from_bits` #40470 * `Ord::{min, max}` #42496 * `Ord::clamp` #44095 (eventually got reverted due to these breakages) * `Iterator::flatten` #48115 (recently added) This PR changes the probing order so that unstable items are considered last. If a stable item is found, the unstable items will not be considered (but a future-incompatible warning will still be emitted), thus allowing stable code continue to function without using qualified names. Once the unstable feature is stabilized, the ambiguity error will still be emitted, but the user can also use newly stable std methods, while the current situation is that downstream user is forced to update the code without any immediate benefit. (I hope that we could bring back `Ord::clamp` if this PR is merged.)
Pursuant to issue #25663, this PR adds max and min methods with default implementations to std::cmp::Ord. It also modifies std::cmp::max|min to internally alias to Ord::max|min, so that any overrides of the default implementations are automatically used by std::cmp::max|min.
Closes #25663