From 7eaca60f3b3b783ffa1e80ccf91e820f9436b3a3 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 21 May 2017 05:03:49 -0700 Subject: [PATCH] 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. --- src/libcore/iter/range.rs | 4 ++++ src/libcore/tests/ops.rs | 5 +++++ src/test/run-pass/range_inclusive.rs | 14 +++++++------- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index a6fde7e5d6dee..02d38ccea44ea 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -575,6 +575,10 @@ impl Iterator for ops::RangeInclusive where #[inline] fn size_hint(&self) -> (usize, Option) { + 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 50aed15896c75..b81b3878c9d6e 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 cfa9f6e36e9bc..372d4a8b732ac 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"); }