Skip to content
Select theme

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.

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 here
4 | let b = &mut scores;
| ^^^^^^^^^^^ second mutable borrow occurs here
5 | 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:

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:

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:

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:

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.

Two neighbours that look similar but carry different codes:

  • Holding a shared borrow alive while calling a &mut method — a read that overlaps the write — is E0502, and its message says while it is borrowed as immutable.
  • Not declaring the binding mut at all is E0596 (cannot borrow as mutable, as it is not declared as mutable). There the problem is the declaration, not a second borrow.