-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Closed
Labels
A-iteratorsArea: IteratorsArea: IteratorsC-bugCategory: This is a bug.Category: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Description
I would expect the following code to either not compile (because iter shouldn't implement FusedIterator) or to not panic (because it does, so its contract should guarantee that calling next after the first None will always return None), however it compiles and panics:
use core::iter::FusedIterator;
fn check_is_fused<T, I: Iterator<Item = T> + FusedIterator>(mut i: I) {
while let Some(_) = i.next() {}
assert!(i.next().is_none());
}
struct NonFusedIter(bool);
impl Iterator for NonFusedIter {
type Item = ();
fn next(&mut self) -> Option<Self::Item> {
self.0 = !self.0;
Some(()).filter(|_| !self.0)
}
}
impl DoubleEndedIterator for NonFusedIter {
fn next_back(&mut self) -> Option<Self::Item> {
self.0 = !self.0;
Some(()).filter(|_| !self.0)
}
}
fn main() {
let mut iter = vec![NonFusedIter(true)].into_iter().flatten();
iter.next_back();
check_is_fused(iter);
}This is caused by the fact that the impl of FusedIterator for Flatten only requires the outer iterator to implement FusedIterator, not the inner one, however the implementation doesn't actually fuse backiter, which is what causes the assert to fail. The same problem is present for FlatMap.
Possible solutions:
- Change how
FlattenCompatis implemented to guarantee it to be fused even if the inner iterators are not fused. This would silently change its behavior, however it wouldn't be a breaking change. - Change the bounds for those impls. This would be a (minor?) breaking change.
Additionally I don't think there's anything that requires the outer iterator to always be manually fused in FlattenCompat. Should we also change it in the process?
Metadata
Metadata
Assignees
Labels
A-iteratorsArea: IteratorsArea: IteratorsC-bugCategory: This is a bug.Category: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.