Rust — E0499 cannot borrow as mutable more than once at a time
Fix E0499 by scoping mutable borrows, using reborrowing, or restructuring to hold one mutable reference.
Symptoms
- error[E0499]: cannot borrow `x` as mutable more than once at a time
- Two mutable borrows of the same value overlap
- A loop holds a mutable reference while taking another
- A method returning a reference extends the borrow
Possible causes
- A second mutable borrow begins while the first is still live
- A mutable reference is stored while the code needs another
- A method signature returns &mut self extending the borrow
- An iterator holds a mutable borrow across other mutations
Diagnosis steps
Read where each mutable borrow starts
cargo build 2>&1 | head -30Interpretation
The compiler shows both borrow sites and their live ranges, revealing the overlap.
Scope the first borrow
{ let a = &mut x; a.update(); } let b = &mut x;Interpretation
Ending the first borrow in a block lets the second take ownership of mutability.
Use reborrowing implicitly
fn f(x: &mut T); f(&mut *y);Interpretation
Passing a mutable reference to a function reborrows rather than moving, if the signature accepts a shorter lifetime.
Root cause
Two mutable references to the same value were live at the same time, which the borrow checker forbids because mutable aliasing would allow data races or inconsistent state.
Fix
End one mutable borrow before starting another by scoping it, restructure so only one mutable reference is held at a time, or use interior mutability when shared mutation is genuinely required.
Verify the fix
Rebuild and confirm the error is gone, then run tests to confirm the mutations occur in the intended order.
Symptom walkthrough
The compiler reports E0499, complaining that a value cannot be borrowed as mutable more than once at a time. Two mutable references are live together, which rust forbids because mutable aliasing undermines memory safety. It frequently appears when a loop or method holds a mutable borrow while the code tries to take another, or when a method that returns &mut self keeps the borrow alive.
Fix in practice
Scope each mutable borrow so it ends before the next begins, restructure to hold a single mutable reference at a time, or, when shared mutation is unavoidable, use interior mutability such as RefCell or a lock with clear discipline. Choose the option that keeps the borrows disjoint rather than fighting the checker.
Verification
Rebuild and confirm the error is gone, then run the tests and confirm the mutations happen in the intended order. The right behavior confirms the restructure is correct, not merely compilable.
Diagnostic commands
Check the behavior with commands like these:
cargo build 2>&1 | head -30
{ let a = &mut x; a.update(); } let b = &mut x;
fn f(x: &mut T); f(&mut *y);