On this example
use std::marker::PhantomData;
pub struct A<'a, T> {
    elements: Vec<B<'a, T>>
}
pub struct B<'a, T> {
    _phantom: PhantomData<&'a T>
}
impl<'a, T> A<'a, T> {
    pub fn iter(& self) -> Iter<'a, T> {
        Iter {
            iter: self.elements.iter(),
        }
    }
}
pub struct Iter<'a, T> {
    iter: std::slice::Iter<'a, B<'a, T>>,
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e246ef19b9ae5f1d405bde7c59d456d7
I get
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/lib.rs:14:24
   |
14 |             iter: self.elements.iter(),
   |                                 ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
  --> src/lib.rs:12:17
//...
I know why this happens: the elements in self.elements lives as long as &self, so it cannot possibly create an Iter with lifetime a. The easy solution would be to do
pub fn iter(&'a self) -> Iter<'a, T> {
    Iter {
        iter: self.elements.iter(),
    }
}
but then I'm forced to borrow the &self for its entire existence which leads me to other problems. Whatis the easiest solution here?
Your Iter implementation is over-constrained; you have two unrelated lifetimes that are required to be the same. You should separate them:
impl<'a, T> A<'a, T> {
    pub fn iter(&self) -> Iter<'a, '_, T> {
        Iter {
            iter: self.elements.iter(),
        }
    }
}
pub struct Iter<'a, 'b, T> {
    iter: std::slice::Iter<'b, B<'a, T>>,
}
That way, even if 'a is invariant, you don't run into issues with linking that lifetime to self. See it working on the playground (with additional tests).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With