Auto merge of #100806 - timvermeulen:split_inclusive_double_ended_bound, r=dtolnay

Fix generic bound of `str::SplitInclusive`'s `DoubleEndedIterator` impl

`str::SplitInclusive`'s `DoubleEndedIterator` implementation currently uses a `ReverseSearcher` bound for the corresponding searcher. A `DoubleEndedSearcher` bound should have been used instead.

`DoubleEndedIterator` requires that repeated `next_back` calls produce the same items as repeated `next` calls, in opposite order. `ReverseSearcher` lets you search starting from the back of a string, but it makes no guarantees about how its matches correspond to the matches found by a forward search. `DoubleEndedSearcher` is a subtrait of `ReverseSearcher` and does require that the same matches are found in both directions.

This bug fix is a breaking change. Calling `next_back` on `"a+++b".split_inclusive("++")` is currently accepted with repeated calls producing `"b"` and `"a+++"`, while forward iteration yields `"a++"` and `"+b"`. Also see https://github.com/rust-lang/rust/issues/100756#issuecomment-1221307166 for more details.

I believe that this is the only iterator that uses this bound incorrectly — other related iterators such as `str::Split` do have a `DoubleEndedSearcher` bound for their `DoubleEndedIterator` implementation. And `slice::SplitInclusive` doesn't face this problem at all because it doesn't use patterns, only a predicate.

cc `@SkiFire13`
This commit is contained in:
bors 2023-10-07 17:10:02 +00:00
commit 598e29bf70
1 changed files with 1 additions and 1 deletions

View File

@ -1360,7 +1360,7 @@ impl<'a, P: Pattern<'a, Searcher: Clone>> Clone for SplitInclusive<'a, P> {
}
#[stable(feature = "split_inclusive", since = "1.51.0")]
impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator
impl<'a, P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>> DoubleEndedIterator
for SplitInclusive<'a, P>
{
#[inline]