error[E0311]: the parameter type `A` may not live long enough
--> src/main.rs:27:35
|
27 | fn new_container<A>(v: Vec<A>) -> Container<VecValues<A>>
| ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> src/main.rs:22:14
|
22 | where V: for<'a> Values<'a>
| ^^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound...
|
27 | fn new_container<A: 'a>(v: Vec<A>) -> Container<VecValues<A>>
| ++++
I think I understand. I must bound the lifetime. But how do I do that?
This line would mean that V: Values<'static>, since 'static is a valid value for 'a. This is certainly not what you want your trait to do, or what you can implement for a container.
Now you have a visible problem: the lifetime of the returned Self::Item is unrelated to the lifetime of the borrow on &'b self, so you can't return a borrowed value.
What you really want is to return Self::Item, which has the same lifetime as the borrow itself. Since the borrowed lifetime exists only in the fn get() itself, this means that your Self::Item must actually be generic in the lifetime parameter, so that you could write
In the past that's the point where people would tell you "but you can't have generic associated items on stable Rust", but you're in luck, because generic associated types were recently stabilized and will land in Rust 1.65.
With GATs, you can do what you want quite simply:
pub trait Values {
type Item<'a> where Self: 'a;
fn get(&self, index: usize) -> Self::Item<'_>;
}
struct VecValues<A> {
pub values: Vec<A>
}
impl<A> Values for VecValues<A> {
type Item<'a> = &'a A where Self: 'a;
fn get(&self, index: usize) -> Self::Item<'_> {
&self.values[index]
}
}
Just make sure you know of the restrictions of the current GAT implementation.