Why is Iterator::find implemented the way it is?

113 points This_Hippo

Looking through std's source, I see that Iterator::find is implemented like so:

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where
    Self: Sized,
    P: FnMut(&Self::Item) -> bool,
{
    #[inline]
    fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
        move |(), x| {
            if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
        }
    }

    self.try_fold((), check(predicate)).break_value()
}

What is the point of making it so seemingly complicated? My first instinct would just e to implement it like the following:

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where
    Self: Sized,
    P: FnMut(&Self::Item) -> bool,
{
    while let Some(x) = self.next() {
        if predicate(&x) {
            return Some(x);
        }
    }

    None
}

But I assume std must have a reason for doing it its way. Does anyone have insight into this?