In essence, this is the setup I'm working with: (playground link)
trait Lifetime<'a> {
type Item: 'a;
fn take_by_ref(&'a self) -> Self::Item;
}
struct WithLifetime<'a> {
a_ref: &'a ()
}
impl <'a> Lifetime<'a> for WithLifetime<'a> {
type Item = &'a ();
fn take_by_ref(&'a self) -> Self::Item {
self.a_ref
}
}
struct Container<'a, T> {
some_ref: &'a (),
val: T
}
impl <'a, T> Container<'a, T>
where T: Lifetime<'a> + 'a {
fn consume(self) {
self.val.take_by_ref();
}
}
fn main() {
let val = WithLifetime { a_ref: &() };
let container = Container {
some_ref: &(),
val
};
container.consume()
}
Anything I've tried so far has either caused the trait implementation or its usage to cause lifetime errors - this is the current one:
error[E0597]: `self.val` does not live long enough
--> src/main.rs:27:9
|
24 | impl <'a, T> Container<'a, T>
| -- lifetime `'a` defined here
...
27 | self.val.take_by_ref();
| ^^^^^^^^--------------
| |
| borrowed value does not live long enough
| argument requires that `self.val` is borrowed for `'a`
28 | }
| - `self.val` dropped here while still borrowed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
I'm fairly certain that the lifetime on the trait is necessary - it's pretty much analogous to rayon's IntoParallelRefIterator.
I'm assuming the error is due to the lifetime annotation requiring self.val
to live past the function, even though it is dropped at the end of it... I'm just not sure how to express that correctly.
Or maybe what I'm trying to do is simply impossible and I need to redesign everything?
Also, it's probably fairly harmless to use uns*fe here, but... you know... I'd rather not.