title: How to implement generics over all types capable of arithmetic operations?
body: <p>The <code>Number</code> wrapper presents subtraction on its contained type if possible. The <code>Difference</code> struct saves two numbers and their difference (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=f0b0b536376c7ac35db01c206dcfeeea" rel="nofollow noreferrer">playground</a>):</p>
  <pre><code>use std::ops::Sub;
  
  #[derive(Debug)]
  struct Number&lt;T&gt;(T); // Doesn't have the Copy marker
  // Implements subtraction whenever the contained type does
  // Only the case with references implemented for brevity
  impl&lt;'a, 'b, T&gt; Sub&lt;&amp;'b Number&lt;T&gt;&gt; for &amp;'a Number&lt;T&gt;
  where
      &amp;'a T: Sub&lt;&amp;'b T, Output = T&gt; 
  {
      type Output = Number&lt;T&gt;;
      
      fn sub(self, rhs: &amp;'b Number&lt;T&gt;) -&gt; Number&lt;T&gt; {
          Number(&amp;self.0 - &amp;rhs.0)
      }
  }
  
  #[derive(Debug)]
  struct Difference&lt;T&gt; {
      a: Number&lt;T&gt;,
      b: Number&lt;T&gt;,
      diff: Number&lt;T&gt;,
  }
  impl&lt;'a, 'b, T: 'b + 'a&gt; Difference&lt;T&gt;
  where
      // &quot;Any type for which `Number` implements subtraction&quot;
      &amp;'a Number&lt;T&gt;: Sub&lt;&amp;'b Number&lt;T&gt;, Output = Number&lt;T&gt;&gt;,
  {
      fn new(a: Number&lt;T&gt;, b: Number&lt;T&gt;) -&gt; Self {
          let diff = &amp;b - &amp;a;
          Difference { a, b, diff }
      }
  }
  
  fn main() {
      println!(&quot;{:?}&quot;, Difference::new(Number(3), Number(5)));
  }
  </code></pre>
  <p>This code doesn't compile for several reasons. Firstly, there's recursion while evaluating the <code>Sub</code> trait bound:</p>
  <pre class="lang-none prettyprint-override"><code>error[E0275]: overflow evaluating the requirement `&amp;BTreeSet&lt;_&gt;: Sub&lt;&amp;BTreeSet&lt;_&gt;&gt;`
    --&gt; src/main.rs:36:22
     |
  36 |     println!(&quot;{:?}&quot;, Difference::new(Number(3), Number(5)));
     |                      ^^^^^^^^^^^^^^^
     |
     = help: consider adding a `#![recursion_limit=&quot;256&quot;]` attribute to your crate (`playground`)
  note: required because of the requirements on the impl of `Sub&lt;&amp;Number&lt;BTreeSet&lt;_&gt;&gt;&gt;` for `&amp;Number&lt;BTreeSet&lt;_&gt;&gt;`
    --&gt; src/main.rs:7:17
     |
  7  | impl&lt;'a, 'b, T&gt; Sub&lt;&amp;'b Number&lt;T&gt;&gt; for &amp;'a Number&lt;T&gt;
     |                 ^^^^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^
     = note: 127 redundant requirements hidden
     = note: required because of the requirements on the impl of `Sub` for `&amp;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;Number&lt;BTreeSet&lt;_&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;`
  </code></pre>
  <p>I don't understand that, because as I see it, the compiler should:</p>
  <ul>
  <li>see that <code>Difference::new()</code> is invoked</li>
  <li>extract the <code>T</code> type from its parameters (<code>{integer}</code> in this case)</li>
  <li>check if there is any valid implementation for the bounds of this type:
  <pre class="lang-none prettyprint-override"><code>`&amp;'a Number&lt;{integer}&gt;: Sub&lt;&amp;'b Number&lt;{integer}&gt;, Output = Number&lt;{integer}&gt;&gt;`
  </code></pre>
  </li>
  <li>see that <code>impl&lt;'a, 'b, T&gt; Sub&lt;&amp;'b Number&lt;T&gt;&gt; for &amp;'a Number&lt;T&gt;</code> with <code>type Output = Number&lt;T&gt;;</code> is the correct implementation if the bounds on <code>T</code> are satisfied</li>
  <li>see that every <code>{integer}</code> satisfies the <code>&amp;'a T: Sub&lt;&amp;'b T, Output = T&gt;</code> bound</li>
  </ul>
  <p>It seems to me, that the compiler instead tries to recursively substitute <code>Number&lt;T&gt;</code> as <code>T</code>, but I don't understand why.</p>
  <p>Even after this problem is resolved (or hidden by commenting the <code>println!</code> invocation) a new error is generated:</p>
  <pre class="lang-none prettyprint-override"><code>error[E0597]: `b` does not live long enough
    --&gt; src/main.rs:30:20
     |
  24 | impl&lt;'a, 'b, T: 'b + 'a&gt; Difference&lt;T&gt;
     |      -- lifetime `'a` defined here
  ...
  30 |         let diff = &amp;b - &amp;a;
     |                    ^^
     |                    |
     |                    borrowed value does not live long enough
     |                    requires that `b` is borrowed for `'a`
  31 |         Difference { a, b, diff }
  32 |     }
     |     - `b` dropped here while still borrowed
  
  error[E0597]: `a` does not live long enough
    --&gt; src/main.rs:30:25
     |
  24 | impl&lt;'a, 'b, T: 'b + 'a&gt; Difference&lt;T&gt;
     |          -- lifetime `'b` defined here
  ...
  30 |         let diff = &amp;b - &amp;a;
     |                         ^^
     |                         |
     |                         borrowed value does not live long enough
     |                         requires that `a` is borrowed for `'b`
  31 |         Difference { a, b, diff }
  32 |     }
     |     - `a` dropped here while still borrowed
  
  error[E0505]: cannot move out of `a` because it is borrowed
    --&gt; src/main.rs:31:22
     |
  24 | impl&lt;'a, 'b, T: 'b + 'a&gt; Difference&lt;T&gt;
     |          -- lifetime `'b` defined here
  ...
  30 |         let diff = &amp;b - &amp;a;
     |                         --
     |                         |
     |                         borrow of `a` occurs here
     |                         requires that `a` is borrowed for `'b`
  31 |         Difference { a, b, diff }
     |                      ^ move out of `a` occurs here
  
  error[E0505]: cannot move out of `b` because it is borrowed
    --&gt; src/main.rs:31:25
     |
  24 | impl&lt;'a, 'b, T: 'b + 'a&gt; Difference&lt;T&gt;
     |      -- lifetime `'a` defined here
  ...
  30 |         let diff = &amp;b - &amp;a;
     |                    --
     |                    |
     |                    borrow of `b` occurs here
     |                    requires that `b` is borrowed for `'a`
  31 |         Difference { a, b, diff }
     |                         ^ move out of `b` occurs here
  </code></pre>
  <p>The idea is that I borrow <code>a</code> and <code>b</code> for the subtraction and then give them back, so that they can be moved into the returned struct. However, in the bound <code>&amp;'a Number&lt;T&gt;: Sub&lt;&amp;'b Number&lt;T&gt;, Output = Number&lt;T&gt;&gt;</code> I promise that they will be borrowed for the entire duration of the function. I don't want to promise that, but I need some lifetime to be even able to specify the bound, and I don't know how to specify a shorter lifetime.</p>
  <p>How would I go about solving these problems?</p>