Chain iterator adaptor shold drop exhausted subiterator #66031
Open
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