Skip to content

Commit

Permalink
Rollup merge of rust-lang#89825 - martinvonz:split-inclusive-empty, r…
Browse files Browse the repository at this point in the history
…=m-ou-se

Make split_inclusive() on an empty slice yield an empty output

`[].split_inclusive()` currently yields a single, empty slice. That's
different from `"".split_inslusive()`, which yields no output at
all. I think that makes the slice version harder to use.

The case where I ran into this bug was when writing code for
generating a diff between two slices of bytes. I wanted to prefix
removed lines with "-" and a added lines with "+". Due to
`split_inclusive()`'s current behavior, that means that my code prints
just a "-" or "+" for empty files. I suspect most existing callers
have similar "bugs" (which would be fixed by this patch).

Closes rust-lang#89716.
  • Loading branch information
matthiaskrgr authored Dec 14, 2021
2 parents 404c847 + f6e4c74 commit 50327d2
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 6 deletions.
8 changes: 4 additions & 4 deletions library/alloc/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ fn test_splitator_inclusive() {
assert_eq!(xs.split_inclusive(|_| true).collect::<Vec<&[i32]>>(), splits);

let xs: &[i32] = &[];
let splits: &[&[i32]] = &[&[]];
let splits: &[&[i32]] = &[];
assert_eq!(xs.split_inclusive(|x| *x == 5).collect::<Vec<&[i32]>>(), splits);
}

Expand All @@ -883,7 +883,7 @@ fn test_splitator_inclusive_reverse() {
assert_eq!(xs.split_inclusive(|_| true).rev().collect::<Vec<_>>(), splits);

let xs: &[i32] = &[];
let splits: &[&[i32]] = &[&[]];
let splits: &[&[i32]] = &[];
assert_eq!(xs.split_inclusive(|x| *x == 5).rev().collect::<Vec<_>>(), splits);
}

Expand All @@ -903,7 +903,7 @@ fn test_splitator_mut_inclusive() {
assert_eq!(xs.split_inclusive_mut(|_| true).collect::<Vec<_>>(), splits);

let xs: &mut [i32] = &mut [];
let splits: &[&[i32]] = &[&[]];
let splits: &[&[i32]] = &[];
assert_eq!(xs.split_inclusive_mut(|x| *x == 5).collect::<Vec<_>>(), splits);
}

Expand All @@ -923,7 +923,7 @@ fn test_splitator_mut_inclusive_reverse() {
assert_eq!(xs.split_inclusive_mut(|_| true).rev().collect::<Vec<_>>(), splits);

let xs: &mut [i32] = &mut [];
let splits: &[&[i32]] = &[&[]];
let splits: &[&[i32]] = &[];
assert_eq!(xs.split_inclusive_mut(|x| *x == 5).rev().collect::<Vec<_>>(), splits);
}

Expand Down
6 changes: 4 additions & 2 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,8 @@ where
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
#[inline]
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
let finished = slice.is_empty();
Self { v: slice, pred, finished }
}
}

Expand Down Expand Up @@ -729,7 +730,8 @@ where
impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
#[inline]
pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
let finished = slice.is_empty();
Self { v: slice, pred, finished }
}
}

Expand Down

0 comments on commit 50327d2

Please sign in to comment.