Let’s compare the two definitions. First, the trait method:
fn to_c<'a>(&self, r: &'a Ref) -> Container<'a>;
And the implementation:
fn to_c(&self, r: &'a Ref) -> Container<'a>;
See the difference? The latter doesn’t have <'a>
. <'a>
has been specified elsewhere; the fact that it has the same name does not matter: it is a different thing entirely.
Functionally, your trait definition says that the returned container will have a reference inside it to something from r
, but nothing from self
. It may use self
inside the method, but it may not store any references to it in the returned value.
Your method definition, however, is using a 'a
that ties the lifetimes of r
and the returned Container
to self
(that is, to the object itself, not the reference—the ρ? in &'ρ? T<'ρ?>
—it’s a subtle but sometimes significant difference), whereas the trait definition had no such connection.
The two can be made to match by inserting the <'a>
in the method definition in the implementation. But bear in mind that that is shadowing the 'a
from ContainerB<'a>
; it is not the same 'a
! We’re better to give it another name; for convenience, I’ll make the change the other way round, changing it on the impl instead of the method (either would do):
impl<'b> ToC for ContainerB<'b> {
fn to_c<'a>(&self, r: &'a Ref) -> Container<'a> {
self.c
}
}
But now of course you have a problem: the return value is of type Container<'b>
(because that’s what the field c
in a ContainerB<'b>
is), but your signature demands Container<'a>
(something using a reference from r
, not from self
).
One way which would fix it is specifying the lifetime of &self
as 'a
in both the trait definition and the implementation; in the implementation, this would then demand that 'b
was greater than or equal to 'a
(by virtue of the fact that you have successfully taken a reference with lifetime 'a
to an object with lifetime 'b
, and the object must outlive the reference) and so due to the subtyping ('a
is a subtype of 'b
) Container<'b>
would be safely coerced to Container<'a>
.
These sorts of lifetime matters are difficult to think about when you’re not familiar with them; but in time they become quite natural.