title: How to return a newly created struct as a reference?
body: <p>As an exercise to learn Rust I decided to implement a Bit Vector library, with inspiration from <code>std::vec::Vec</code> for which methods to provide.</p>
  
  <p>I have the following code:</p>
  
  <pre><code>extern crate num;
  
  use std::cmp::Eq;
  use std::ops::{BitAnd,BitOrAssign,Index,Shl};
  use num::{One,Zero,Unsigned,NumCast};
  
  pub trait BitStorage: Sized + 
      BitAnd&lt;Self, Output = Self&gt; + 
      BitOrAssign&lt;Self&gt; + 
      Shl&lt;Self, Output = Self&gt; + 
      Eq + Zero + One + Unsigned + NumCast + Copy {}
  
  impl&lt;S&gt; BitStorage for S where S: Sized + 
      BitAnd&lt;S, Output = S&gt; + 
      BitOrAssign&lt;S&gt; + 
      Shl&lt;S, Output = S&gt; + 
      Eq + Zero + One + Unsigned + NumCast + Copy {}
  
  pub struct BitVector&lt;S: BitStorage&gt; {
      data: Vec&lt;S&gt;,
      capacity: usize,
      storage_size: usize
  }
  
  impl&lt;S: BitStorage&gt; BitVector&lt;S&gt; {
      pub fn with_capacity(capacity: usize) -&gt; BitVector&lt;S&gt; {
          let storage_size = std::mem::size_of::&lt;S&gt;() * 8;
          let len = (capacity / storage_size) + 1;
          BitVector { 
              data: vec![S::zero(); len],
              capacity: capacity,
              storage_size: storage_size
          }
      }
  
      pub fn get(&amp;self, index: usize) -&gt; Option&lt;bool&gt; {
          match self.index_in_bounds(index) {
              true =&gt; Some(self.get_unchecked(index)),
              false =&gt; None
          }
      }
  
      pub fn set(&amp;mut self, index: usize, value: bool) {
          self.panic_index_bounds(index);
          let (data_index, remainder) = self.compute_data_index_and_remainder(index);
          let value = if value { S::one() } else { S::zero() };
          self.data[data_index] |= value &lt;&lt; remainder;
      }
  
      pub fn capacity(&amp;self) -&gt; usize {
          self.capacity
      }
  
      pub fn split_at(&amp;self, index: usize) -&gt; (&amp;BitVector&lt;S&gt;, &amp;BitVector&lt;S&gt;) {
          self.panic_index_not_on_storage_bound(index);
          let data_index = self.compute_data_index(index);
          let (capacity_left, capacity_right) = self.compute_capacities(index);
          let (data_left, data_right) = self.data.split_at(data_index);
  
          let left = BitVector {
              data: data_left.to_vec(),
              capacity: capacity_left,
              storage_size: self.storage_size
          };
          let right = BitVector {
              data: data_right.to_vec(),
              capacity: capacity_right,
              storage_size: self.storage_size
          };
          (&amp;left, &amp;right)
      }
  
      pub fn split_at_mut(&amp;mut self, index: usize) -&gt; (&amp;mut BitVector&lt;S&gt;, &amp;mut BitVector&lt;S&gt;) {
          self.panic_index_not_on_storage_bound(index);
          let data_index = self.compute_data_index(index);
          let (capacity_left, capacity_right) = self.compute_capacities(index);
          let (data_left, data_right) = self.data.split_at_mut(data_index);
  
          let mut left = BitVector {
              data: data_left.to_vec(),
              capacity: capacity_left,
              storage_size: self.storage_size
          };
          let mut right = BitVector {
              data: data_right.to_vec(),
              capacity: capacity_right,
              storage_size: self.storage_size
          };
          (&amp;mut left, &amp;mut right)
      }
  
      #[inline]
      fn get_unchecked(&amp;self, index: usize) -&gt; bool {
          let (data_index, remainder) = self.compute_data_index_and_remainder(index);
          (self.data[data_index] &amp; (S::one() &lt;&lt; remainder)) != S::zero()
      }
  
      #[inline]
      fn compute_data_index_and_remainder(&amp;self, index: usize) -&gt; (usize, S) {
          let data_index = self.compute_data_index(index);
          let remainder = self.compute_data_remainder(index);
          (data_index, remainder)
      }
  
      #[inline]
      fn compute_data_index(&amp;self, index: usize) -&gt; usize {
          index / self.storage_size
      }
  
      #[inline]
      fn compute_data_remainder(&amp;self, index: usize) -&gt; S {
          let remainder = index % self.storage_size;
          // we know that remainder is always smaller or equal to the size that S can hold
          // for example if S = u8 then remainder &lt;= 2^8 - 1
          let remainder: S = num::cast(remainder).unwrap();
          remainder
      }
  
      #[inline]
      fn compute_capacities(&amp;self, index_to_split: usize) -&gt; (usize, usize) {
          (index_to_split, self.capacity - index_to_split)
      }
  
      #[inline]
      fn index_in_bounds(&amp;self, index: usize) -&gt; bool {
          index &lt; self.capacity
      }
  
      #[inline]
      fn panic_index_bounds(&amp;self, index: usize) {
          if !self.index_in_bounds(index) {
              panic!("Index out of bounds. Length = {}, Index = {}", self.capacity, index);
          }
      }
  
      #[inline]
      fn panic_index_not_on_storage_bound(&amp;self, index: usize) {
          if index % self.storage_size != 0 {
              panic!("Index not on storage bound. Storage size = {}, Index = {}", self.storage_size, index);
          }
      }
  }
  
  static TRUE: bool = true;
  static FALSE: bool = false;
  
  macro_rules! bool_ref {
      ($cond:expr) =&gt; (if $cond { &amp;TRUE } else { &amp;FALSE })
  }
  
  impl&lt;S: BitStorage&gt; Index&lt;usize&gt; for BitVector&lt;S&gt; {
      type Output = bool;
  
      fn index(&amp;self, index: usize) -&gt; &amp;bool {
          self.panic_index_bounds(index);
          bool_ref!(self.get_unchecked(index))
      }
  }
  </code></pre>
  
  <p>The compiler errors occur at the <code>split_at</code> and <code>split_at_mut</code> methods: They basically tell me that <code>left</code> and <code>right</code> in both cases do not live long enough to be returned as a reference. I understand this, because they are created on the stack and then I want to return them as a reference.</p>
  
  <p>However with my design being inspired by <code>std::vec::Vec</code> you can see that <a href="https://github.com/rust-lang/rust/blob/master/src/libcore/slice.rs">in the SliceExt trait</a> their definitions are as follows:</p>
  
  <pre><code>#[stable(feature = "core", since = "1.6.0")]
  fn split_at(&amp;self, mid: usize) -&gt; (&amp;[Self::Item], &amp;[Self::Item]);
  
  #[stable(feature = "core", since = "1.6.0")]
  fn split_at_mut(&amp;mut self, mid: usize) -&gt; (&amp;mut [Self::Item], &amp;mut [Self::Item]);
  </code></pre>
  
  <p>I suppose this is done for end user convenience as they rather deal with references than with boxes.</p>
  
  <p>I think I could fix my errors by putting the returned bit vectors into a <code>Box&lt;_&gt;</code>, but is there a way to return the created structs as a reference?</p>
  
  <p>As a bonus question: It does work if I return <code>(BitVector&lt;S&gt;, BitVector&lt;S&gt;)</code>, what are the downsides to doing this? Why does the <code>SliceExt</code> trait not do this?</p>