Skip to content

Commit 3c5eb95

Browse files
committed
Rollup merge of rust-lang#22065 - bluss:range-size-hint, r=Gankro
When self.start > self.end, these iterators simply return None, so we adjust the size_hint to just return zero in this case. Certain optimizations can be implemented in and outside libstd if we know we can trust the size_hint for all inputs to for example Range<usize>. This corrects the ExactSizeIterator implementations, which IMO were unsound and incorrect previously, since they allowed a range like (2..1) to return a size_hint of -1us in when debug assertions are turned off.
2 parents fa4732c + 4f61e16 commit 3c5eb95

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

src/libcore/iter.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,13 +2646,7 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
26462646
macro_rules! range_exact_iter_impl {
26472647
($($t:ty)*) => ($(
26482648
#[stable(feature = "rust1", since = "1.0.0")]
2649-
impl ExactSizeIterator for ::ops::Range<$t> {
2650-
#[inline]
2651-
fn len(&self) -> usize {
2652-
debug_assert!(self.end >= self.start);
2653-
(self.end - self.start) as usize
2654-
}
2655-
}
2649+
impl ExactSizeIterator for ::ops::Range<$t> { }
26562650
)*)
26572651
}
26582652

@@ -2673,9 +2667,12 @@ impl<A: Int> Iterator for ::ops::Range<A> {
26732667

26742668
#[inline]
26752669
fn size_hint(&self) -> (usize, Option<usize>) {
2676-
debug_assert!(self.end >= self.start);
2677-
let hint = (self.end - self.start).to_uint();
2678-
(hint.unwrap_or(0), hint)
2670+
if self.start >= self.end {
2671+
(0, Some(0))
2672+
} else {
2673+
let length = (self.end - self.start).to_uint();
2674+
(length.unwrap_or(0), length)
2675+
}
26792676
}
26802677
}
26812678

src/libcoretest/iter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ fn test_range() {
756756
// this test is only meaningful when sizeof uint < sizeof u64
757757
assert_eq!((uint::MAX - 1..uint::MAX).size_hint(), (1, Some(1)));
758758
assert_eq!((-10..-1).size_hint(), (9, Some(9)));
759+
assert_eq!((-1..-10).size_hint(), (0, Some(0)));
759760
}
760761

761762
#[test]

0 commit comments

Comments
 (0)