Compile-time enforcement of the fundamental law of systems safety: multiple immutable readers OR exactly one mutable writer.
fn main() {
let mut data = vec![1, 2, 3];
let r1 = &data; // Shared reference (Reader 1)
let r2 = &data; // Shared reference (Reader 2)
println!("Readers: {:?}, {:?}", r1, r2);
// After r1 and r2 are no longer used (NLL):
let w = &mut data; // Exclusive mutable reference (Writer)
w.push(4);
println!("Updated: {:?}", w);
}The Borrow Checker enforces the 'Aliasing XOR Mutability' theorem at compile time, eliminating data races, iterator invalidation, and pointer corruption without runtime overhead.
When a shared reference `&T` is active, the underlying target is frozen in place: neither the owner nor any other reference can mutate or move it.
When a mutable reference `&mut T` is created, it asserts exclusive access. The original variable cannot be read or written directly until the mutable borrow expires.
Thanks to Non-Lexical Lifetimes (NLL), a borrow ends at its last line of actual use rather than the end of the enclosing curly-brace block.
In C++ or JavaScript, pushing into a vector while looping over it can reallocate the backing buffer, causing undefined behavior or stale pointers. Rust catches this at compile time.
let mut vec = vec![1, 2, 3];
for item in &vec { // &vec borrows immutable
// vec.push(10); // COMPILE ERROR: cannot borrow `vec` as mutable
}Violating the Aliasing XOR Mutability theorem by holding a read reference while attempting to mutate the underlying data.
Attempting to create two overlapping mutable references to the same memory location.