I though I got smart with lifetimes, but the compiler teaches me again...
error[E0521]: borrowed data escapes outside of method
pub struct Bugger<S> {
pub items: S,
}
impl<S> Bugger<S>
where
&'static S: IntoIterator + 'static,
<&'static S as IntoIterator>::Item: AsRef<u8>,
{
fn do_something_with_items(&self) -> impl Iterator<Item = u8> {
(&self.items).into_iter().map(|b| *b.as_ref())
}
}
I want to accept a generic member that implements the IntoIterator on it's reference and then use it in another method, actually a trait impl, but even this fails.
The primary reason this fails to compile is because you take &self
(which must be valid for any lifetime) but the bound on the implementation block requires IntoIterator
to be implemented for a reference with 'static
lifetime. The way you use this bound in the method therefore requires that the &self
reference also be 'static
, but you've not indicated this. You can fix this specific example by having the method take &'static self
.
However, this is likely not what you want anyway. Most likely, you want a lifetime shorter than 'static
. You can describe this in the trait bound with a higher-rank trait bound (HRTB).
You also need to indicate in the return type that the returned iterator borrows from self
, which you can do by adding the anonymous lifetime '_
to the bound.
pub struct Bugger<S> {
pub items: S,
}
impl<S> Bugger<S>
where
for<'a> &'a S: IntoIterator,
for<'a> <&'a S as IntoIterator>::Item: AsRef<u8>,
{
fn do_something_with_items(&self) -> impl Iterator<Item = u8> + '_ {
(&self.items).into_iter().map(|b| *b.as_ref())
}
}
Note that the anonymous lifetime is just syntactic sugar for this:
fn do_something_with_items<'a>(&'a self) -> impl Iterator<Item = u8> + 'a