diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 42886e90f997d..3f0cf04648bbc 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -4,6 +4,7 @@ use super::super::{ Product, Rev, Scan, Skip, SkipWhile, StepBy, Sum, Take, TakeWhile, TrustedRandomAccessNoCoerce, Zip, try_process, }; +use super::TrustedLen; use crate::array; use crate::cmp::{self, Ordering}; use crate::num::NonZero; @@ -3762,7 +3763,7 @@ pub trait Iterator { } } - match iter_compare(self, other.into_iter(), compare(eq)) { + match SpecIterCompare::spec_iter_compare(self, other.into_iter(), compare(eq)) { ControlFlow::Continue(ord) => ord == Ordering::Equal, ControlFlow::Break(()) => false, } @@ -3984,6 +3985,41 @@ pub trait Iterator { } } +trait SpecIterCompare: Iterator { + fn spec_iter_compare(self, b: B, f: F) -> ControlFlow + where + F: FnMut(Self::Item, B::Item) -> ControlFlow; +} + +impl SpecIterCompare for A { + #[inline] + default fn spec_iter_compare(self, b: B, f: F) -> ControlFlow + where + F: FnMut(A::Item, ::Item) -> ControlFlow, + { + iter_compare(self, b, f) + } +} + +impl SpecIterCompare for A { + #[inline] + fn spec_iter_compare(self, b: B, f: F) -> ControlFlow + where + F: FnMut(Self::Item, ::Item) -> ControlFlow, + { + if let (_, Some(a)) = self.size_hint() + && let (_, Some(b)) = b.size_hint() + { + let ord = a.cmp(&b); + if ord != Ordering::Equal { + return ControlFlow::Continue(ord); + } + } + + iter_compare(self, b, f) + } +} + /// Compares two iterators element-wise using the given function. /// /// If `ControlFlow::Continue(())` is returned from the function, the comparison moves on to the next