Ownership
One owner per value: the rule that deletes the garbage collector.
Every value has exactly one owner. Assigning a non-Copy value moves it: the old name is no longer valid. This is how Rust frees memory with no garbage collector and no double-frees.
Run it, then uncomment the println!("{s1}") line and watch the compiler stop you.
The error you just produced, E0382, is the most famous message in Rust. It is not the compiler being difficult; it is a whole class of memory bugs refusing to exist, surfaced at compile time instead of in production.
Here is the same mistake with the training wheels off, beside exactly what rustc says about it. This error text is captured from the real compiler and re-verified against every new stable release; if rustc ever changes its wording, this page fails the build instead of lying to you.
fn main() {
let s1 = String::from("owned");
let s2 = s1; // s1 is MOVED into s2
println!("{s1}"); // s1 is gone; the compiler stops you here
println!("{s2}");
}
error[E0382]: borrow of moved value: `s1`
--> main.rs:5:16
|
3 | let s1 = String::from("owned");
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
4 | let s2 = s1; // s1 is MOVED into s2
| -- value moved here
5 | println!("{s1}"); // s1 is gone; the compiler stops you here
| ^^ value borrowed here after move
|
help: consider cloning the value if the performance cost is acceptable
|
4 | let s2 = s1.clone(); // s1 is MOVED into s2
| ++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0382`.
If you write `let v = vec![1, 2, 3]; let w = v;`, what happens to `v` after the second line?
What does Rust gain by enforcing exactly one owner per value?