I'm trying to implement the following trait, where the <'baz>
is required for a later impl<'baz> Baz<'baz> for T where T: OtherTrait
†.
trait Baz<'baz>: Clone {
fn baz(&'baz mut self);
fn bazzed(&self) -> Self {
let mut x = self.clone();
x.baz();
x
}
}
Rustc understandably fails:
Compiling playground v0.0.1 (/playground)
error[E0309]: the parameter type `Self` may not live long enough
--> src/lib.rs:6:9
|
6 | x.baz();
| ^
|
= help: consider adding an explicit lifetime bound `Self: 'baz`...
= note: ...so that the type `Self` is not borrowed for too long
error[E0309]: the parameter type `Self` may not live long enough
--> src/lib.rs:6:11
|
6 | x.baz();
| ^^^
|
= help: consider adding an explicit lifetime bound `Self: 'baz`...
= note: ...so that the reference type `&'baz mut Self` does not outlive the data it points at
For more information about this error, try `rustc --explain E0309`.
error: could not compile `playground` due to 2 previous errors
So I follow its suggestion:
trait Baz<'baz>: Clone {
fn baz(&'baz mut self);
fn bazzed(&self) -> Self
where
Self: 'baz
{
let mut x = self.clone();
x.baz();
x
}
}
And I don't quite understand what it's not liking now...
Compiling playground v0.0.1 (/playground)
error[E0597]: `x` does not live long enough
--> src/lib.rs:9:9
|
1 | trait Baz<'baz>: Clone {
| ---- lifetime `'baz` defined here
...
9 | x.baz();
| ^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `x` is borrowed for `'baz`
10 | x
11 | }
| - `x` dropped here while still borrowed
error[E0505]: cannot move out of `x` because it is borrowed
--> src/lib.rs:10:9
|
1 | trait Baz<'baz>: Clone {
| ---- lifetime `'baz` defined here
...
9 | x.baz();
| -------
| |
| borrow of `x` occurs here
| argument requires that `x` is borrowed for `'baz`
10 | x
| ^ move out of `x` occurs here
Some errors have detailed explanations: E0505, E0597.
For more information about an error, try `rustc --explain E0505`.
error: could not compile `playground` due to 2 previous errors
I tried making Self: 'static
too but that did not help either. What am I missing here?
† The <'baz>
I need for another trait, that looks roughly like:
trait ReturnIteratorMut<'item> {
type IterType: Iterator<Item = &'item mut Thing>;
fn iterator<'slf: 'item>(&'slf mut self) -> Self::IterType;
}
I want to implement Baz
for all of these by applying baz()
to every item in the iterator, so I need 'baz: 'item
. This works fine with just the baz()
method, it's only the bazzed()
that it starts to complain at.