Closed
Description
Here's an example showing this behavior:
struct Input<'a> {
foo: &'a u32
}
impl <'a> std::cmp::PartialEq<Input<'a>> for Input<'a> {
fn eq(&self, other: &Input<'a>) -> bool {
self.foo == other.foo
}
fn ne(&self, other: &Input<'a>) -> bool {
self.foo != other.foo
}
}
// same error if no lifetime parameters are used, but I'm using explicit lifetime parameters to try to show the actual error
fn bar<'a, 'b>(x: Input<'a>, y: Input<'b>) -> bool {
x == y
}
(https://play.rust-lang.org/?gist=c7b5d06f19fd345eef91)
Errors with:
<anon>:17:5: 17:11 error: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
<anon>:17 x == y
^~~~~~
<anon>:16:1: 18:2 help: consider using an explicit lifetime parameter as shown: fn bar<'a>(x: Input<'a>, y: Input<'a>) -> bool
<anon>:16 fn bar(x: Input, y: Input) -> bool {
<anon>:17 x == y
<anon>:18 }
error: aborting due to previous error
Using impl <'a, 'b> std::cmp::PartialEq<Input<'b>> for Input<'a>
works, but it is confusing why the below allows lifetime elision while the above doesn't. I would think it would make sense for the rust compiler to merge the minimum of two lifetimes ('a
and 'b
) automatically when using ==
if PartialEq is only implemented for one shared lifetime.
impl <'a, 'b> std::cmp::PartialEq<Input<'b>> for Input<'a> {
fn eq(&self, other: &Input<'b>) -> bool {
self.foo == other.foo
}
fn ne(&self, other: &Input<'b>) -> bool {
self.foo != other.foo
}
}
Activity
[-]#[derive(PartialEq)] on structs with references kills lifetime elision on functions using ==[/-][+]Implementing PartialEq for a struct with a lifetime parameter using the same lifetime for T stops lifetime elision[/+]eefriedman commentedon Aug 23, 2015
(Ignore this; the comment was completely off-base.)
steveklabnik commentedon Sep 3, 2015
/cc @rust-lang/lang
[-]Implementing PartialEq for a struct with a lifetime parameter using the same lifetime for T stops lifetime elision[/-][+]`==` operator does not support subtyping[/+]nikomatsakis commentedon Sep 4, 2015
I've taken the liberty of renaming the issue to be more precise. The problem is that the
==
operator, as implemented now, performs a precise match on the type of the LHS and RHS, rather than permitting subtyping. This means that the two lifetimes must match exactly. This is why you get an error when your two references have distinct lifetimes. The compiler could fairly probably introduce subtyping; I think it probably should, since the intuition is thata == b
is the same asPartialEq::eq(&a, &b)
, except that if you write the latter, you'll find the program type-checks: http://is.gd/36eVCQsteveklabnik commentedon Mar 1, 2017
Triage: no change
Centril commentedon Feb 18, 2019
The linked playground in the issue compiles fine now; all that is left to do is to add a compile-pass test for it.
8 remaining items