pub struct IterOverVecVec<'a> {
m: &'a dyn IterTrait,
}
impl<'a> Iterator for IterOverVecVec<'a> {
type Item = u16;
fn next(&mut self) -> Option<Self::Item> {
Some(1)
}
}
impl<'a> IterOverVecVec<'a> {
fn new(m: &'a dyn IterTrait) -> Self {
Self { m }
}
}
pub trait IterTrait {}
impl<'b> dyn IterTrait {
pub fn get_iter<'a>(&'a self) -> IterOverVecVec<'a> {
IterOverVecVec::new(self)
}
}
pub struct HasAVec<'a> {
m: &'a Vec<Vec<u16>>,
}
impl<'a> IterTrait for HasAVec<'a> {}
impl<'a> HasAVec<'a> {
pub fn new(m: &'a Vec<Vec<u16>>) -> Self {
Self { m }
}
}
#[test]
fn fails() {
let vecvec: Vec<Vec<u16>> = vec![vec![1, 2, 3], vec![4, 5, 6]];
let struct_with_vecs = HasAVec::new(&vecvec);
let ni = <dyn IterTrait>::get_iter(&struct_with_vecs);
}
error[E0597]: `vecvec` does not live long enough
--> src/lib.rs:41:41
|
41 | let struct_with_vecs = HasAVec::new(&vecvec);
| ^^^^^^^ borrowed value does not live long enough
42 | let ni = <dyn IterTrait>::get_iter(&struct_with_vecs);
| ----------------- cast requires that `vecvec` is borrowed for `'static`
43 | }
| - `vecvec` dropped here while still borrowed
Link to playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5d7b88a4a261821fabfd0228e8ef8b2c
My understanding of the root cause is: after struct_with_vecs
is cast to the trait type on line 33, the compiler tries to infer it's (new?) lifetime and somehow arrives at 'static
, and since I don't have the correct lifetime annotations, it errors out.
The closest thing to my issue that I found is a Rust forums thread ( https://users.rust-lang.org/t/argument-requires-that-is-borrowed-for-static/66503/2 ) which if I understand correctly, says that in a case like this one, Rust tries to apply the longest possible lifetime. However, I was not able to apply the solution from that question to my problem, since there is seems to me to be caused by closures which I am not using.
So my question goes, how do I make use of IterTrait::get_iter()
without vecvec
getting borrowed for 'static
?
The reason rustc arrives at 'static
is because dyn Trait
is dyn Trait + 'static
. To allow other lifetimes you should use dyn Trait + 'lifetime
, or dyn Trait + '_
with the elided lifetime.
If you replace
impl dyn IterTrait {
with
impl dyn IterTrait + '_ {
Then it works (playground).