+ Self: Iterator + TrustedRandomAccessNoCoerce;
+}
+
+// Work around limitations of specialization, requiring `default` impls to be repeated
+// in intermediary impls.
+macro_rules! zip_impl_general_defaults {
+ () => {
+ default fn new(a: A, b: B) -> Self {
+ Zip {
+ a,
+ b,
+ index: 0, // unused
+ len: 0, // unused
+ a_len: 0, // unused
+ }
+ }
+
+ #[inline]
+ default fn next(&mut self) -> Option<(A::Item, B::Item)> {
+ let x = self.a.next()?;
+ let y = self.b.next()?;
+ Some((x, y))
+ }
+
+ #[inline]
+ default fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.super_nth(n)
+ }
+
+ #[inline]
+ default fn next_back(&mut self) -> Option<(A::Item, B::Item)>
+ where
+ A: DoubleEndedIterator + ExactSizeIterator,
+ B: DoubleEndedIterator + ExactSizeIterator,
+ {
+ // The function body below only uses `self.a/b.len()` and `self.a/b.next_back()`
+ // and doesn’t call `next_back` too often, so this implementation is safe in
+ // the `TrustedRandomAccessNoCoerce` specialization
+
+ let a_sz = self.a.len();
+ let b_sz = self.b.len();
+ if a_sz != b_sz {
+ // Adjust a, b to equal length
+ if a_sz > b_sz {
+ for _ in 0..a_sz - b_sz {
+ self.a.next_back();
+ }
+ } else {
+ for _ in 0..b_sz - a_sz {
+ self.b.next_back();
+ }
+ }
+ }
+ match (self.a.next_back(), self.b.next_back()) {
+ (Some(x), Some(y)) => Some((x, y)),
+ (None, None) => None,
+ _ => unreachable!(),
+ }
+ }
+ };