Theme
Q015. How do reassignment and shadowing differ from a move?
Short Answer
A move transfers an existing value and makes its source unavailable. Reassignment writes a new value into the same mutable place and drops the old value if that place was initialized. Shadowing introduces a distinct binding with the same name; it can change the type and does not by itself immediately drop the previous binding.
Deep Dive
The three operations affect program state differently:
- move: the destination is initialized from the source, and the source becomes moved from;
- reassignment: an existing place receives a new value, and its previous initialized value is dropped;
- shadowing: a new
letbinding is created and hides the old name for subsequent source code.
Shadowing does not mutate the old binding. The hidden value normally remains alive until its own drop scope ends. Reinitializing a moved-from mutable binding is a special reassignment case where there is no old value left to drop in that place.
Internal Model
Move analysis changes initialization state between places. Assignment targets an existing place and emits destruction for its old value when required. Shadowing creates a separate local in the compiler's intermediate representation, even though both locals use the same source-level name.
Optimization may reuse physical storage, but it must preserve observable drop behavior.
Example
rust
fn main() {
let original = String::from("move");
let moved = original;
let mut reassigned = String::from("old");
println!("before: {reassigned}");
reassigned = String::from("new");
let shadowed = String::from("text");
let shadowed = shadowed.len();
println!("{moved} {reassigned} {shadowed}");
}Common Mistakes
- Calling every
let name = ...with a repeated name a reassignment. - Assuming shadowing immediately destroys the hidden value.
- Assuming reassignment and reinitialization always drop an old value.
Follow-ups
- What is the drop order of shadowed bindings?
- Why can shadowing change a variable's type?
- What happens when the right-hand side of an assignment uses the old value?
Related
- Q010. How does ownership determine a value's lifetime?
- Q013. What happens to the source binding after a move?
- Q014. Can a moved binding be reinitialized?
References
- The Rust Programming Language
- Rust Reference