Under The Hood
backend rust Rust 1.75+ (edition 2021)

Rust borrow checker and lifetimes

Last updated
Prerequisites:
Rust ownership basics
Understanding of references and generics
  • rust
  • borrow-checker
  • lifetimes
  • ownership
  • memory-safety
  • miri

Read at your depth

The practical view

Every value in Rust has an owner; when the owner goes out of scope, the value is dropped. References let code use a value without taking ownership: &T (shared borrow, many readers) and &mut T (exclusive borrow, one writer). The borrow checker enforces: you cannot have a &mut T while any &T is live, and references must not outlive their referent. Lifetimes (usually elided: fn first<'a>(x: &'a str, y: &'a str) -> &'a str) tell the compiler how long a reference is valid — 'a is the intersection of the inputs' lifetimes. The compiler proves these rules at compile time, so most memory bugs become compile errors.

Legacy vs modern

Invalidating a borrow vs the borrow-checked version

The unsafe/mutable-alias pattern corrupts memory; Rust rejects it at compile time, forcing the shared-ownership design that is safe.

before → after
Aliasing mutation (invalid in Rust)
let mut v = vec![1, 2, 3];
let first = &v[0];       // shared borrow
v.push(4);               // ERROR: cannot borrow v as mutable
println!("{first}");      //   while `first` is still live
Index-based / scoped design
let len = v.len();
let first = v[0];  // copy the value out, no borrow held
v.push(4);         // fine: no outstanding borrow
println!("{first}");

Interview gotchas

Under The Hood — a multi-depth technical interview hub.

Press ⌘ K to search.