Ownership & safety
·
v0.0.13
The borrow checker
The rule is one line: aliasing XOR mutability. At any point in the program, a place has either any number of shared borrows, or exactly one exclusive borrow, never both.
let mut v: vec::Vec[i32] = vec::new::[i32]();
v.push(1);
let n: usize = v.len(); // shared borrow — fine
let p: i32 = v.get(0); // shared borrow — fine
v.push(2); // exclusive — but no live shared borrow now; fine
Because shared borrows can read but not mutate, and the single exclusive borrow is the only one allowed to mutate, two threads or two code paths can never hold a writer and a reader of the same place at once. That is why data races do not compile.
The common diagnostics
- E0372: move out of a borrowed value.
- E0383: read while exclusively borrowed.
- E0370 family: overlapping incompatible borrows.
The fix is almost always a scope boundary
When two borrows conflict, the fix is usually to end one before the other begins, by introducing a scope so they do not co-exist:
{
let r: i32 = v.get(0);
println(r);
} // shared borrow ends here
v.push(99); // exclusive borrow now fine
The borrow checker reasons within a function boundary. For the full picture of what it enforces versus what it trusts you to uphold (views and raw pointers), see Ownership.
Next
Continue with error handling.