Search code examples
rustborrow-checker

`&` reference, so the data it refers to cannot be borrowed as mutable


Here's the code I have:

pub struct Scope<'a> {
    pub parent: Option<Box<Scope<'a>>>,
    pub vars: HashMap<&'a str, Value>,
}

impl<'a> Scope<'a> {

    pub fn update(&mut self, name: &'a str, v: Value) -> Option<String> {
        if self.vars.contains_key(name) {
            self.vars.remove(name);
            self.vars.insert(name, v);
            None
        } else {
            if let Some(parent) = &self.parent {
                parent.update(name, v) // error here
            } else {
                Some(format!("{} is undefined", name))
            }
        }
    }
}

Here's the error message I got from the compiler:

error[E0596]: cannot borrow `**parent` as mutable, as it is behind a `&` reference
  --> src/interpreter/scope.rs:34:17
   |
34 |                 parent.update(name, v)
   |                 ^^^^^^^^^^^^^^^^^^^^^^ `parent` is a `&` reference, so the data it refers to cannot be borrowed as mutable

I changed let Some(parent) == &self.parent to let mut Some(parent) == &self.parent, but the compiler throws syntax errors. How can I fix this error?


Solution

  • By using & to borrow you take a shared reference, but you can't mutate anything behind a shared reference (except for things in an UnsafeCell but that doesn't matter here). To be able to mutate you have to take a mutable reference with &mut instead of &:

    if let Some(parent) = &mut self.parent {