diff options
| author | bors <bors@rust-lang.org> | 2021-01-21 21:05:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-01-21 21:05:34 +0000 |
| commit | 202720bf483088dbdb343f78c0aa77067fdd8156 (patch) | |
| tree | 27c9c1236708dad1a5987b1f8bb25fef47c98c4b | |
| parent | 65767e56537e20903b54ecde7c371cbfb1b201b0 (diff) | |
| parent | 9272d53c5a73198436f429a1a70e5d60afa995a7 (diff) | |
| download | rust-202720bf483088dbdb343f78c0aa77067fdd8156.tar.gz rust-202720bf483088dbdb343f78c0aa77067fdd8156.zip | |
Auto merge of #81152 - lzutao:intersperse_fold, r=m-ou-se
Fix intersperse_fold Here is a standalone playground link in case anybody wants to modify code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=626b4d044fb74f044a36098ad907e40f Fixes #81145 cc #79479 `@jonas-schievink`
| -rw-r--r-- | library/core/src/iter/adapters/intersperse.rs | 7 | ||||
| -rw-r--r-- | library/core/tests/iter.rs | 41 |
2 files changed, 45 insertions, 3 deletions
diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index 1d01e9b5fb7..b1170f32ba1 100644 --- a/library/core/src/iter/adapters/intersperse.rs +++ b/library/core/src/iter/adapters/intersperse.rs @@ -160,7 +160,7 @@ where } fn intersperse_fold<I, B, F, G>( - mut iter: Peekable<I>, + mut iter: I, init: B, mut f: F, mut separator: G, @@ -173,10 +173,11 @@ where { let mut accum = init; - // Use `peek()` first to avoid calling `next()` on an empty iterator. - if !needs_sep || iter.peek().is_some() { + if !needs_sep { if let Some(x) = iter.next() { accum = f(accum, x); + } else { + return accum; } } diff --git a/library/core/tests/iter.rs b/library/core/tests/iter.rs index bc5421bfb5f..78b4d1acaf5 100644 --- a/library/core/tests/iter.rs +++ b/library/core/tests/iter.rs @@ -3563,6 +3563,47 @@ fn test_intersperse_size_hint() { } #[test] +fn test_intersperse_fold() { + let v = (1..4).intersperse(9).fold(Vec::new(), |mut acc, x| { + acc.push(x); + acc + }); + assert_eq!(v.as_slice(), [1, 9, 2, 9, 3]); + + let mut iter = (1..4).intersperse(9); + assert_eq!(iter.next(), Some(1)); + let v = iter.fold(Vec::new(), |mut acc, x| { + acc.push(x); + acc + }); + assert_eq!(v.as_slice(), [9, 2, 9, 3]); + + struct NoneAtStart(i32); // Produces: None, Some(2), Some(3), None, ... + impl Iterator for NoneAtStart { + type Item = i32; + fn next(&mut self) -> Option<i32> { + self.0 += 1; + Some(self.0).filter(|i| i % 3 != 1) + } + } + + let v = NoneAtStart(0).intersperse(1000).fold(0, |a, b| a + b); + assert_eq!(v, 0); +} + +#[test] +fn test_intersperse_collect_string() { + let contents = vec![1, 2, 3]; + + let contents_string = contents + .into_iter() + .map(|id| id.to_string()) + .intersperse(", ".to_owned()) + .collect::<String>(); + assert_eq!(contents_string, "1, 2, 3"); +} + +#[test] fn test_fold_specialization_intersperse() { let mut iter = (1..2).intersperse(0); iter.clone().for_each(|x| assert_eq!(Some(x), iter.next())); |
