Closed
Description
I tried this code:
let mut iter = "A..B..".split_terminator('.');
dbg!(&iter); // finished: false (expected)
iter.by_ref().for_each(drop);
dbg!(&iter); // finished: false (unexpected)
dbg!(iter.next());
dbg!(&iter); // finished: false (unexpected)
output
[src/main.rs:3] &iter = SplitTerminator(
SplitInternal {
start: 0,
end: 6,
matcher: CharSearcher {
haystack: "A..B..",
finger: 0,
finger_back: 6,
needle: '.',
utf8_size: 1,
utf8_encoded: [
46,
0,
0,
0,
],
},
allow_trailing_empty: false,
finished: false,
},
)
[src/main.rs:6] &iter = SplitTerminator(
SplitInternal {
start: 6,
end: 6,
matcher: CharSearcher {
haystack: "A..B..",
finger: 6,
finger_back: 6,
needle: '.',
utf8_size: 1,
utf8_encoded: [
46,
0,
0,
0,
],
},
allow_trailing_empty: false,
finished: false,
},
)
[src/main.rs:8] iter.next() = None
[src/main.rs:9] &iter = SplitTerminator(
SplitInternal {
start: 6,
end: 6,
matcher: CharSearcher {
haystack: "A..B..",
finger: 6,
finger_back: 6,
needle: '.',
utf8_size: 1,
utf8_encoded: [
46,
0,
0,
0,
],
},
allow_trailing_empty: false,
finished: false,
},
)
I've expected the finished
flag to be set when the iterator is exhausted, however it isn't.
Meta
Tested on playground's stable 1.51.0
and nightly 1.54.0-nightly (2021-05-05 bacf770f2983a52f31e3)
Likely cause
It seems this behaviour is caused by allow_trailing_empty: false
: SplitInternal
only sets the finished flag if allow_trailing_empty: true
or there is something to return.
Should the flag be set unconditionally? Maybe like this?
if !self.finished {
self.finished = true;
if self.allow_trailing_empty || self.end - self.start > 0 {
return unsafe { ... }
}
}
None