Lifetime bounds in HRTB

I've been reading a blog post (Giving, lending, and async closures) that presented a lending iterator trait that can also be used as a "regular" iterator:

trait LendingIterator {
    type Item<'this>
    where
        Self: 'this;

    fn next(&mut self) -> Option<Self::Item<'_>>;
}

fn take_two_v3<U, T>(t: &mut T) -> Option<(U, U)>
where
    T: for<'a> LendingIterator<Item<'a> = U>,
{
    let Some(i) = t.next() else { return None };
    let Some(j) = t.next() else { return None };
    Some((i, j))
}

I got curious and tried a different approach that didn't work:

fn take_two_v4<T>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)>
where
    T: for<'a> LendingIterator<Item<'a>: 'static>, // <-- added `: 'static`
{
    let Some(i) = t.next() else { return None };
    let Some(j) = t.next() else { return None }; // <-- cannot borrow `*t` as mutable more than once at a time
    Some((i, j))
}

My hope was that : 'static would tell the compiler that Item doesn't hold references to t, but I'm clearly mistaken here.

Could someone please help me understand T: for<'a> LendingIterator<Item<'a>: 'static>: is it a meaningful construct and what it actually means?

1 Like