title: How do I implement a newtype wrapper around borrowed values?
body: <p>I'm trying to implement a newtype wrapper around a borrowed value, in order to implement different behavior for a trait but can't get this to conform to the borrowing rules. I prepared a simplified example below.</p>
  <p>Note: <a href="https://github.com/apache/arrow/blob/apache-arrow-1.0.1/rust/arrow/src/array/ord.rs#L72" rel="nofollow noreferrer">The actual code is more complex</a> and also needs to work with values that need <code>.as_any().downcast_ref()</code> first, which is why I'd like this to work with borrowed values.</p>
  <pre><code>use std::cmp::Ordering;
  
  trait OrdVec {
      fn cmp(&amp;self, i: usize, j: usize) -&gt; Ordering;
  }
  
  // note: actual trait bound is more complex and would lead to
  // &quot;conflicting implementations&quot; when trying to implement `OrdSlice for &amp;[f64]`
  impl&lt;T&gt; OrdVec for Vec&lt;T&gt;
  where
      T: Ord,
  {
      fn cmp(&amp;self, i: usize, j: usize) -&gt; Ordering {
          self[i].cmp(&amp;self[j])
      }
  }
  
  #[repr(transparent)]
  struct F64VecAsOrdVec&lt;'a&gt;(&amp;'a Vec&lt;f64&gt;);
  
  impl OrdVec for F64VecAsOrdVec&lt;'_&gt; {
      fn cmp(&amp;self, i: usize, j: usize) -&gt; Ordering {
          let a: f64 = self.0[i];
          let b: f64 = self.0[j];
  
          if a &lt; b {
              return Ordering::Less;
          }
          if a &gt; b {
              return Ordering::Greater;
          }
  
          unimplemented!(&quot;convert NaN to canonical form and compare bitwise&quot;)
      }
  }
  
  fn as_ord_vec&lt;'a&gt;(first: bool, int_vec: &amp;'a Vec&lt;i64&gt;, float_vec: &amp;'a Vec&lt;f64&gt;) -&gt; &amp;'a dyn OrdVec {
      if first {
          int_vec
      } else {
          // returns a reference to data owned by the current function
          &amp;F64VecAsOrdVec(float_vec)
  
          // newtype should have same layout but this fails on calling `cmp`
          // with &quot;SIGSEGV: invalid memory reference&quot;
          // let ord: &amp;F64VecAsOrdVec = unsafe { std::mem::transmute(float_vec) };
          // ord
      }
  }
  
  #[test]
  fn test_int_as_ord() {
      let int_vec = vec![1, 2, 3];
      let float_vec = vec![3.0, 2.0, 1.0];
      let int_ord = as_ord_vec(true, &amp;int_vec, &amp;float_vec);
  
      assert_eq!(Ordering::Less, int_ord.cmp(0, 1));
  }
  
  #[test]
  fn test_float_as_ord() {
      let int_vec = vec![1, 2, 3];
      let float_vec = vec![3.0, 2.0, 1.0];
      let float_ord = as_ord_vec(false, &amp;int_vec, &amp;float_vec);
  
      assert_eq!(Ordering::Greater, float_ord.cmp(0, 1));
  }
  </code></pre>
  <pre class="lang-none prettyprint-override"><code>error[E0515]: cannot return reference to temporary value
    --&gt; src/lib.rs:43:5
     |
  43 |     &amp;F64VecAsOrdVec(vec)
     |     ^-------------------
     |     ||
     |     |temporary value created here
     |     returns a reference to data owned by the current function
  </code></pre>