diff options
| author | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2015-08-25 03:56:35 +0200 |
|---|---|---|
| committer | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2015-08-25 19:07:24 +0200 |
| commit | 35eb3e8b79c60ec18e724c7a68625d7cdf9300c0 (patch) | |
| tree | cbe9683058388284c4b11e0579c719eef98827b1 /src/libcoretest | |
| parent | 4c996499a1bcf747b12f8290eeff3024e59da529 (diff) | |
| download | rust-35eb3e8b79c60ec18e724c7a68625d7cdf9300c0.tar.gz rust-35eb3e8b79c60ec18e724c7a68625d7cdf9300c0.zip | |
Correct iterator adaptor Chain
The iterator protocol specifies that the iteration ends with the return value `None` from `.next()` (or `.next_back()`) and it is unspecified what further calls return. The chain adaptor must account for this in its DoubleEndedIterator implementation. It uses three states: - Both `a` and `b` are valid - Only the Front iterator (`a`) is valid - Only the Back iterator (`b`) is valid The fourth state (neither iterator is valid) only occurs after Chain has returned None once, so we don't need to store this state. Fixes #26316
Diffstat (limited to 'src/libcoretest')
| -rw-r--r-- | src/libcoretest/iter.rs | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index ea65c118e5e..87e69581c54 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -729,6 +729,26 @@ fn test_double_ended_chain() { assert_eq!(it.next_back().unwrap(), &5); assert_eq!(it.next_back().unwrap(), &7); assert_eq!(it.next_back(), None); + + + // test that .chain() is well behaved with an unfused iterator + struct CrazyIterator(bool); + impl CrazyIterator { fn new() -> CrazyIterator { CrazyIterator(false) } } + impl Iterator for CrazyIterator { + type Item = i32; + fn next(&mut self) -> Option<i32> { + if self.0 { Some(99) } else { self.0 = true; None } + } + } + + impl DoubleEndedIterator for CrazyIterator { + fn next_back(&mut self) -> Option<i32> { + self.next() + } + } + + assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0)); + assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0)); } #[test] |
