about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2017-05-21 05:03:49 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2017-05-21 05:03:49 -0700
commit7eaca60f3b3b783ffa1e80ccf91e820f9436b3a3 (patch)
tree5fd4eb1b9d221dea54890af1cfd75a547bace52d
parentf166bd9857dac3c66e812ba6bc33e59494c3fef2 (diff)
Return a correct size_hint for degenerate inclusive ranges
Fixes https://github.com/rust-lang/rust/issues/42135

Found while fixing run-pass/range_inclusive test failure.
-rw-r--r--src/libcore/iter/range.rs4
-rw-r--r--src/libcore/tests/ops.rs5
-rw-r--r--src/test/run-pass/range_inclusive.rs14
3 files changed, 16 insertions, 7 deletions
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index a6fde7e5d6d..02d38ccea44 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -575,6 +575,10 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
+        if !(self.start <= self.end) {
+            return (0, Some(0));
+        }
+
         match Step::steps_between_by_one(&self.start, &self.end) {
             Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
             None => (0, None),
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 50aed15896c..b81b3878c9d 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -62,4 +62,9 @@ fn test_range_inclusive() {
     r = RangeInclusive { start: -128i8, end: -128 };
     assert_eq!(r.next_back(), Some(-128));
     assert_eq!(r.next_back(), None);
+
+    // degenerate
+    r = RangeInclusive { start: 1, end: -1 };
+    assert_eq!(r.size_hint(), (0, Some(0)));
+    assert_eq!(r.next(), None);
 }
\ No newline at end of file
diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs
index cfa9f6e36e9..372d4a8b732 100644
--- a/src/test/run-pass/range_inclusive.rs
+++ b/src/test/run-pass/range_inclusive.rs
@@ -82,7 +82,7 @@ pub fn main() {
     short.next();
     assert_eq!(long.size_hint(), (255, Some(255)));
     assert_eq!(short.size_hint(), (0, Some(0)));
-    assert_eq!(short, RangeInclusive::Empty { at: 42 });
+    assert_eq!(short, 1...0);
 
     assert_eq!(long.len(), 255);
     assert_eq!(short.len(), 0);
@@ -97,28 +97,28 @@ pub fn main() {
     for i in 3...251 {
         assert_eq!(long.next(), Some(i));
     }
-    assert_eq!(long, RangeInclusive::Empty { at: 251 });
+    assert_eq!(long, 1...0);
 
     // check underflow
     let mut narrow = 1...0;
     assert_eq!(narrow.next_back(), None);
-    assert_eq!(narrow, RangeInclusive::Empty { at: 0 });
+    assert_eq!(narrow, 1...0);
     let mut zero = 0u8...0;
     assert_eq!(zero.next_back(), Some(0));
     assert_eq!(zero.next_back(), None);
-    assert_eq!(zero, RangeInclusive::Empty { at: 0 });
+    assert_eq!(zero, 1...0);
     let mut high = 255u8...255;
     assert_eq!(high.next_back(), Some(255));
     assert_eq!(high.next_back(), None);
-    assert_eq!(high, RangeInclusive::Empty { at: 255 });
+    assert_eq!(high, 1...0);
 
     // what happens if you have a nonsense range?
     let mut nonsense = 10...5;
     assert_eq!(nonsense.next(), None);
-    assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });
+    assert_eq!(nonsense, 10...5);
 
     // output
     assert_eq!(format!("{:?}", 0...10), "0...10");
     assert_eq!(format!("{:?}", ...10), "...10");
-    assert_eq!(format!("{:?}", long), "[empty range @ 251]");
+    assert_eq!(format!("{:?}", long), "1...0");
 }