Rust's Borrow Checker Is My Strict Aunt

· 3 min read · Syed Omar Faruk Towaha
Rust's Borrow Checker Is My Strict Aunt

Every Bangladeshi family has one: the aunt who checks your collar, your homework and your posture before you're allowed out the door. She's not cruel. She simply refuses to let you embarrass yourself in public.

Rust's borrow checker is that aunt, living inside your compiler.

The three house rules

Rust's ownership model boils down to three rules:

  1. Every value has exactly one owner.
  2. When the owner goes out of scope, the value is dropped (freed).
  3. You can have either many read-only references or one mutable reference, never both at the same time.

That third rule is where most arguments with aunty happen.

fn main() {
    let mut list = vec![1, 2, 3];
    let first = &list[0];   // read-only borrow
    list.push(4);           // try to modify while someone is looking
    println!("{first}");
}
The compiler says no
Rust refuses to compile this, and for a very good reason.

Why is this illegal? Because push might need more space and move the whole vector to a new place in memory. Then first would point at memory that no longer belongs to the list. In C or C++, this compiles happily and fails weeks later, in production, on a customer's machine, in a way that only reproduces during a full moon. Rust just refuses up front.

The fix is usually boring

fn main() {
    let mut list = vec![1, 2, 3];
    list.push(4);
    let first = &list[0];   // borrow after the change
    println!("{first}");
}

Do the mutation, then take the reference. Or copy the value (let first = list[0];) because integers are cheap. Most borrow checker fights end with a small reordering, not a rewrite.

Moves: when aunty takes your toy

let name = String::from("Syed");
let greeting = name;      // ownership moves to greeting
println!("{name}");       // error: value borrowed after move

String owns heap memory, so assigning it moves ownership. The old variable is now empty-handed. If you really want two copies, ask for one explicitly with .clone(). Rust makes expensive things visible, which is very aunty-coded of it.

Why put up with her

Because the payoff is huge. A whole category of bugs, including use-after-free, double free and data races between threads, simply can't happen in safe Rust. Not "rarely happens." Can't. Large engineering organisations have reported that memory-safety issues make up a big share of their serious security bugs, which is exactly why Rust keeps showing up in browsers, operating systems and cloud infrastructure.

Tips for living with her

The first week with Rust feels like being nagged. Somewhere around week three, you notice you've stopped writing a certain kind of bug in every language. That's aunty's real gift. She doesn't just keep you safe; she changes how you think.

// related

// prefer the terminal?

Open the terminal blog and type read rust-borrow-checker-strict-aunt.