Rust errors / Ownership and borrowing
Rust compiler error · checked with rustc 1.99.0
Rust error E0502: cannot borrow as mutable because it is also borrowed as immutable
What it meansYou are changing something while a shared reference to it is still in use. A shared & borrow promises the data will not change until that borrow ends.
What rustc prints
error[E0502]: cannot borrow `*a` as mutable because it is also borrowed as immutable
--> main.rs:4:5
|
3 | let y = &a; // a is borrowed as immutable.
| -- immutable borrow occurs here
4 | bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
| ^^^^^^ mutable borrow occurs here
5 | // as immutable
6 | println!("{}", y);
| - immutable borrow later used hereReal output of rustc 1.99.0 compiling the official example below (2021 edition). Your names and line numbers will differ; the first line is the part to match.
Why it happens
let first = &v[0]; v.push(1); println!("{first}"): push may reallocate, which would leavefirstdangling.- Iterating with
for x in &v(or.iter()) and modifyingvinside the loop. - Calling
map.get(..), keeping the result, then callingmap.insert(..).
How to fix it
1. Copy out what you need first
Clone or copy the value so the borrow ends before the mutation.
let first = v[0]; // i32 is Copy: no borrow kept
v.push(1);
println!("{first}");2. Collect changes, then apply
Read in one pass, write in a second.
let extra: Vec<_> = v.iter().filter(|x| **x > 2).map(|x| x * 10).collect();
v.extend(extra);3. Use the entry API for maps
One lookup that can insert, with no outstanding borrow.
*counts.entry(word).or_insert(0) += 1;4. Mutate by index
Indices are plain numbers, so they do not hold a borrow.
for i in 0..v.len() {
if v[i] > 2 { v[i] *= 10; }
}Other wordings of this error
cannot borrow as mutable because it is also borrowed as immutable, immutable borrow occurs here, mutable borrow occurs here, immutable borrow later used here
The compiler team's explanation
A variable already borrowed with a certain mutability (either mutable or immutable) was borrowed again with a different mutability.
Erroneous code example:
fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
let y = &a; // a is borrowed as immutable.
bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
// as immutable
println!("{}", y);
}
To fix this error, ensure that you don't have any other references to the variable before trying to access it with a different mutability:
fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
bar(a);
let y = &a; // ok!
println!("{}", y);
}
For more information on Rust's ownership system, take a look at the References & Borrowing section of the Book.
From rustc --explain E0502 (1.99.0), part of the Rust project, MIT or Apache-2.0. Official page.
Related errors
- E0382borrow of moved value
- E0499cannot borrow as mutable more than once at a time
- E0106missing lifetime specifier
- E0597does not live long enough
- E0500closure requires unique access to `*jon_snow` but it is already borrowed
- E0501cannot borrow `*a` as mutable because previous closure requires unique access
- E0503cannot use `value` because it was mutably borrowed
- E0505cannot move out of because it is borrowed
Up next
Often hit nextE0382: borrow of moved valueA related error from the same family.Read it next →Did this answer your question?