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 upFully generalize cmp instances #20063
Comments
aturon
added
A-libs
labels
Dec 20, 2014
This comment has been minimized.
This comment has been minimized.
|
I don't think we need to do this prior to stabilization, since we can always safely generalize in the future. I'd also like to put some thought into how general we want to make things, but the example above seems like a good minimum. |
This comment has been minimized.
This comment has been minimized.
|
A bit of follow up: I'm seeing some cases where e.g. the |
aturon
added a commit
to aturon/rust
that referenced
this issue
Dec 20, 2014
aturon
added a commit
to aturon/rust
that referenced
this issue
Dec 30, 2014
aturon
added a commit
to aturon/rust
that referenced
this issue
Dec 30, 2014
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Dec 31, 2014
bors
added a commit
that referenced
this issue
Dec 31, 2014
This comment has been minimized.
This comment has been minimized.
|
What's the status of this with #20065 merged? |
This comment has been minimized.
This comment has been minimized.
|
I am guessing the status is that it's done, so I'm giving it a close. Let me know if there's anything specific still missing. |
steveklabnik
closed this
Feb 15, 2015
This comment has been minimized.
This comment has been minimized.
|
@steveklabnik No, this hasn't been done yet. Basically it would require a sweep through all existing impls to generalize them. I'm not sure where you want to track tickets like this. It's generally backwards compatible to make these changes, and not exactly high priority, but something nice for expressiveness and consistency (and definitely does not require an RFC). |
aturon
reopened this
Feb 16, 2015
This comment has been minimized.
This comment has been minimized.
|
Yeah, it's hard because it's not directly actionable, it's more like 'double check all these things.' It'd be nice if we had an actual list. |
This comment has been minimized.
This comment has been minimized.
|
I think the following command gives you a "Good Enough" list of implementations of
Example output on liballoc:
After running that command on every crate, and filtering out types that only have lifetime parameters like
I'll let @aturon pick the subset that would be nice to have for 1.0 ( Disclaimer: This list is not exhaustive, because some lines got wrapped around by the pretty printer and the grep expression expects a single line match. |
This comment has been minimized.
This comment has been minimized.
|
@japaric Sorry for the delay, this comment was buried in my inbox (and I was away on vacation). Anyway:
That makes good sense to me as a 1.0 starting point, and I certainly agree that not all of the listed types should get this treatment. |
This comment has been minimized.
This comment has been minimized.
|
cc #20927 |
This comment has been minimized.
This comment has been minimized.
|
I took a shot at just implementing this manually for
I feel like there should be a nicer solution here. I'm pretty sure that adding type annotations to every |
This comment has been minimized.
This comment has been minimized.
|
Argh! Sounds like it may not be possible to generalise. :( |
huonw
referenced this issue
Aug 11, 2015
Open
More general PartialEq implementation for Option #1239
This comment has been minimized.
This comment has been minimized.
|
It seems type parameter defaults may help to solve the issue @shepmaster met: #![feature(default_type_parameter_fallback)]
enum Maybe<T> { Nothing, Just(T) }
use Maybe::*;
impl<T, U = T> PartialEq<Maybe<U>> for Maybe<T>
where T: PartialEq<U>
{
fn eq(&self, other: &Maybe<U>) -> bool {
match (self, other) {
(&Nothing, &Nothing) => true,
(&Just(ref a), &Just(ref b)) => a == b,
_ => false,
}
}
}
fn main() {
println!("{}", Nothing == Just("foo"));
println!("{}", Just("foo") == Nothing);
}Without the default, both |
This comment has been minimized.
This comment has been minimized.
|
How frustrating (and interesting!). Is it possible to improve default type parameters to allow mutual identity defaults? |
This comment has been minimized.
This comment has been minimized.
|
You aren't currently allowed to forward declare defaults, we might be able to lift that requirement having both be equal should just give you this set of equalities:
|
This comment has been minimized.
This comment has been minimized.
|
I'm up late working on a paper and this thought came to mind, you can encode a cute little trait trick in order to apply a secondary default: #![feature(default_type_parameter_fallback)]
enum Maybe<T> { Nothing, Just(T) }
use Maybe::*;
trait DefaultTo<Ty, Default> {}
impl<T, U=T> DefaultTo<U, T> for () {}
impl<U, T = U> PartialEq<Maybe<U>> for Maybe<T>
where T: PartialEq<U>,
(): DefaultTo<U, T>
{
fn eq(&self, other: &Maybe<U>) -> bool {
match (self, other) {
(&Nothing, &Nothing) => true,
(&Just(ref a), &Just(ref b)) => a == b,
_ => false,
}
}
}
fn main() {
println!("{}", PartialEq::eq(&Nothing, &Just("foo")));
println!("{}", PartialEq::eq(&Just("foo"), &Nothing));
} |
aturon commentedDec 20, 2014
With cmp/ops reform, all of the comparison traits allow the types of the two sides to differ. However, the traits provide a default type for the right-hand size that is the same as the left-hand side. Thus, an impl like:
is more limited than it needs to be; it could instead be
(Of course, you could imagine being even more general than that, allowing Rc values to be compared to other values.)
The various impls in the standard library should probably be generalized along these lines; currently a few are but most aren't.