The Borrow Checker
The borrow checker tracks which bindings own data and which references borrow it. It rejects programs that could cause use-after-free, double-free, or data races.
Busca en todas las páginas de la documentación
The borrow checker tracks which bindings own data and which references borrow it. It rejects programs that could cause use-after-free, double-free, or data races.
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() >= b.len() { a } else { b }
}
fn main() {
let s1 = String::from("longer");
let len = {
let s2 = String::from("x");
longest(&s1, &s2)
};
println!("{len}");
}When to reach for this: Understanding compile errors about "borrowed value does not live long enough" or "cannot borrow as mutable".
struct Cache { data: Vec<String> }
impl Cache {
fn get_or_insert(&mut self, key: &str) -> &String {
for s in &self.data {
if s == key { return s; }
}
self.data.push(key.to_string());
self.data.last().unwrap()
}
}
fn main() {
let mut c = Cache { data: vec![] };
let v = c.get_or_insert("a");
println!("{v}");
}What this demonstrates:
&String from &mut self extends borrow of selfc while v borrows from it| Error message | Typical cause |
|---|---|
| value borrowed after move | Used binding after transfer |
| cannot borrow as mutable | Active shared borrow exists |
| does not live long enough | Returned ref outlives owner |
&mut across method call | Overlapping loans in struct methods |
{ }unsafe or transmute - Hides real design issue. Fix: Safe refactor first.String/Arc or indices.&mut while mutating collection - Second borrow fails. Fix: Separate passes or indices.| Alternative | Use When | Don't Use When |
|---|---|---|
Return owned T | Callers need independent data | Zero-copy sharing required |
| Indices into arena | Stable handles without refs | Simple tree with parent refs |
Rc<RefCell<T>> | Shared graph in one thread | Performance-critical hot path |
| Arena allocator | Many short-lived tied refs | Long-lived unrelated objects |
No. It runs at compile time only. Zero runtime cost for borrow rules.
Rust prints full causality chains. Focus on the first error and highlighted spans.
Sometimes APIs feel hard to express. Patterns like split_at_mut and lifetimes exist to model safe use.
No. Only memory safety and thread safety (with Send/Sync). Use tests for logic.
Mutable borrow of struct field may be split across autoref steps in method calls. Errors can be subtle.
Experimental analysis improving some error cases. Stable rustc uses NLL-based checker.
Only with unsafe Rust inside an unsafe block for raw pointers - not for normal references.
Lifetime parameters connect input and output borrows so callers cannot misuse returned refs.
Cell moves Copy values in/out at runtime. RefCell enforces borrow rules dynamically with panics.
rustc --explain E0499 (and related codes), rust-analyzer inlay hints, and Miri for unsafe.
'aStack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 16 jul 2026