1
votes

I have reproduced my problem in the short code below.

Problem: The inner thread uses reference of variable v from the outer thread. The rust compiler throws an error because "technically" the outer thread could terminate before the inner thread and hence inner thread could loose access to variable v. However in the code below that clearly cannot happen.

Question: How shall I change this code so that it complies while maintaining the same functionality?

fn main() { //outer thread
    let v = vec![0, 1];
    let test = Test { v: &v }; //inner_thread
    std::thread::spawn(move || test.print());
    loop {
        // this thread will never die because it will never leave this loop
    }
}

pub struct Test<'a> {
    v: &'a Vec<u32>,
}

impl<'a> Test<'a> {
    fn print(&self) {
        println!("{:?}", self.v);
    }
}
error[E0597]: `v` does not live long enough
 --> src/main.rs:3:26
  |
3 |     let test = Test { v: &v }; //inner_thread
  |                          ^^ borrowed value does not live long enough
4 |     std::thread::spawn(move || test.print());
  |     ---------------------------------------- argument requires that `v` is borrowed for `'static`
...
8 | }
  | - `v` dropped here while still borrowed
1
Why exactly do you want test to hold a reference and not move v ? The real solution depends on your real problem, which isn't shown here. The solution might be moving, using static, using crossbeam's scope, etc.Denys Séguret

1 Answers

1
votes

The obvious solution would be to have Test own the vector instead of just have a reference.

But if you really need to borrow the value in the thread (probably because you want to use it after end of execution), then you may use crossbeam's scope:

let v = vec![0, 1];
let test = Test { v: &v }; //inner_thread
crossbeam::thread::scope(|scope| {
    scope.spawn(|_| test.print());
}).unwrap();