From 20d8478864333b2633509c530b66d52ffef91fbb Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
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<I, B, F, G>(
-    mut iter: Peekable<I>,
+    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::<String>();
+    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 <m-ou.se@m-ou.se>
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<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]