about summary refs log tree commit diff
path: root/src/libcore/tests
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2020-04-21 14:56:59 -0700
committerJosh Stone <jistone@redhat.com>2020-04-21 14:56:59 -0700
commiteeb687f20e86f2e2cf61ef89139c102cb92abfcb (patch)
treee2a60e667c3e5f0633089e719552f5628f8c1f45 /src/libcore/tests
parent45d050cde277b22a755847338f2acc2c7b834141 (diff)
downloadrust-eeb687f20e86f2e2cf61ef89139c102cb92abfcb.tar.gz
rust-eeb687f20e86f2e2cf61ef89139c102cb92abfcb.zip
Don't fuse Chain in its second iterator
Only the "first" iterator is actually set `None` when exhausted,
depending on whether you iterate forward or backward. This restores
behavior similar to the former `ChainState`, where it would transition
from `Both` to `Front`/`Back` and only continue from that side.

However, if you mix directions, then this may still set both sides to
`None`, totally fusing the iterator.
Diffstat (limited to 'src/libcore/tests')
-rw-r--r--src/libcore/tests/iter.rs64
-rw-r--r--src/libcore/tests/lib.rs1
2 files changed, 40 insertions, 25 deletions
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 1a1dbcd7b87..7da02b11676 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -207,51 +207,65 @@ fn test_iterator_chain_find() {
     assert_eq!(iter.next(), None);
 }
 
-#[test]
-fn test_iterator_chain_size_hint() {
-    struct Iter {
-        is_empty: bool,
-    }
+struct Toggle {
+    is_empty: bool,
+}
 
-    impl Iterator for Iter {
-        type Item = ();
+impl Iterator for Toggle {
+    type Item = ();
 
-        // alternates between `None` and `Some(())`
-        fn next(&mut self) -> Option<Self::Item> {
-            if self.is_empty {
-                self.is_empty = false;
-                None
-            } else {
-                self.is_empty = true;
-                Some(())
-            }
+    // alternates between `None` and `Some(())`
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.is_empty {
+            self.is_empty = false;
+            None
+        } else {
+            self.is_empty = true;
+            Some(())
         }
+    }
 
-        fn size_hint(&self) -> (usize, Option<usize>) {
-            if self.is_empty { (0, Some(0)) } else { (1, Some(1)) }
-        }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if self.is_empty { (0, Some(0)) } else { (1, Some(1)) }
     }
+}
 
-    impl DoubleEndedIterator for Iter {
-        fn next_back(&mut self) -> Option<Self::Item> {
-            self.next()
-        }
+impl DoubleEndedIterator for Toggle {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.next()
     }
+}
 
+#[test]
+fn test_iterator_chain_size_hint() {
     // this chains an iterator of length 0 with an iterator of length 1,
     // so after calling `.next()` once, the iterator is empty and the
     // state is `ChainState::Back`. `.size_hint()` should now disregard
     // the size hint of the left iterator
-    let mut iter = Iter { is_empty: true }.chain(once(()));
+    let mut iter = Toggle { is_empty: true }.chain(once(()));
     assert_eq!(iter.next(), Some(()));
     assert_eq!(iter.size_hint(), (0, Some(0)));
 
-    let mut iter = once(()).chain(Iter { is_empty: true });
+    let mut iter = once(()).chain(Toggle { is_empty: true });
     assert_eq!(iter.next_back(), Some(()));
     assert_eq!(iter.size_hint(), (0, Some(0)));
 }
 
 #[test]
+fn test_iterator_chain_unfused() {
+    // Chain shouldn't be fused in its second iterator, depending on direction
+    let mut iter = NonFused::new(empty()).chain(Toggle { is_empty: true });
+    iter.next().unwrap_none();
+    iter.next().unwrap();
+    iter.next().unwrap_none();
+
+    let mut iter = Toggle { is_empty: true }.chain(NonFused::new(empty()));
+    iter.next_back().unwrap_none();
+    iter.next_back().unwrap();
+    iter.next_back().unwrap_none();
+}
+
+#[test]
 fn test_zip_nth() {
     let xs = [0, 1, 2, 4, 5];
     let ys = [10, 11, 12];
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 05f958cbe81..e7d36d327cd 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -42,6 +42,7 @@
 #![feature(unwrap_infallible)]
 #![feature(leading_trailing_ones)]
 #![feature(const_forget)]
+#![feature(option_unwrap_none)]
 
 extern crate test;