error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
Rustβs borrow checker prevents you from having mutable and immutable references at the same time.
Why this happens
Rust enforces memory safety at compile time through its ownership system. You can have either one mutable reference or any number of immutable references, but not both simultaneously. This prevents data races and iterator invalidation. The compiler tracks borrow lifetimes and rejects code where a mutable and immutable borrow overlap.
Fix 1: Limit the scope of borrows
let mut data = vec![1, 2, 3];
// β Immutable borrow lives too long
let first = &data[0];
data.push(4); // Error! Can't mutate while borrowed
println!("{}", first);
// β
Use the immutable borrow before mutating
let first = &data[0];
println!("{}", first); // Done with immutable borrow
data.push(4); // Now OK
Fix 2: Clone the data
let mut data = vec![1, 2, 3];
let first = data[0].clone(); // Own the value
data.push(4); // Fine β no borrow conflict
println!("{}", first);
Fix 3: Use interior mutability
use std::cell::RefCell;
let data = RefCell::new(vec![1, 2, 3]);
data.borrow_mut().push(4);
Alternative solution: Split borrows on different fields
The borrow checker tracks struct fields independently:
struct State { items: Vec<i32>, count: usize }
let mut state = State { items: vec![1, 2], count: 0 };
// Borrowing different fields is fine
state.count = state.items.len();
Prevention
- Design functions to take ownership or return new values instead of requiring simultaneous mutable and immutable access.
- Use
cargo clippyregularly β it suggests idiomatic patterns that avoid borrow conflicts.
Related: Rust cheat sheet Β· Rust: Expected Type X, Found Y β How to Fix It Β· Rust: Value Used After Move β How to Fix It