Theme
Q026. In what order are local variables and struct fields dropped?
Short Answer
Local variables in the same scope are dropped in reverse declaration order, and nested scopes are destroyed from the inside out. Struct fields are dropped in declaration order after the struct's own Drop::drop returns. Tuple fields and array elements are dropped from first to last. Only the active enum variant's fields are dropped.
Deep Dive
Rust guarantees several distinct ordering rules:
- locals are dropped in reverse order of declaration;
- temporaries in the same drop scope are generally dropped in reverse creation order;
- struct fields are dropped in declaration order;
- tuple fields are dropped from first to last;
- array and owned-slice elements are dropped from first to last;
- fields of the active enum variant are dropped in declaration order;
- values captured by a closure by value have unspecified drop order.
Shadowed bindings are separate locals, so the later binding is dropped before the earlier one when they share a drop scope. Reordering struct fields is usually safer than using ManuallyDrop solely to control destruction order.
Internal Model
Drop elaboration expands destruction into an ordered sequence of drop glue calls. If a type has custom Drop, that method runs first while all fields are still valid; generated glue then destroys fields in their guaranteed order.
Partially moved aggregates skip fields that are no longer initialized while preserving the relative order of remaining field drops.
Example
rust
struct Trace(&'static str);
impl Drop for Trace {
fn drop(&mut self) {
println!("{}", self.0);
}
}
struct Pair {
_first: Trace,
_second: Trace,
}
fn main() {
let _early = Trace("local: early");
let _pair = Pair {
_first: Trace("field: first"),
_second: Trace("field: second"),
};
let _late = Trace("local: late");
}Common Mistakes
- Applying reverse local-variable order to struct fields.
- Assuming closure captures have a guaranteed field-like drop order.
- Forgetting that custom
Drop::dropruns before automatic field destruction.
Follow-ups
- What output does the example produce?
- How does partial initialization affect field drop order?
- When can destruction order matter for soundness or resource dependencies?
Related
- Q015. How do reassignment and shadowing differ from a move?
- Q016. What is a partial move?
- Q024. How are ownership,
Drop, and RAII related?
References
- Rust Reference
- Rust Standard Library