Skip to content

Threads3 solution does not compile #2365

@Jtachan

Description

@Jtachan

I believe the solution for the exercise threads3.rs is incorrect.

So I coded the expected "correct solution" on my own and got a compiler error. After checking with the solved file (and not finding any major difference), I copy-pasted into my code and surprisingly I got the same error.
This is the error print:

error[E0382]: use of moved value: `q`
  --> .\rustlings\threads3.rs:30:19
   |
17 | fn send_tx(q: Queue, tx: mpsc::Sender<u32>) {
   |            - move occurs because `q` has type `Queue`, which does not implement the `Copy` trait
...
20 |     thread::spawn(move || {
   |                   ------- value moved into closure here
21 |         for val in q.first_half {
   |                    ------------ variable moved due to use in closure
...
30 |     thread::spawn(move || {
   |                   ^^^^^^^ value used here after move
31 |         for val in q.second_half {
   |                    ------------- use occurs due to use in closure

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0382`.

For my limited understanding, there seems to be an ownership problem as q is moved into two different threads. I managed to get a correct output only after extracting both struct fields into new variables. This is my solution:

// -- snip
fn send_tx(q: Queue, tx: mpsc::Sender<u32>) {
    // Clone the sender `tx` first.
    let tx_clone = tx.clone();

    let first_half = q.first_half;
    let second_half = q.second_half;

    thread::spawn(move || {
        for val in first_half {
            println!("Sending {val:?}");
            // Then use the clone in the first thread. This means that
            // `tx_clone` is moved to the first thread and `tx` to the second.
            tx_clone.send(val).unwrap();
            thread::sleep(Duration::from_millis(250));
        }
    });

    thread::spawn(move || {
        for val in second_half {
            println!("Sending {val:?}");
            tx.send(val).unwrap();
            thread::sleep(Duration::from_millis(250));
        }
    });
}
// -- snip

Is this analysis correct? Is there actually something I missed?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions