Skip to content

Commit 101a146

Browse files
committed
Fix rust-lang#85462 by adding a marker flag
This will not affect ABI since the other variant of the enum is bigger. It may break some code, but that would be very strange: usually people don't continue after the first `Done` (or `None` for a normal iterator).
1 parent 4581c4e commit 101a146

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

library/core/src/str/pattern.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,8 @@ struct EmptyNeedle {
928928
end: usize,
929929
is_match_fw: bool,
930930
is_match_bw: bool,
931+
// Needed in case of an empty haystack, see #85462
932+
is_finished: bool,
931933
}
932934

933935
impl<'a, 'b> StrSearcher<'a, 'b> {
@@ -941,6 +943,7 @@ impl<'a, 'b> StrSearcher<'a, 'b> {
941943
end: haystack.len(),
942944
is_match_fw: true,
943945
is_match_bw: true,
946+
is_finished: false,
944947
}),
945948
}
946949
} else {
@@ -966,13 +969,19 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> {
966969
fn next(&mut self) -> SearchStep {
967970
match self.searcher {
968971
StrSearcherImpl::Empty(ref mut searcher) => {
972+
if searcher.is_finished {
973+
return SearchStep::Done;
974+
}
969975
// empty needle rejects every char and matches every empty string between them
970976
let is_match = searcher.is_match_fw;
971977
searcher.is_match_fw = !searcher.is_match_fw;
972978
let pos = searcher.position;
973979
match self.haystack[pos..].chars().next() {
974980
_ if is_match => SearchStep::Match(pos, pos),
975-
None => SearchStep::Done,
981+
None => {
982+
searcher.is_finished = true;
983+
SearchStep::Done
984+
}
976985
Some(ch) => {
977986
searcher.position += ch.len_utf8();
978987
SearchStep::Reject(pos, searcher.position)
@@ -1045,12 +1054,18 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> {
10451054
fn next_back(&mut self) -> SearchStep {
10461055
match self.searcher {
10471056
StrSearcherImpl::Empty(ref mut searcher) => {
1057+
if searcher.is_finished {
1058+
return SearchStep::Done;
1059+
}
10481060
let is_match = searcher.is_match_bw;
10491061
searcher.is_match_bw = !searcher.is_match_bw;
10501062
let end = searcher.end;
10511063
match self.haystack[..end].chars().next_back() {
10521064
_ if is_match => SearchStep::Match(end, end),
1053-
None => SearchStep::Done,
1065+
None => {
1066+
searcher.is_finished = true;
1067+
SearchStep::Done
1068+
}
10541069
Some(ch) => {
10551070
searcher.end -= ch.len_utf8();
10561071
SearchStep::Reject(searcher.end, end)

0 commit comments

Comments
 (0)