introduce the Comparable trait for BTree operations#144506
introduce the Comparable trait for BTree operations#144506conradludgate wants to merge 6 commits intorust-lang:mainfrom
Conversation
|
r? @ibraheemdev rustbot has assigned @ibraheemdev. Use |
|
r? libs-api because this is related to a future API change, I'm sure if this is the best way to proceed. |
|
We discussed this in the @rust-lang/libs-api meeting and would be interested in having these traits in the standard library. An idea also came up to also provide blanket implementations of these traits for tuples of types implementing We are however not willing to accept this PR as it is: we want these traits to be public and tracked by a tracking issue so that people can start experimenting with them on nightly. cc @cuviper |
|
Ok. I can create a tracking issue and update the PR to expose these traits in core with some blanket impls |
This comment has been minimized.
This comment has been minimized.
8ee7f33 to
4dd7d91
Compare
This comment has been minimized.
This comment has been minimized.
4dd7d91 to
578b1b4
Compare
This comment has been minimized.
This comment has been minimized.
Doesn't seem to be possible. |
This comment has been minimized.
This comment has been minimized.
Right, It would probably make a good example though, e.g. some kind of |
|
Could we make this work by moving the reference to |
|
☔ The latest upstream changes (presumably #146160) made this pull request unmergeable. Please resolve the merge conflicts. |
c9fb097 to
44d3e27
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
|
This will most likely need a crater run to see if changing the parameters of stable functions breaks anything. |
|
I believe we also have an insta-stable hazard for the (&K1, &K2) impl |
|
The job Click to see the possible cause of the failure (guessed by this bot)For more information how to resolve CI failures of this job, visit this link. |
|
Well, I don't think we need a crater run 😅 |
| /// | ||
| /// This trait allows ordered map lookup to be customized. | ||
| #[unstable(feature = "comparable_trait", issue = "145986")] | ||
| pub trait Comparable<Q> { |
There was a problem hiding this comment.
With all your Clone additions, it sure would be nice if we could force Comparable<Q: Clone> here instead, but I don't think that would get elaborated elsewhere. This would work better the other way with Q: Comparable<K>, because then we could add a supertrait Comparable: Clone.
Also, I think Copy would be better, because it would be a perf footgun if some user type with non-trivial Clone was use for lookup.
Yeah, this is damning against changing the type parameters. Too bad. |
| /// | ||
| /// This trait allows ordered map lookup to be customized. | ||
| #[unstable(feature = "comparable_trait", issue = "145986")] | ||
| pub trait Comparable<Q> { |
There was a problem hiding this comment.
BTW, the tracking issue declares Comparable: Equivalent, but that relationship is missing here -- are you purposely leaving that out?
There was a problem hiding this comment.
I was implementing as it was given in rust-lang/libs-team#699 (comment). No supertrait relationship there, but I did consider that it was potentially an oversight
I think we can still do this over an edition by making use of edition-dependent name resolution. But yea, this is effectively dead until we have support for this in the compiler. |
| impl<'a, Q1: ?Sized, K1, Q2: ?Sized, K2> Equivalent<(&'a Q1, &'a Q2)> for (K1, K2) | ||
| where | ||
| Q1: Eq, | ||
| K1: crate::borrow::Borrow<Q1>, | ||
| Q2: Eq, | ||
| K2: crate::borrow::Borrow<Q2>, | ||
| { | ||
| #[inline] | ||
| fn equivalent(&self, key: (&'a Q1, &'a Q2)) -> bool { | ||
| PartialEq::eq(self.0.borrow(), key.0) && PartialEq::eq(self.1.borrow(), key.1) | ||
| } | ||
| } |
There was a problem hiding this comment.
I think this should allow the inner members to use the new trait too:
| impl<'a, Q1: ?Sized, K1, Q2: ?Sized, K2> Equivalent<(&'a Q1, &'a Q2)> for (K1, K2) | |
| where | |
| Q1: Eq, | |
| K1: crate::borrow::Borrow<Q1>, | |
| Q2: Eq, | |
| K2: crate::borrow::Borrow<Q2>, | |
| { | |
| #[inline] | |
| fn equivalent(&self, key: (&'a Q1, &'a Q2)) -> bool { | |
| PartialEq::eq(self.0.borrow(), key.0) && PartialEq::eq(self.1.borrow(), key.1) | |
| } | |
| } | |
| impl<Q1, K1, Q2, K2> Equivalent<(Q1, Q2)> for (K1, K2) | |
| where | |
| K1: Equivalent<Q1>, | |
| K2: Equivalent<Q2>, | |
| { | |
| #[inline] | |
| fn equivalent(&self, key: (Q1, Q2)) -> bool { | |
| K1::equivalent(&self.0, key.0) && K2::equivalent(&self.1, key.1) | |
| } | |
| } |
(assuming we solve the API evolution problem to enable this at all)
View all comments
Tracking issue: #145986
This introduces the Equivalent and Comparable traits into core, under the
comparable_traitfeature flag. This exposesComparablefor btree key lookups, with a blanket impl forBorrowkeys to remain backwards compatible.The one annoying thing is that we still need
Q: Ordin order to provide the panic messages for bad usage in range queries. One could likely address this but it would move the branch inside the search loop which might impact performance. Another approach is to move the condition out, but that won't help if we want the same helpful panic condition in any potential exposed API. Note that this check is not needed for memory safety (as we already have to deal with invalid Ord impls) so maybe such a check is not really that necessary. The alternative is we accept thisQ: Ordbound as not a significant limitation.