2

The following code fails to compile:

use std::thread;

#[derive(Debug)]
struct Contained {
    a: u8
}

#[derive(Debug)]
struct Wrapper<'a> {
    b: &'a Contained,
}

fn main() {
    println!("Hello, world!");

    let c = Contained { a: 42 };
    let w = Wrapper { b: &c };

    println!("C: {:?}", c);
    println!("W: {:?}", w);

    let handle = thread::spawn(move || {
        println!("C in thread: {:?}", c);
    });
    handle.join().unwrap();
}

Error message:

src/main.rs:24:39: 24:40 error: cannot move `c` into closure because it is borrowed [E0504]
src/main.rs:24         println!("C in thread: {:?}", c);
                                                     ^
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:24:9: 24:42 note: in this expansion of println! (defined in <std macros>)
src/main.rs:18:27: 18:28 note: borrow of `c` occurs here
src/main.rs:18     let w = Wrapper { b: &c };
                                         ^

The borrow checker is obviously right about this. A way to work around this is by using explicit scopes, so that the wrapper is dropped, freeing the borrowed contained object.

let c = Contained { a: 42 };
{
    let w = Wrapper { b: &c };
    println!("C: {:?}", c);
    println!("W: {:?}", w);
}
let handle = thread::spawn(move || {
    println!("C in thread: {:?}", c);
});

This compiles properly.

Another way to make an object go out of scope is by using the std::mem::drop function. In this case it does not work though:

let c = Contained { a: 42 };
let w = Wrapper { b: &c };
println!("C: {:?}", c);
println!("W: {:?}", w);
drop(w);
let handle = thread::spawn(move || {
    println!("C in thread: {:?}", c);
});

The borrow checker complains with the same error message as before.

Why does drop(w) not free the borrowed c?

Danilo Bargen
  • 18,626
  • 15
  • 91
  • 127
  • @ker you're right. It's hard to find though, maybe the title of the other question can be adjusted. – Danilo Bargen Mar 15 '16 at 15:44
  • no need. if this question is marked as a duplicate, people will find the correct answer through this question – oli_obk Mar 15 '16 at 15:45
  • 2
    @DaniloBargen: As ker mentioned, don't worry. The very purpose of retaining duplicate on StackOverflow is to provide multiple entry points each with its own wording. This is precisely because some problems can have many different formulations :) – Matthieu M. Mar 15 '16 at 15:59
  • See also [these](http://stackoverflow.com/questions/35765440/what-are-the-options-to-end-a-mutable-borrow-in-rust/) more recent question and answer. – Vladimir Matveev Mar 15 '16 at 16:05

0 Answers0