title: How can I borrow from a HashMap to read and write at the same time?
body: <p>I have a function <code>f</code> that accepts two references, one <code>mut</code> and one not <code>mut</code>. I have values for <code>f</code> inside a <code>HashMap</code>:</p>
  
  <pre><code>use std::collections::HashMap;
  
  fn f(a: &amp;i32, b: &amp;mut i32) {}
  
  fn main() {
      let mut map = HashMap::new();
  
      map.insert("1", 1);
      map.insert("2", 2);
  
      {
          let a: &amp;i32 = map.get("1").unwrap();
          println!("a: {}", a);
  
          let b: &amp;mut i32 = map.get_mut("2").unwrap();
          println!("b: {}", b);
          *b = 5;
      }
      println!("Results: {:?}", map)
  }
  </code></pre>
  
  <p>This doesn't work because <code>HashMap::get</code> and <code>HashMap::get_mut</code> attempt to  mutably borrow and immutably borrow at the same time:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0502]: cannot borrow `map` as mutable because it is also borrowed as immutable
    --&gt; src/main.rs:15:27
     |
  12 |         let a: &amp;i32 = map.get("1").unwrap();
     |                       --- immutable borrow occurs here
  ...
  15 |         let b: &amp;mut i32 = map.get_mut("2").unwrap();
     |                           ^^^ mutable borrow occurs here
  ...
  18 |     }
     |     - immutable borrow ends here
  </code></pre>
  
  <p>In my real code I'm using a large, complex structure instead of a <code>i32</code> so it is not a good idea to clone it.</p>
  
  <p>In fact, I'm borrowing two different things mutably/immutably, like:</p>
  
  <pre><code>struct HashMap {
      a: i32,
      b: i32,
  }
  let mut map = HashMap { a: 1, b: 2 };
  let a = &amp;map.a;
  let b = &amp;mut map.b;
  </code></pre>
  
  <p>Is there any way to explain to the compiler that this is actually safe code?</p>
  
  <p>I see how it possible to solve in the concrete case with <code>iter_mut</code>:</p>
  
  <pre><code>{
      let mut a: &amp;i32 = unsafe { mem::uninitialized() };
      let mut b: &amp;mut i32 = unsafe { mem::uninitialized() };
      for (k, mut v) in &amp;mut map {
          match *k {
              "1" =&gt; {
                  a = v;
              }
              "2" =&gt; {
                  b = v;
              }
              _ =&gt; {}
          }
      }
      f(a, b);
  }
  </code></pre>
  
  <p>But this is slow in comparison with <code>HashMap::get/get_mut</code></p>