Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Borrow and internal IntoIterator

I though I got smart with lifetimes, but the compiler teaches me again…

error[E0521]: borrowed data escapes outside of method

play

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


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.

>Solution :

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())
    }
}

(Playground)

Note that the anonymous lifetime is just syntactic sugar for this:

fn do_something_with_items<'a>(&'a self) -> impl Iterator<Item = u8> + 'a
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading