How to fix error E0499: cannot borrow as mutable more than once
Short answer: two &mut borrows of the same value were alive at the same time. A value can
have exactly one mutable borrow at a time. End the first borrow before the second one starts —
under modern Rust that usually just means reordering the code so each borrow is used and done —
or restructure so the borrows point at different memory.
The error
Section titled “The error”fn main() { let mut scores = vec![10, 20, 30]; let a = &mut scores; let b = &mut scores; a.push(40); b.push(50); println!("{a:?} {b:?}");}Compiling that with cargo build prints:
error[E0499]: cannot borrow `scores` as mutable more than once at a time --> src/main.rs:4:13 |3 | let a = &mut scores; | ----------- first mutable borrow occurs here4 | let b = &mut scores; | ^^^^^^^^^^^ second mutable borrow occurs here5 | a.push(40); | - first borrow later used here
For more information about this error, try `rustc --explain E0499`.a borrows scores mutably, and because a is used after b is created, the compiler treats
both borrows as alive at once. Rust does not allow that: two write handles to the same Vec
could disagree about the vector’s length, and one of them could hand out a reference to memory
the other just freed.
“More than once” means “more than once at a time”
Section titled ““More than once” means “more than once at a time””The error is not about the count of &mut expressions in the file. It is about how many are
alive simultaneously. This version has two mutable borrows too, and it compiles:
fn main() { let mut scores = vec![10, 20, 30]; let a = &mut scores; a.push(40); println!("{a:?}"); let b = &mut scores; b.push(50); println!("{b:?}");}This prints:
[10, 20, 30, 40][10, 20, 30, 40, 50]a’s borrow ends at its last use — the println! line — not at the end of the block. The
borrow checker reads the code flow, so b starting a fresh borrow afterwards is fine. This
rule (the borrow ends at last use, not at the closing brace) is called non-lexical lifetimes.
The fix: use one borrow up before starting the next
Section titled “The fix: use one borrow up before starting the next”The broken version at the top interleaved the creations of the two borrows and only then used
them. The fix is to use a while it is the only borrow, then let b take over:
fn main() { let mut scores = vec![10, 20, 30]; let a = &mut scores; a.push(40); let b = &mut scores; b.push(50); println!("{b:?}");}This prints [10, 20, 30, 40, 50]. If the two pieces of code feel like they belong in separate
blocks, braces make the boundary explicit:
fn main() { let mut scores = vec![10, 20, 30]; { let a = &mut scores; a.push(40); } // the borrow ends here let b = &mut scores; b.push(50); println!("{b:?}");}The braces are what non-lexical lifetimes do for you automatically: a borrow’s scope is from its creation to its last use. Reach for explicit braces when you want the end of a borrow to be visible in the source rather than inferred from use.
When you need two at once: split the borrow
Section titled “When you need two at once: split the borrow”Sometimes two mutable borrows really are needed at the same time. That is allowed as long as they point at different memory — for example, different fields of a struct:
struct Player { name: String, score: u32,}
fn main() { let mut p = Player { name: String::from("Ada"), score: 0, }; let name = &mut p.name; let score = &mut p.score; name.push_str(" Lovelace"); *score += 150; println!("{} scored {}", name, score);}This compiles and prints Ada Lovelace scored 150. p.name and p.score are separate
locations, so borrowing one mutably does not conflict with borrowing the other. The same idea
applies to slices: split_at_mut hands back two non-overlapping mutable halves of one slice,
which is how library code lets callers write to both halves without unsafety.
Not this error
Section titled “Not this error”Two neighbours that look similar but carry different codes:
- Holding a shared borrow alive while calling a
&mutmethod — a read that overlaps the write — is E0502, and its message says while it is borrowed as immutable. - Not declaring the binding
mutat all is E0596 (cannot borrow as mutable, as it is not declared as mutable). There the problem is the declaration, not a second borrow.
Related errors
Section titled “Related errors”- E0382 — borrow of moved value
- E0384 — cannot assign twice to immutable variable
E0502— cannot borrow as mutable while it is borrowed as immutable