Skip to content

Commit 17f79af

Browse files
committed
auto merge of #16728 : bluss/rust/zip-next-back, r=alexcrichton
Use ExactSize::len() and defer to its decisions about overly defensive assertions. Remove the length double-check and simply put a failure case if the Zip finds an uneven end in .next_back(). Fixing this up since I think I wrote this, and it's been known to confuse rusties (PR #15886).
2 parents 8d3390e + d363770 commit 17f79af

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

src/libcore/iter.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,10 @@ pub trait ExactSize<A> : DoubleEndedIterator<A> {
728728
/// Return the exact length of the iterator.
729729
fn len(&self) -> uint {
730730
let (lower, upper) = self.size_hint();
731+
// Note: This assertion is overly defensive, but it checks the invariant
732+
// guaranteed by the trait. If this trait were rust-internal,
733+
// we could use debug_assert!; assert_eq! will check all Rust user
734+
// implementations too.
731735
assert_eq!(upper, Some(lower));
732736
lower
733737
}
@@ -1195,21 +1199,20 @@ impl<A, B, T: ExactSize<A>, U: ExactSize<B>> DoubleEndedIterator<(A, B)>
11951199
for Zip<T, U> {
11961200
#[inline]
11971201
fn next_back(&mut self) -> Option<(A, B)> {
1198-
let (a_sz, a_upper) = self.a.size_hint();
1199-
let (b_sz, b_upper) = self.b.size_hint();
1200-
assert!(a_upper == Some(a_sz));
1201-
assert!(b_upper == Some(b_sz));
1202-
if a_sz < b_sz {
1203-
for _ in range(0, b_sz - a_sz) { self.b.next_back(); }
1204-
} else if a_sz > b_sz {
1205-
for _ in range(0, a_sz - b_sz) { self.a.next_back(); }
1206-
}
1207-
let (a_sz, _) = self.a.size_hint();
1208-
let (b_sz, _) = self.b.size_hint();
1209-
assert!(a_sz == b_sz);
1202+
let a_sz = self.a.len();
1203+
let b_sz = self.b.len();
1204+
if a_sz != b_sz {
1205+
// Adjust a, b to equal length
1206+
if a_sz > b_sz {
1207+
for _ in range(0, a_sz - b_sz) { self.a.next_back(); }
1208+
} else {
1209+
for _ in range(0, b_sz - a_sz) { self.b.next_back(); }
1210+
}
1211+
}
12101212
match (self.a.next_back(), self.b.next_back()) {
12111213
(Some(x), Some(y)) => Some((x, y)),
1212-
_ => None
1214+
(None, None) => None,
1215+
_ => unreachable!(),
12131216
}
12141217
}
12151218
}
@@ -1395,9 +1398,8 @@ impl<A, T: ExactSize<A>> DoubleEndedIterator<(uint, A)> for Enumerate<T> {
13951398
fn next_back(&mut self) -> Option<(uint, A)> {
13961399
match self.iter.next_back() {
13971400
Some(a) => {
1398-
let (lower, upper) = self.iter.size_hint();
1399-
assert!(upper == Some(lower));
1400-
Some((self.count + lower, a))
1401+
let len = self.iter.len();
1402+
Some((self.count + len, a))
14011403
}
14021404
_ => None
14031405
}

0 commit comments

Comments
 (0)