Skip to content

InterleaveShortest<I, J> is not actually fused #533

Open
@nox

Description

@nox

I was looking at the code and it turns out that InterleaveShortest<I, J> will resume iterating after a None if one of its iterators is not fused.

use itertools::Itertools;

fn not_fused() -> impl Iterator<Item = bool> {
    let mut last = Some(true);
    std::iter::from_fn(move || {
        match last {
            Some(b) => {
                last = None;
                Some(b)
            },
            None => {
                last = Some(true);
                None
            }
        }
    })
}

fn demonstrate_that_not_fused_is_indeed_not_fused() {
    let mut not_fused = not_fused();
    assert_eq!(not_fused.next(), Some(true));
    assert_eq!(not_fused.next(), None);
    assert_eq!(not_fused.next(), Some(true));
}

fn main() {
    demonstrate_that_not_fused_is_indeed_not_fused();

    let mut interleave_shortest = std::iter::repeat(false).interleave_shortest(not_fused());
    assert_eq!(interleave_shortest.next(), Some(false));
    assert_eq!(interleave_shortest.next(), Some(true));
    assert_eq!(interleave_shortest.next(), Some(false));
    assert_eq!(interleave_shortest.next(), None);

    // This fails, because `InterleaveShortest<I, J>` is not actually fused.
    assert_eq!(interleave_shortest.next(), None);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions