Skip to content

take_while_inclusive: tighten FusedIterator to require I: FusedIterator#1101

Open
c-tonneslan wants to merge 1 commit into
rust-itertools:masterfrom
c-tonneslan:fix/take-while-inclusive-fused
Open

take_while_inclusive: tighten FusedIterator to require I: FusedIterator#1101
c-tonneslan wants to merge 1 commit into
rust-itertools:masterfrom
c-tonneslan:fix/take-while-inclusive-fused

Conversation

@c-tonneslan
Copy link
Copy Markdown

Closes #1088.

TakeWhileInclusive currently unconditionally implements FusedIterator, but its next() keeps calling the inner iterator after that inner iterator returned None (it only sets done when the predicate fails, not when the source runs dry). So if you wrap a non-fused iterator and then .fuse() the result, Fuse trusts the marker, short-circuits to None on its first observed None, and the underlying iterator's subsequent Some is dropped. The other direction is just as broken: without .fuse(), the marker is a lie since Some can follow None.

std::iter::TakeWhile already does the right thing here, only implementing FusedIterator when the underlying iterator is fused. Doing the same for TakeWhileInclusive keeps the marker honest without changing the runtime behavior for any caller whose source iterator was already fused.

The current impl marks TakeWhileInclusive as FusedIterator regardless
of the underlying iterator, so wrapping a non-fused iterator and then
calling .fuse() is unsound: TakeWhileInclusive forwards next() to the
inner iterator after it returns None once, and the .fuse() layer takes
the FusedIterator marker at face value and short-circuits to None.
Calling next() a second time can then yield Some after the first None,
breaking the FusedIterator contract.

Mirror std::iter::TakeWhile and only implement FusedIterator when the
inner iterator is fused.

Closes rust-itertools#1088

Signed-off-by: Charlie Tonneslan <cst0520@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect FusedIterator implementation on TakeWhileInclusive

1 participant