Skip to content

Chain iterator adaptor shold drop exhausted subiterator #66031

Open
@matklad

Description

Consider the following program:

use std::sync::mpsc::channel;

fn main() {
    let (sender, reciever) = channel();

    let source = (1..10).map(move |i| {sender.send(i).unwrap(); i});
    let sink = reciever;

    let iter = source.chain(sink);
    for x in iter {
        println!("{}", x);
    }

    println!("done");
}

Currently, it deadlocks. It can be argued, however, that this program should finish, given that "equivalent" program without chain finishes:

use std::sync::mpsc::channel;

fn main() {
    let (sender, reciever) = channel();

    let source = (1..10).map(move |i| {sender.send(i).unwrap(); i});
    let sink = reciever;

    for x in source {
        println!("{}", x)
    }
    for x in sink {
        println!("{}", x);
    }

    println!("done");
}

I think this can be achieved by changing the Chain definition from

struct Chain<A, B> {
  left: A,
  right: B,
  state: State,
}

enum State { Left, Right, Both }

to

struct Chain<A, B> {
  state: State<A, B>,
}

enum State<A, B> { Left(A), Right(B), Both(A, B) }

this will require some unsafe code to flip from Both to Left, using only &mut Both, but should be doable.

Context: I've discovered similarly-shaped code when trying to simplify this code. Basically, this is an event loop, which works on the stream of events, and some events can feed new events back into the loop. The goal is to make sure the loop is cleanly exhausted.

Not sure if this actually worth it, given super-obscure use-case and potential complications during implementation...

cc @bluss

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-iteratorsArea: IteratorsC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions