title: Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in?
body: <p>I've got a persistent compile error where Rust complains that I have an immutable borrow while I'm trying to mutably borrow, but the immutable borrow is from another scope, and I'm not bringing anything across from it.</p>
  
  <p>I have some code that checks for a value in a map, and if it's present, returns it, otherwise it needs to mutate the map in various ways. The problem is that I can't seem to find a way to get Rust let me do both, even though the two operations are totally separate.</p>
  
  <p>Here's some nonsensical code that follows the same structure as my code and exhibits the problem:</p>
  
  <pre><code>use std::collections::BTreeMap;
  
  fn do_stuff(map: &amp;mut BTreeMap&lt;i32, i32&gt;, key: i32) -&gt; Option&lt;&amp;i32&gt; {
      // extra scope in vain attempt to contain the borrow
      {
          // borrow immutably
          if let Some(key) = map.get(&amp;key) {
              return Some(key);
          }
      }
  
      // now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed
  
      map.insert(0, 0); // borrow mutably, which errors
      None
  }
  </code></pre>
  
  <p>This errors out with:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
    --&gt; src/lib.rs:14:5
     |
  3  | fn do_stuff(map: &amp;mut BTreeMap&lt;i32, i32&gt;, key: i32) -&gt; Option&lt;&amp;i32&gt; {
     |                  - let's call the lifetime of this reference `'1`
  ...
  7  |         if let Some(key) = map.get(&amp;key) {
     |                            --- immutable borrow occurs here
  8  |             return Some(key);
     |                    --------- returning this value requires that `*map` is borrowed for `'1`
  ...
  14 |     map.insert(0, 0); // borrow mutably, which errors
     |     ^^^^^^^^^^^^^^^^ mutable borrow occurs here
  </code></pre>
  
  <p>This doesn't make any sense to me. How does the immutable borrow outlive that scope?! One branch of that <code>match</code> exits the function via <code>return</code>, and the other does nothing and leaves the scope.</p>
  
  <p>I've seen this happen before where I was mistakenly smuggling the borrow out of the scope in some other variable, but that's not the case here!</p>
  
  <p>True, the borrow is escaping the scope via the <code>return</code> statement, but it's ridiculous that that blocks borrowing farther down in the function -- the program cannot possibly return AND keep going! If I return something else there, the error goes away, so I think this is what the borrow checker is getting hung up on. This feels like a bug to me.</p>
  
  <p>Unfortunately, I've been unable to find any way to rewrite this without hitting the same error, so it's a particularly nasty bug if that's the case.</p>