From 20d8478864333b2633509c530b66d52ffef91fbb Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Mon, 18 Jan 2021 03:02:47 +0000 Subject: [PATCH 1/2] Fix intersperse_fold --- library/core/src/iter/adapters/intersperse.rs | 5 ++-- library/core/tests/iter.rs | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index 1d01e9b5fb7dc..2143509d71dc7 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( - mut iter: Peekable, + mut iter: I, init: B, mut f: F, mut separator: G, @@ -173,8 +173,7 @@ 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); } diff --git a/library/core/tests/iter.rs b/library/core/tests/iter.rs index bc5421bfb5f8f..fa259e68a4370 100644 --- a/library/core/tests/iter.rs +++ b/library/core/tests/iter.rs @@ -3562,6 +3562,35 @@ fn test_intersperse_size_hint() { assert_eq!([].iter().intersperse(&()).size_hint(), (0, Some(0))); } +#[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]); +} + +#[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::(); + assert_eq!(contents_string, "1, 2, 3"); +} + #[test] fn test_fold_specialization_intersperse() { let mut iter = (1..2).intersperse(0); From 9272d53c5a73198436f429a1a70e5d60afa995a7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Jan 2021 12:17:58 +0000 Subject: [PATCH 2/2] Stop `fold` at first None when iterator yield --- library/core/src/iter/adapters/intersperse.rs | 2 ++ library/core/tests/iter.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index 2143509d71dc7..b1170f32ba161 100644 --- a/library/core/src/iter/adapters/intersperse.rs +++ b/library/core/src/iter/adapters/intersperse.rs @@ -176,6 +176,8 @@ where 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 fa259e68a4370..78b4d1acaf5cd 100644 --- a/library/core/tests/iter.rs +++ b/library/core/tests/iter.rs @@ -3577,6 +3577,18 @@ fn test_intersperse_fold() { 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 { + 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]