Skip to content

Commit

Permalink
Rollup merge of rust-lang#81152 - lzutao:intersperse_fold, r=m-ou-se
Browse files Browse the repository at this point in the history
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 rust-lang#81145

cc rust-lang#79479 ``@jonas-schievink``
  • Loading branch information
m-ou-se committed Jan 20, 2021
2 parents 443109e + 9272d53 commit f6b3d9d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
7 changes: 4 additions & 3 deletions library/core/src/iter/adapters/intersperse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
}
}

Expand Down
41 changes: 41 additions & 0 deletions library/core/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3562,6 +3562,47 @@ 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]);

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);
Expand Down

0 comments on commit f6b3d9d

Please sign in to comment.