Lending iterator lending out subslices

I have the following lending iterator code

trait LendingIterator {
  type Item<'this> where Self: 'this;
  fn next(&mut self) -> Option<Self::Item<'_>>;
}

struct Foo<'a>(&'a mut [u8]);

impl<'a> LendingIterator for Foo<'a>  
where
  Self: 'a
{
  type Item<'this> = &'this mut [u8] where Self: 'this;

  fn next(&mut self) -> Option<Self::Item<'_>> {
    let (first, rest) = self.0.split_at_mut(3);
    self.0 = rest;
    Some(first)
  }
}

I get a lifetime error saying that the lifetime of &mut self must outlive 'a, when I think the lifetimes need to be the other way round ('a should outlive '_). Can anyone explain what's going on here?

EDIT playground link

After some poking around, it turned out that the error had nothing to do with returning the slice, and so I suspected that the problem is that self.0 is being taken as a reborrow from self, meaning that you can't store it back into self.0 because it doesn't live for 'a. Change the split_at_mut line to explicitly remove the reference from self and it compiles:

    let (first, rest) = std::mem::take(&mut self.0).split_at_mut(3);

I believe you would have had the same problem even without the LendingIterator trait being involved, as long as you tried to put this logic in a &mut self method.

2 Likes

Yep this worked! You're amazing, thankyou :slight_smile:

Even better: I could do what I wanted just using a normal iterator.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.