0

Why do I need to clone tx? I moved it. I cannot use it in my main thread anymore.

use std::sync::mpsc::{channel, Sender};

fn main() {
    let (tx, _rx) = channel();

    std::thread::spawn(move || {
        takes_closure(|| Foo { sender: tx });
    });
}

struct Foo {
    sender: Sender<()>,
}

fn takes_closure(_: impl FnMut() -> Foo) {}

Playground

This has the error:

error[E0507]: cannot move out of captured variable in an `FnMut` closure
 --> src/main.rs:7:40
  |
4 |     let (tx, _rx) = channel();
  |          -- captured outer variable
...
7 |         takes_closure(|| Foo { sender: tx });
  |                                        ^^ cannot move out of captured variable in an `FnMut` closure
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Marco
  • 61
  • 7
  • Don't you need another `move` there? I'm actually not familiar with that syntax, but it looks like it should be `connect(url, move |sender| Client { ...` – Bartek Banachewicz Jul 29 '19 at 10:21
  • If you add a `move` to the closure in the `connect(url, move |sender| ...)` call, do you still need the `clone`? – rodrigo Jul 29 '19 at 10:23
  • 4
    Please provide a [MCVE]. We don't know how `connect` or `Client` is defined. Furthermore, the `url` part is (presumably) not needed to reproduce the error. Without knowing all information, we cannot help you. I tried to reproduce the error (guessing that it has to do with the second closure), but I couldn't. It always worked for me. So please [edit] your question to provide all information. – Lukas Kalbertodt Jul 29 '19 at 11:16
  • 3
    Ok I think I found a minimal example: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e3ee886580739a4c5095942b7d7f9777). Is that the error you are getting? If so, simply [edit] your question to include this minimal example. And next time, please provide a minimal example or at least the exact error message in your question. This error message in particular could have helped answer the question even without reproducible example. – Lukas Kalbertodt Jul 29 '19 at 11:22
  • 1
    I presume the connect function spawns threads when needed. If the connect function calls the closure several times for use in different threads, there's no other solution than cloning the sender as you can't share a sender between threads. The initial move could be avoided using crossbeam's scope but that's a detail. – Denys Séguret Jul 29 '19 at 11:23
  • 1
    @LukasKalbertodt, yes you got it!. I made a little modification (probably useless) to your playground. Thank you. The minimal reproducible example [here](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b4ff97e8e2fbba294a44b1cd042896b7). NB: I will add this to the original question!. – Marco Jul 29 '19 at 17:53
  • It looks like your question might be answered by the answers of [Cannot move out of captured variables in an `FnMut` closure](https://stackoverflow.com/q/53038935/155423) or [How can I move a captured variable into a closure within a closure?](https://stackoverflow.com/q/28521637/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jul 29 '19 at 18:01
  • I encourage you to *search for your error message* in the future. Doing so quickly leads to existing questions that likely solve your problem. – Shepmaster Jul 29 '19 at 18:02
  • Conceptually, what should happen when the closure is called multiple times? What value should `tx` be on the second and every subsequent call? – Shepmaster Jul 29 '19 at 18:05
  • @Shepmaster You can mark this question as Already answered. Denis Séguret made it clear: if I don't clone it, it works only for the first spawned thread. Not for the others... Thank you – Marco Jul 29 '19 at 18:12
  • @Marco Thank you for editing your question and keeping cool despite our critical comments :) Creating a good question on StackOverflow is not trivial and we just want to improve questions, that's why we comment like this. Happy hacking in Rust! – Lukas Kalbertodt Jul 29 '19 at 19:16

0 Answers0