:#/ GSLF Journal
← :#/ GSLF Journal

Rustlers Atom 2.4: The Borrow Checker Rules

On this page

<figure class="video" style="margin:0;">
<div style="position:relative;width:100%;padding-bottom:56.25%;height:0;overflow:hidden;">
<iframe src="https://www.youtube.com/embed/Vq8Z2MDEJu0?si=pStaxvaX7D--x0WY"
title="YouTube video player"
style="position:absolute;top:0;left:0;width:100%;height:100%;border:0;"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen></iframe>
</div>
</figure>

The Borrow Checker is the part of the compiler that enforces memory safety without a garbage collector. These rules are non-negotiable. They prevent data races—the situation where two pointers access the same memory, at least one is writing, and there is no synchronization.

The Two Laws of Borrowing#

RULE 1 - The Validity Rule
References must always be valid. You cannot have a reference pointing to memory that has been freed (dangling pointer).

// Valid reference
let x = 10;
let r = &x; // valid: x is still alive here
println!("{}", r); // ok


// Invalid reference
let r;
{
    let x = 10;
    r = &x; // ❌ x goes out of scope at the end of this block
}            // r now points to freed memory — invalid!
println!("{}", r); // ❌ ERROR: r would be a dangling reference

RULE 2 - The Aliasing X Mutability Rule
At any given time, you can have either (but not both):

  • One mutable reference (&mut T).
  • Any number of immutable references (&T).
// Many immutable references
let value = 42;

let a = &value;
let b = &value;
let c = &value; // any number of immutable references is allowed

println!("{}, {}, {}", a, b, c);

// One mutable reference, no others
let mut value = 42;

let r = &mut value; // the only active reference
*r += 1;

println!("{}", r);

// Invalid
let mut value = 42;

let r1 = &value;      // immutable borrow
let r2 = &mut value;  // ❌ cannot borrow as mutable while immutable borrows exist

println!("{}, {}", r1, r2);

Why strictly one writer?#

If you have a &mut T, you are guaranteed strict exclusivity. No one else is reading; no one else is writing. This means you can safely change data structures (like resizing a Vector) without worrying that another pointer is looking at the old memory address. In C, everything is permitted, leading to a segfault or security vulnerability. Rust catches this bug before it runs.