title: How do I specify the lifetime on a generic type passed to function by move?
body: <p>I'd like to wrap a function in a struct to package it with other data. When I specify the input type of the function explicitly, it works fine. When I attempt to generalize the pattern into a generic struct, I run into lifetime errors.</p>
  
  <p>I've shared a code snippet in a playground and below. As is this does not compile. If I switch from <code>Wrapper</code> to <code>WrapperExplicit</code>, it works perfectly. What's going wrong? How I can make this wrapper generic?</p>
  
  <p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=92cac14257aaec53b648df93566ac3df" rel="nofollow noreferrer">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=92cac14257aaec53b648df93566ac3df</a></p>
  
  <pre><code>use std::marker::PhantomData;
  
  struct Reference&lt;'a, X&gt; {
      x : &amp; 'a mut X 
  }
  
  //Works
  struct WrapperExplicit&lt;F&gt; 
      where F : Fn(Reference&lt;String&gt;)
  {
      data : u64,
      func : F,
  }
  impl&lt;F&gt; WrapperExplicit&lt;F&gt;
      where F : Fn(Reference&lt;String&gt;)
  {
      pub fn new(func: F) -&gt; WrapperExplicit&lt;F&gt; {
          WrapperExplicit {
              data : 10,
              func: func,
          }
      }
  
      pub fn call(&amp; mut self, arg: Reference&lt;String&gt;)
      {
          (self.func)(arg)
      }
  }
  
  //Doesn't work
  struct Wrapper&lt;F, U&gt; 
      where F : Fn(U)
  {
      data : u64,
      func : F,
      _marker: PhantomData&lt;U&gt;,
  }
  
  impl&lt;F,U&gt; Wrapper&lt;F,U&gt;
      where F : Fn(U)
  {
      pub fn new(func: F) -&gt; Wrapper&lt;F,U&gt; {
          Wrapper {
              data : 0,
              func: func,
              _marker: PhantomData {}
          }
      }
  
      pub fn call(&amp; mut self, arg: U)
      {
          (self.func)(arg)
      }
  }
  
  fn fn_borrow(x : Reference&lt;String&gt;) {
      println!("{}", x.x);
  }
  
  fn fn_move(y : String) {
      println!("{}", &amp;y);
  }
  
  pub fn test_example() {
      let mut f = Wrapper::new(fn_borrow); //Doesn't work
      // let mut f = WrapperExplicit::new(fn_borrow); //Works
      let mut y = "Hello!".to_string();
      let x = Reference{ x : &amp;mut y};
      f.call(x);
      fn_move(y);
      println!("{}", f.data)
  }
  </code></pre>
  
  <hr>
  
  <p>EDIT:
  Here's an even simpler example:
  <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=0f4f5236d4e4439b3bec5a717f62567c" rel="nofollow noreferrer">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=0f4f5236d4e4439b3bec5a717f62567c</a></p>
  
  <p>I believe the issue is that because the generic type has to be set when you create the struct, the lifetime for the generic type is set then as well, so you can't use a different lifetime when you call the struct's associated function. Is that true? Is there a way to let the "type" part of the struct be generic, but leave the lifetime to be decided when one of the struct's functions is called? </p>
  
  <pre><code>use std::marker::PhantomData;
  
  //Doesn't work
  struct WrapperSimple&lt;U&gt; 
  {
      data : u64,
      _marker: PhantomData&lt;U&gt;,
  }
  
  impl&lt;U&gt; WrapperSimple&lt;U&gt;
  {
      pub fn new() -&gt; WrapperSimple&lt;U&gt; {
          WrapperSimple {
              data : 0,
              _marker: PhantomData {}
          }
      }
  
      pub fn call(&amp; mut self, _arg: U)
      {
      }
      pub fn call2&lt;V&gt;(&amp; mut self, _arg: V)
      {
      }
  }
  
  fn fn_move(y : String) {
      println!("{}", &amp;y);
  }
  
  fn main() {
      let mut w = WrapperSimple::&lt;&amp;str&gt;::new();
      let mut y = "Hello!".to_string();
      let x = &amp; mut y;
      w.call(x); //Doesn't work
      //w.call2(x); //Works, (obviously)
      fn_move(y);
      println!("{}", w.data)
  }
  </code></pre>
  
  <hr>
  
  <p>EDIT 2:</p>
  
  <p>I think here's how it ultimately shakes out:</p>
  
  <ul>
  <li>You can't store a generic function with generic inputs in a struct
  without referencing the function's input type in the struct's type
  parameters, and therefore also need a PhantomData field of that type
  (otherwise you have an unconstrained or unused type parameter)</li>
  <li>Once you have a field of that type, the type's embedded lifetime has
  to be set when the struct is monomorphized, for example at
  construction</li>
  <li>That means the lifetime is fixed and cannot vary each
  time you call one of the struct's methods</li>
  <li>You also can't create a new generic type parameter for the method and constrain it to match the struct's type parameter, except stripping the struct type's lifetime</li>
  </ul>
  
  <p>Therefore, what I want to accomplish is not currently supported by rust's type system. Please let me know if one of my assumptions here is wrong.</p>