title: Lifetime requirements in generic function returning impl trait + 'static
body: <p>I was reading <a href="https://tech.fpcomplete.com/rust/ownership-and-impl-trait" rel="nofollow noreferrer">Ownership and impl Trait</a> and I don't fully understand why Rust won't compile this.  The (slightly modified) code in question is:</p>
  
  <pre><code>fn make_debug&lt;'a, T: 'a&gt;(_: T) -&gt; impl std::fmt::Debug + 'static {
      42u8
  }
  
  fn test() -&gt; impl std::fmt::Debug + 'static {
      let value = "value".to_string();
      make_debug(&amp;value)
  }
  
  pub fn main() {
      println!("{:?}", test());
  }
  </code></pre>
  
  <p>The compilation fails:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0515]: cannot return value referencing local variable `value`
   --&gt; src/main.rs:7:5
    |
  7 |     make_debug(&amp;value)
    |     ^^^^^^^^^^^------^
    |     |          |
    |     |          `value` is borrowed here
    |     returns a value referencing data owned by the current function
  </code></pre>
  
  <p>Why does Rust not rely on the <code>'static</code> lifetime in the return value of the function signature of <code>make_debug()</code>?  I would have assumed the correctness of the function signature, including lifetimes, has been established by the compiler and can thus be relied upon.</p>
  
  <p>Is there an example where the return lifetime indicates <code>'static</code> but Rust somehow relies on non-<code>'static</code> data?  The blog post suggests this may be the case by stating</p>
  
  <blockquote>
    <p>The <code>impl Debug</code> may rely upon data inside the <code>T</code> parameter</p>
  </blockquote>
  
  <p>How?</p>
  
  <p>Concretely, the following does not allow non-<code>'static</code> data to be returned as <code>'static</code>.  So why does Rust not rely on the explicitly (and correctly) stated lifetimes associated with <code>make_debug()</code> at the call site in <code>test()</code>?</p>
  
  <p><strong>Note:</strong> the code below fails to compile if the lifetime on the return values of <code>make_debug()</code> is changed to <code>'static</code>.  As written, the code compiles.</p>
  
  <pre><code>struct A&lt;'a&gt; {
      s: &amp;'a String,
  }
  
  trait Foo {
      type Item;
      fn get&lt;'a&gt;(&amp;'a self) -&gt; Self::Item;
  }
  
  impl&lt;'a&gt; Foo for A&lt;'a&gt; {
      type Item = &amp;'a String;
      fn get&lt;'b&gt;(&amp;'b self) -&gt; Self::Item {
          self.s
      }
  }
  
  impl&lt;T, U&gt; Foo for &amp;T
  where
      T: Foo&lt;Item = U&gt;,
  {
      type Item = U;
      fn get&lt;'a&gt;(&amp;'a self) -&gt; Self::Item {
          (*self).get()
      }
  }
  
  // return lifetime 'a works, but does not work with 'static
  fn make_debug&lt;'a, T&gt;(x: T) -&gt; impl std::fmt::Debug + 'a
  where
      T: Foo,
      &lt;T as Foo&gt;::Item: std::fmt::Debug + 'a,
  {
      x.get()
  }
  </code></pre>