title: In Rust, how can a reference be a pointer to a pointer-to-a-pointer?
body: <p>Today's Rust mystery is from section 4.9 of The Rust Programming Language, First Edition.  The example of references and borrowing has this example:</p>
  
  <pre><code>fn main() {
      fn sum_vec(v: &amp;Vec&lt;i32&gt;) -&gt; i32 {
          return v.iter().fold(0, |a, &amp;b| a + b);
      }
  
      fn foo(v1: &amp;Vec&lt;i32&gt;) -&gt; i32 {
          sum_vec(v1);
      }
  
      let v1 = vec![1, 2, 3];
  
      let answer = foo(&amp;v1);
      println!("{}", answer);
  }
  </code></pre>
  
  <p>That seems reasonable.  It prints "6", which is what you'd expect if the
  <code>v</code> of <code>sum_vec</code> is a C++ reference; it's just a name for a memory
  location, the vector <code>v1</code> we defined in <code>main()</code>.</p>
  
  <p>Then I replaced the body of <code>sum_vec</code> with this:</p>
  
  <pre><code>fn sum_vec(v: &amp;Vec&lt;i32&gt;) -&gt; i32 {
      return (*v).iter().fold(0, |a, &amp;b| a + b);
  }
  </code></pre>
  
  <p>It compiled and worked as expected.  Okay, that's not… entirely crazy.  The compiler is trying to make my life easier, I get that.  Confusing, something that I have to memorize as a specific tic of the language, but not entirely crazy.  Then I tried:</p>
  
  <pre><code>fn sum_vec(v: &amp;Vec&lt;i32&gt;) -&gt; i32 {
      return (**v).iter().fold(0, |a, &amp;b| a + b);
  }
  </code></pre>
  
  <p>It still worked!  What the hell?</p>
  
  <pre><code>fn sum_vec(v: &amp;Vec&lt;i32&gt;) -&gt; i32 {
      return (***v).iter().fold(0, |a, &amp;b| a + b);
  }
  </code></pre>
  
  <p><code>type [i32] cannot be dereferenced</code>.  Oh, thank god, something that makes sense.  But I would have expected that almost two iterations earlier!  </p>
  
  <p>References in Rust aren't C++ "names for another place in memory," but what <em>are</em> they?  They're not pointers either, and the rules about them seem to be either esoteric or highly ad-hoc.  What is happening such that a reference, a pointer, and a pointer-to-a-pointer all work equally well here?</p>