Cannot borrow as immutable because it also borrowed as mutable

Viewed 324

I have the following minimal example to reproduce this issue:

fn main() {
    let mut vec = Vec::from(["Hello"]);
    let mut some_struct = SomeStruct { field: "World" };
    some_struct.doSomething(&mut vec);
    
    println!("{:?}", vec);
}

struct SomeStruct<'a> {
    field: &'a str
}

impl<'a> SomeStruct<'a> {
    fn doSomething(&mut self, vec: &'a mut Vec<&'a str>) {
        vec.push(self.field);
    }
}

(obviously, doSomething doesn't need to take a mutable reference to self in this example, but I do need a mutable reference in the original code)

When I run the above example, I get the following errror:

error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
  --> src/main.rs:22:22
   |
20 |     some_struct.doSomething(&mut vec);
   |                             -------- mutable borrow occurs here
21 |
22 |     println!("{:?}", vec);
   |                      ^^^
   |                      |
   |                      immutable borrow occurs here
   |                      mutable borrow later used here
   |
   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

How can I print out the vec after it being borrowed mutably by doSomething?

I've tried cloning vec, RefCell, but nothing seems to work.

1 Answers

The problem is the &'a mut Vec<...>. Repeating lifetimes is often wrong. In this case, you tell Rust "I want to borrow vec for 'a". But 'a is determined by self.field, and is inferred to be 'static here (or not; it doesn't really matter. The most important part is that it is inferred to be longer/equal to the lifetime of self, because otherwise self would hold a dangling reference). Now, by borrowing vec for 'a, you prevent use of it at least until self is destroyed.

If you remove the 'a lifetime from vec, it works:

fn doSomething(&mut self, vec: &mut Vec<&'a str>) {
    vec.push(self.field);
}
Related