Echo
Echo

Reputation: 319

Unexpected closed channel in sync::mpsc after rx moved

I'm learning the rust lifetime model. But when using mpsc::channel, the rx is always broken.

My questions:

The codes:

use tokio::sync::mpsc::channel;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let (tx, mut rx) = channel::<f32>(1024);

    build_rx(move || {
        let a = rx.recv();
    });

    // The tx is closed.
    if tx.is_closed() {
        panic!("channel broken.");
    }

    Ok(())
}

fn build_rx<T>(callback: T)
where
    T: FnMut() + Send + 'static,
{
}

playground

gives:

 Compiling playground v0.0.1 (/playground)
warning: unused variable: `a`
 --> src/main.rs:8:13
  |
8 |         let a = rx.recv();
  |             ^ help: if this is intentional, prefix it with an underscore: `_a`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `callback`
  --> src/main.rs:18:16
   |
18 | fn build_rx<T>(callback: T)
   |                ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_callback`

warning: `playground` (bin "playground") generated 2 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 1.61s
     Running `target/debug/playground`
thread 'main' panicked at 'channel broken.', src/main.rs:12:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Upvotes: 0

Views: 279

Answers (1)

Jmb
Jmb

Reputation: 23339

You move rx into a closure, then you move that closure into build_rx. When build_rx returns, it drops the closure since you didn't store it anywhere, which causes the rx inside the closure to be dropped too.

Upvotes: 2

Related Questions