title: How can I pass a reference to a stack variable to a thread?
body: <p>I'm writing a WebSocket server where a web client connects to play chess against a multithreaded computer AI. The WebSocket server wants to pass a <code>Logger</code> object into the AI code. The <code>Logger</code> object is going to pipe down log lines from the AI to the web client. The <code>Logger</code> must contain a reference to the client connection.</p>
  <p>I'm confused about how lifetimes interact with threads. I've reproduced the problem with a <code>Wrapper</code> struct parameterized by a type. The <code>run_thread</code> function tries to unwrap the value and log it.</p>
  <pre class="lang-rs prettyprint-override"><code>use std::fmt::Debug;
  use std::thread;
  
  struct Wrapper&lt;T: Debug&gt; {
      val: T,
  }
  
  fn run_thread&lt;T: Debug&gt;(wrapper: Wrapper&lt;T&gt;) {
      let thr = thread::spawn(move || {
          println!(&quot;{:?}&quot;, wrapper.val);
      });
  
      thr.join();
  }
  
  fn main() {
      run_thread(Wrapper::&lt;i32&gt; { val: -1 });
  }
  </code></pre>
  <p>The <code>wrapper</code> argument lives on the stack, and its lifetime doesn't extend past <code>run_thread</code>'s stack frame, even though the thread will be joined before the stack frame ends. I'd could copy the value off the stack:</p>
  <pre class="lang-rs prettyprint-override"><code>use std::fmt::Debug;
  use std::thread;
  
  struct Wrapper&lt;T: Debug + Send&gt; {
      val: T,
  }
  
  fn run_thread&lt;T: Debug + Send + 'static&gt;(wrapper: Wrapper&lt;T&gt;) {
      let thr = thread::spawn(move || {
          println!(&quot;{:?}&quot;, wrapper.val);
      });
  
      thr.join();
  }
  
  fn main() {
      run_thread(Wrapper::&lt;i32&gt; { val: -1 });
  }
  </code></pre>
  <p>This will not work if <code>T</code> is a reference to a big object I don't want copied:</p>
  <pre class="lang-rs prettyprint-override"><code>use std::fmt::Debug;
  use std::thread;
  
  struct Wrapper&lt;T: Debug + Send&gt; {
      val: T,
  }
  
  fn run_thread&lt;T: Debug + Send + 'static&gt;(wrapper: Wrapper&lt;T&gt;) {
      let thr = thread::spawn(move || {
          println!(&quot;{:?}&quot;, wrapper.val);
      });
  
      thr.join();
  }
  
  fn main() {
      let mut v = Vec::new();
      for i in 0..1000 {
          v.push(i);
      }
  
      run_thread(Wrapper { val: &amp;v });
  }
  </code></pre>
  <p>Which results in:</p>
  <pre class="lang-none prettyprint-override"><code>error: `v` does not live long enough
    --&gt; src/main.rs:22:32
     |
  22 |     run_thread(Wrapper { val: &amp;v });
     |                                ^ does not live long enough
  23 | }
     | - borrowed value only lives until here
     |
     = note: borrowed value must be valid for the static lifetime...
  </code></pre>
  <p>The only solution I can think of is to use an <code>Arc</code>.</p>
  <pre><code>use std::fmt::Debug;
  use std::sync::Arc;
  use std::thread;
  
  struct Wrapper&lt;T: Debug + Send + Sync + 'static&gt; {
      arc_val: Arc&lt;T&gt;,
  }
  
  fn run_thread&lt;T: Debug + Send + Sync + 'static&gt;(wrapper: &amp;Wrapper&lt;T&gt;) {
      let arc_val = wrapper.arc_val.clone();
      let thr = thread::spawn(move || {
          println!(&quot;{:?}&quot;, *arc_val);
      });
  
      thr.join();
  }
  
  fn main() {
      let mut v = Vec::new();
      for i in 0..1000 {
          v.push(i);
      }
  
      let w = Wrapper { arc_val: Arc::new(v) };
      run_thread(&amp;w);
  
      println!(&quot;{}&quot;, (*w.arc_val)[0]);
  }
  </code></pre>
  <p>In my real program, it appears that both the <code>Logger</code> and the connection object must be placed in <code>Arc</code> wrappers. It seems annoying that the client is required to box the connection in an <code>Arc</code> when it is internal to the library that the code is parallelized. This is especially annoying because the lifetime of the connection is guaranteed to be greater than the lifetime of the worker threads.</p>
  <p>Have I missed something?</p>