1

I want to do something similar to this code:

use std::collections::HashMap;

fn main() {
    let mut vars = HashMap::<String, String>::new();
    find_and_do_someth(&mut vars);
}

fn find_and_do_someth(map: &mut HashMap<String, String>) {
    match map.get("test") {
        None => { /* Do nothing */ }
        Some(string) => do_someth(map, string),
    }
}

fn do_someth(map: &mut HashMap<String, String>, val: &str) {
    // Do something that alters map
}

I get the following compiler error:

error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
  --> src/main.rs:11:35
   |
9  |     match map.get("test") {
   |           --- immutable borrow occurs here
10 |         None => { /* Do nothing */ }
11 |         Some(string) => do_someth(map, string),
   |                                   ^^^ mutable borrow occurs here
12 |     }
   |     - immutable borrow ends here

Is there a general Rust-friendly work-around for this use case?

  • Check something on an object
  • If condition is verified, alter the object

The above is just a simple example using a HashMap.

Case by case, I seem to always find a convoluted solution, however I am not used yet to the way of thinking necessary to master Rust.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Olivier
  • 773
  • 9
  • 14
  • Maybe not exactly the same. In my case, I want the update logic to alter the original map, not a specific value inside the map. Moreover, the problem I am facing can happen with any mutable object, not only with a HashMap. I just took a HashMap as a simple example. – Olivier Jan 07 '18 at 14:56
  • 2
    Your problem isn't really just checking, then modifying based on the result. The function `do_someth()` you defined is fundamentally impossible to call in the way you intend to, since it expects both a mutable reference to the hash map and an immutable reference to one of the strings owned by the hash map. In Rust you can't have both at the same time. That said, you may want to take a look at [this example](https://github.com/nikomatsakis/nll-rfc/blob/master/0000-nonlexical-lifetimes.md#problem-case-2-conditional-control-flow) and the following one in the NLL RFC. – Sven Marnach Jan 07 '18 at 15:23
  • Building on what @SvenMarnach said, if you modify the `HashMap` while you have a reference into the `HashMap`, the reference might be invalidated. Accessing the string would then lead to memory unsafety (crashes, code execution, etc.) You have to clone the value to disassociate it from the `HashMap` before modifying it. [The duplicate applied to your situtation](https://play.rust-lang.org/?gist=42ba09656e7db6387ae4b9124bd37ed5&version=stable). – Shepmaster Jan 07 '18 at 16:10
  • Thank you all. The article that Sven shared was extremely helpful. – Olivier Jan 16 '18 at 06:37

0 Answers0