title: Lifetime parameter for `Self` in trait signature
body: <p>Consider this simple protocol implementation:</p>
  
  <pre><code>#[derive(PartialEq, Debug)]
  enum Req&lt;'a&gt; {
      InputData(&amp;'a [u8]),
      Stop,
  }
  
  impl&lt;'a&gt; Req&lt;'a&gt; {
      fn decode(packet: &amp;'a [u8]) -&gt; Result&lt;Req&lt;'a&gt;, String&gt; {
          match packet.first() {
              Some(&amp;0x01) =&gt; Ok(Req::InputData(&amp;packet[1..])),
              Some(&amp;0x02) =&gt; Ok(Req::Stop),
              _ =&gt; Err(format!("invalid request: {:?}", packet)),
          }
      }
  }
  
  #[derive(PartialEq, Debug)]
  enum Rep&lt;'a&gt; {
      OutputData(&amp;'a [u8]),
      StopAck,
  }
  
  impl&lt;'a&gt; Rep&lt;'a&gt; {
      fn decode(packet: &amp;'a [u8]) -&gt; Result&lt;Rep&lt;'a&gt;, String&gt; {
          match packet.first() {
              Some(&amp;0x01) =&gt; Ok(Rep::OutputData(&amp;packet[1..])),
              Some(&amp;0x02) =&gt; Ok(Rep::StopAck),
              _ =&gt; Err(format!("invalid reply: {:?}", packet)),
          }
      }
  }
  
  fn assert_req(packet: Vec&lt;u8&gt;, sample: Req) {
      assert_eq!(Req::decode(&amp;packet), Ok(sample));
  }
  
  fn assert_rep(packet: Vec&lt;u8&gt;, sample: Rep) {
      assert_eq!(Rep::decode(&amp;packet), Ok(sample));
  }
  
  fn main() {
      assert_req(vec![1, 2, 3], Req::InputData(&amp;[2, 3]));
      assert_req(vec![2], Req::Stop);
      assert_rep(vec![1, 2, 3], Rep::OutputData(&amp;[2, 3]));
      assert_rep(vec![2], Rep::StopAck);
  }
  </code></pre>
  
  <p><a href="https://play.rust-lang.org/?gist=2f18b3f0bd485a1360495055aa4d4980&amp;version=stable" rel="nofollow noreferrer">playground</a></p>
  
  <p>This works, but the two functions <code>assert_req</code> and <code>assert_rep</code> have identical code with only a difference in types. It is a good idea to write one generic <code>assert_packet</code>:</p>
  
  <pre><code>trait Decode&lt;'a&gt;: Sized {
      fn decode(packet: &amp;'a [u8]) -&gt; Result&lt;Self, String&gt;;
  }
  
  #[derive(PartialEq, Debug)]
  enum Req&lt;'a&gt; {
      InputData(&amp;'a [u8]),
      Stop,
  }
  
  impl&lt;'a&gt; Decode&lt;'a&gt; for Req&lt;'a&gt; {
      fn decode(packet: &amp;'a [u8]) -&gt; Result&lt;Req&lt;'a&gt;, String&gt; {
          match packet.first() {
              Some(&amp;0x01) =&gt; Ok(Req::InputData(&amp;packet[1..])),
              Some(&amp;0x02) =&gt; Ok(Req::Stop),
              _ =&gt; Err(format!("invalid request: {:?}", packet)),
          }
      }
  }
  
  #[derive(PartialEq, Debug)]
  enum Rep&lt;'a&gt; {
      OutputData(&amp;'a [u8]),
      StopAck,
  }
  
  impl&lt;'a&gt; Decode&lt;'a&gt; for Rep&lt;'a&gt; {
      fn decode(packet: &amp;'a [u8]) -&gt; Result&lt;Rep&lt;'a&gt;, String&gt; {
          match packet.first() {
              Some(&amp;0x01) =&gt; Ok(Rep::OutputData(&amp;packet[1..])),
              Some(&amp;0x02) =&gt; Ok(Rep::StopAck),
              _ =&gt; Err(format!("invalid reply: {:?}", packet)),
          }
      }
  }
  
  fn assert_packet&lt;'a, T&gt;(packet: Vec&lt;u8&gt;, sample: T)
  where
      T: Decode&lt;'a&gt; + PartialEq + std::fmt::Debug,
  {
      assert_eq!(T::decode(&amp;packet), Ok(sample));
  }
  
  fn main() {
      assert_packet(vec![1, 2, 3], Req::InputData(&amp;[2, 3]));
      assert_packet(vec![2], Req::Stop);
      assert_packet(vec![1, 2, 3], Rep::OutputData(&amp;[2, 3]));
      assert_packet(vec![2], Rep::StopAck);
  }
  </code></pre>
  
  <p><a href="https://play.rust-lang.org/?gist=7cd9c7ef80b9cd4e54cf73011a0bd78b&amp;version=stable" rel="nofollow noreferrer">playground</a></p>
  
  <p>However, this triggers a "does not live long enough" error:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0597]: `packet` does not live long enough
    --&gt; src/main.rs:41:27
     |
  41 |     assert_eq!(T::decode(&amp;packet), Ok(sample));
     |                           ^^^^^^ does not live long enough
  42 | }
     | - borrowed value only lives until here
     |
  note: borrowed value must be valid for the lifetime 'a as defined on the function body at 37:1...
    --&gt; src/main.rs:37:1
     |
  37 | / fn assert_packet&lt;'a, T&gt;(packet: Vec&lt;u8&gt;, sample: T)
  38 | | where
  39 | |     T: Decode&lt;'a&gt; + PartialEq + std::fmt::Debug,
  40 | | {
  41 | |     assert_eq!(T::decode(&amp;packet), Ok(sample));
  42 | | }
     | |_^
  </code></pre>
  
  <p>If I understand correctly, the problem is in the function signature:</p>
  
  <pre><code>fn assert_packet&lt;'a, T&gt;(packet: Vec&lt;u8&gt;, sample: T)
  where
      T: Decode&lt;'a&gt;
  </code></pre>
  
  <p>Here, <code>packet</code> is destroyed when the function returns, but the user-provided <code>'a</code> lifetime parameter says that the lifetime should end somewhere outside the <code>assert_packet</code> function. Is there any right solution? How should the signature look? Maybe <a href="https://doc.rust-lang.org/stable/nomicon/hrtb.html" rel="nofollow noreferrer">higher rank trait bounds</a> could help here?</p>