Working with generic types that have lifetimes attached to them (here, trait M<'m>
), trait methods that work with them need to be generic over the input lifetime. I understand that genericity to be at the caller's choice: A function like fn work_with_m<'m>>(self, message: &'m impl M<'m>)
could be read at "for any implementation of M and any lifetime 'm that has, I'm providing a function that …".
In the following code (playground link], when WrappingH
implements the trait H
, it seems the compiler is trying to work on the child with the same implementation lifetime 'im
(which can't be satisfied, as it's using a local object) – but why does the compiler go that way rather than picking a shorter (one-line) lifetime to work with, during which both the type and the borrow exist?
trait M<'m> {}
struct WrappingM<'m, Inner: M<'m>>(&'m Inner);
impl<'m, I: M<'m>> M<'m> for WrappingM<'m, I> {}
trait H {
fn work_with_m<'m>(&self, message: &'m impl M<'m>);
}
struct WrappingH<C: H> {
child: C,
}
impl<C: H> H for WrappingH<C> {
fn work_with_m<'im>(&self, message: &'im impl M<'im>) {
let wrapped = WrappingM(message);
// The child implements work_with_m for any lifetime of *my* choosing, how can't that be
// enough? (`wrapped` only lives in here, but that's also some time for which it should be
// implemented).
self.child.work_with_m(&wrapped);
}
}
impl H for () {
fn work_with_m<'m>(&self, _: &'m impl M<'m>) {
unimplemented!();
}
}
fn main() {
let _: WrappingH<()> = unimplemented!();
}
The error it is producing is
error[E0597]: `wrapped` does not live long enough
--> src/lib.rs:21:32
|
16 | fn work_with_m<'im>(&self, message: &'im impl M<'im>) {
| --- lifetime `'im` defined here
...
21 | self.child.work_with_m(&wrapped);
| -----------------------^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `wrapped` is borrowed for `'im`
22 | }
| - `wrapped` dropped here while still borrowed
which only makes sense if it were trying to .work_with_m<'im>()
– but I'm not asking for that, or am I?