title: Chaining functions on a trait
body: <p>I'm trying to make chainable transformations on a trait, and I'm having some issues.</p>
  
  <p>I have a bunch of transformation functions of the form:</p>
  
  <pre><code>fn transform&lt;T: MyTrait&gt;(in: T) -&gt; impl MyTrait
  </code></pre>
  
  <p>And I want a function <code>chain</code> which will allow me to do</p>
  
  <pre><code>let mut val: Box&lt;MyTrait&gt; = ...;
  val = chain(val, transform1);
  val = chain(val, transform2);
  ...
  </code></pre>
  
  <p>I have written this function</p>
  
  <pre><code>fn chain&lt;T, U, F&gt;(val: Box&lt;T&gt;, f: F) -&gt; Box&lt;MyTrait&gt;
    where T: MyTrait,
          U: MyTrait,
          F: FnOnce(T) -&gt; U {
    Box::new(f(*val))
  }
  </code></pre>
  
  <p>But when I compile, the borrow checker tells me that the type parameter U doesn't live long enough. I'm pretty sure my trait bounds are what I want, and I've tried various things with lifetime specifiers, so I'm stuck :(</p>
  
  <p>P.S. : Is it possible to make the <code>chain</code> function generic on <code>MyTrait</code>? I don't think it's possible, but we never know...</p>
  
  <p><strong>EDIT</strong>:</p>
  
  <p>I've added the fix proposed by @chris-emerson in his answer, by as I've said in its comments, I have uncovered another problem which seems unresolvable.</p>
  
  <p><a href="https://play.rust-lang.org/?gist=a519f51db3f43191f354c40e85b79fe1&amp;version=nightly" rel="nofollow" title="Here">Here</a> is a gist of the code, to not clutter this post.</p>
  
  <p>In short, the problem is: the chain function needs to dereference the <code>Box&lt;T&gt;</code> object and pass the <code>T</code> to the transform function, so <code>T</code> must be <code>Sized</code>. But the whole point of this function was to allow arbitrary (and unknown at compile-time) <code>MyTrait</code> implementations to be used. For example:</p>
  
  <pre><code>let mut val: Box&lt;MyTrait&gt; = ...;
  //here we can know the type inside the Box
  if ... {
    val = chain(val, transform);
  }
  //but here we don't know anymore
  //(its either the original type,
  //or the type returned by transform)
  </code></pre>
  
  <p>So this design can't work unless the transform function can take a &amp;T or a &amp;mut T (which it can't, as I need to consume the input to produce the output).</p>