In Rust 1.3.0, the Deref
trait has the following signature in the documentation:
pub trait Deref {
type Target: ?Sized;
fn deref(&'a self) -> &'a Self::Target;
}
I would implement it without naming the lifetimes, since they get elided anyway. However, in the docs example it looks like this:
use std::ops::Deref;
struct DerefExample<T> {
value: T
}
impl<T> Deref for DerefExample<T> {
type Target = T;
fn deref<'a>(&'a self) -> &'a T {
&self.value
}
}
fn main() {
let x = DerefExample { value: 'a' };
assert_eq!('a', *x);
}
This works all well and good, but if I specify the lifetime parameter 'a
on the impl instead of the method:
struct DerefExample<T> {
value: T
}
impl<'a, T> Deref for DerefExample<T> {
type Target = T;
fn deref(&'a self) -> &'a T {
&self.value
}
}
I get the following error:
error[E0308]: method not compatible with trait
--> src/main.rs:10:5
|
10 | / fn deref(&'a self) -> &'a T {
11 | | &self.value
12 | | }
| |_____^ lifetime mismatch
|
= note: expected type `fn(&DerefExample<T>) -> &T`
found type `fn(&'a DerefExample<T>) -> &'a T`
note: the anonymous lifetime #1 defined on the method body at 10:5...
--> src/main.rs:10:5
|
10 | / fn deref(&'a self) -> &'a T {
11 | | &self.value
12 | | }
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 7:1
--> src/main.rs:7:1
|
7 | / impl<'a, T> Deref for DerefExample<T> {
8 | | type Target = T;
9 | |
10 | | fn deref(&'a self) -> &'a T {
11 | | &self.value
12 | | }
13 | | }
| |_^
This confuses me. The method's signature is no different than the one from the docs. In addition, I thought that the difference between specifying the lifetime parameter on the impl or on the method directly is in the scope of the parameter only, so it can be used in the entire impl block instead of just the method. What am I missing here?