Lesson 9 / 25
The Aliasing Rule
Many readers or one writer.
Shared XOR mutable
At any time you can have either any number of shared references or exactly one mutable reference to a value, not both. This rule prevents data races and iterator invalidation: pushing to a Vec may reallocate its buffer, which would leave an existing reference to an element dangling. The borrow checker tracks how long each borrow is used (non-lexical lifetimes), so a borrow ends after its last use, not at the end of the block.
Pushing while an element is borrowed, compile error
I compiled this with Rust 1.99.0 (cargo build); it is meant to fail. The output is trimmed to the error lines. Holding a reference to the first score and then pushing (which could reallocate the vector) is rejected with E0502: cannot borrow as mutable because it is also borrowed as immutable.
fn main() {
let mut scores = vec![90, 75, 60];
let first = &scores[0]; // shared borrow
scores.push(100); // mutable borrow while `first` is still used
println!("first = {first}");
}
Output:
error[E0502]: cannot borrow `scores` as mutable because it is also borrowed as immutable --> src/main.rs:4:5 error: could not compile `demo` (bin "demo") due to 1 previous error
Copy out small values
let first = scores[0]; (copying the i32) instead of a reference ends the borrow immediately.
Quick check: Which combination of references does Rust allow at the same time?
- One shared and one mutable
- Many mutable references
- Many shared references, or one mutable reference
- Unlimited references of any kind
Answer
Many shared references, or one mutable reference — Prevents data races at compile time.