about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthieu M <matthieum.147192@gmail.com>2019-02-09 18:42:34 +0100
committerMatthieu M <matthieum.147192@gmail.com>2019-02-09 18:42:34 +0100
commit4fed67f94220351ffa60de1dca078c02a7c15734 (patch)
tree8acf231c15665348ae59f9a49ca38f8b8362842d
parenteb5b09688696562d08ebb35e34ded723e6e44277 (diff)
downloadrust-4fed67f94220351ffa60de1dca078c02a7c15734.tar.gz
rust-4fed67f94220351ffa60de1dca078c02a7c15734.zip
Fix exhaustion of inclusive range try_fold and try_rfold
-rw-r--r--src/libcore/iter/range.rs14
-rw-r--r--src/libcore/tests/iter.rs24
2 files changed, 33 insertions, 5 deletions
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 52b0ccd48d4..f0ed88c3dfd 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -389,6 +389,10 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
     {
         self.compute_is_empty();
 
+        if self.is_empty() {
+            return Try::from_ok(init);
+        }
+
         let mut accum = init;
 
         while self.start < self.end {
@@ -397,11 +401,12 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
             accum = f(accum, n)?;
         }
 
+        self.is_empty = Some(true);
+
         if self.start == self.end {
             accum = f(accum, self.start.clone())?;
         }
 
-        self.is_empty = Some(true);
         Try::from_ok(accum)
     }
 
@@ -445,6 +450,10 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
     {
         self.compute_is_empty();
 
+        if self.is_empty() {
+            return Try::from_ok(init);
+        }
+
         let mut accum = init;
 
         while self.start < self.end {
@@ -453,11 +462,12 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
             accum = f(accum, n)?;
         }
 
+        self.is_empty = Some(true);
+
         if self.start == self.end {
             accum = f(accum, self.start.clone())?;
         }
 
-        self.is_empty = Some(true);
         Try::from_ok(accum)
     }
 }
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index cf19851c17b..89e190e074f 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1738,19 +1738,37 @@ fn test_range_inclusive_folds() {
     assert_eq!((1..=10).sum::<i32>(), 55);
     assert_eq!((1..=10).rev().sum::<i32>(), 55);
 
-    let mut it = 40..=50;
+    let mut it = 44..=50;
     assert_eq!(it.try_fold(0, i8::checked_add), None);
-    assert_eq!(it, 44..=50);
+    assert_eq!(it, 47..=50);
+    assert_eq!(it.try_fold(0, i8::checked_add), None);
+    assert_eq!(it, 50..=50);
+    assert_eq!(it.try_fold(0, i8::checked_add), Some(50));
+    assert!(it.is_empty());
+    assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
+    assert!(it.is_empty());
+
+    let mut it = 40..=47;
+    assert_eq!(it.try_rfold(0, i8::checked_add), None);
+    assert_eq!(it, 40..=44);
     assert_eq!(it.try_rfold(0, i8::checked_add), None);
-    assert_eq!(it, 44..=47);
+    assert_eq!(it, 40..=41);
+    assert_eq!(it.try_rfold(0, i8::checked_add), Some(81));
+    assert!(it.is_empty());
+    assert_eq!(it.try_rfold(0, i8::checked_add), Some(0));
+    assert!(it.is_empty());
 
     let mut it = 10..=20;
     assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(165));
     assert!(it.is_empty());
+    assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(0));
+    assert!(it.is_empty());
 
     let mut it = 10..=20;
     assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(165));
     assert!(it.is_empty());
+    assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(0));
+    assert!(it.is_empty());
 }
 
 #[test]