Understanding the Borrow Checker

A Mental Model

The Rust borrow checker prevents memory safety issues by enforcing strict rules on how references to data can be shared or modified simultaneously.

The Rust borrow checker enforces memory safety by ensuring that at any given time, you have either one mutable reference or any number of immutable references to a value, but never both. This prevents data races and use-after-free errors at compile time without needing a garbage collector.

let mut s = String::from("hello");
let r1 = &s; // Immutable borrow
let r2 = &s; // Immutable borrow allowed
// let r3 = &mut s; // ERROR: Cannot borrow `s` as mutable while it is also borrowed as immutable
println!("{r1}, {r2}"); // Borrow ends here
let r3 = &mut s; // Mutable borrow now allowed
r3.push_str(", world");

The borrow checker tracks the lifetime of references to ensure they do not outlive the data they point to and that mutable and immutable borrows do not overlap.