Skip to content

/errors/rust/e0502-cannot-borrow-as-mutable-because-also-borrowed-as-immutable

Rust error[E0502]: cannot borrow as mutable because it is also borrowed as immutable

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · rustc 1.98.1 (48a229cea 2026-09-01)updated
tool
Rust
exit code
1
versions
Rust 1.x (2018, 2021 and 2024 editions)
os
any

error[E0502]: cannot borrow X as mutable because it is also borrowed as immutable means a shared reference to a value is still alive when the code asks for a mutable one. Rust allows either many & references or one &mut at a time. The usual case: you hold a reference into a Vec and then call push, which may reallocate and leave that reference dangling. Copy the value out, or finish using the reference before mutating.

Reproduce it

bash
cat > main.rs <<'EOF'
fn main() {
    let mut v = vec![1, 2, 3];
    let first = &v[0];
    v.push(4);
    println!("first = {first}");
}
EOF
rustc --edition 2021 main.rs

Output · exit 1

error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
 --> main.rs:4:5
  |
3 |     let first = &v[0];
  |                  - immutable borrow occurs here
4 |     v.push(4);
  |     ^^^^^^^^^ mutable borrow occurs here
5 |     println!("first = {first}");
  |                        ----- immutable borrow later used here

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0502`.

The compiler points at three places: where the immutable borrow starts (&v[0]), the mutable borrow (v.push), and the later use that keeps the first borrow alive (println!).

Fix: copy the value or reorder

bash
cat > main.rs <<'EOF'
fn main() {
    let mut v = vec![1, 2, 3];

    let first = v[0];            // i32 is Copy: no reference is kept
    v.push(4);
    println!("first = {first}");

    let last = &v[v.len() - 1];  // borrow, use it, then mutate
    println!("last = {last}");
    v.push(5);

    for i in 0..v.len() {        // mutate inside a loop through indices
        v[i] *= 10;
    }
    println!("{v:?}");
}
EOF
rustc --edition 2021 main.rs && ./main

Output

first = 1
last = 4
[10, 20, 30, 40, 50]

Since Rust 2018 (non-lexical lifetimes) a borrow ends at its last use, not at the end of the block, so moving the println! above the push is enough.

CodeMessageMeaning
E0499cannot borrow `x` as mutable more than once at a timeTwo &mut references alive at once
E0502cannot borrow `x` as mutable because it is also borrowed as immutableA & and a &mut alive at once
E0506cannot assign to `x` because it is borrowedAssignment while a reference exists
E0382borrow of moved valueUse after the value moved

Sources