-
Notifications
You must be signed in to change notification settings - Fork 533
Document destructors/drop. #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Destructors | ||
|
||
When an [initialized] [variable] in Rust goes out of scope or a [temporary] | ||
is no longer needed its _destructor_ is run. [Assignment] also runs the | ||
destructor of its left-hand operand, unless it's an unitialized variable. If a | ||
[struct] variable has been partially initialized, only its initialized fields | ||
are dropped. | ||
|
||
The destrutor of a type consists of | ||
|
||
1. Calling its [`std::ops::Drop::drop`] method, if it has one. | ||
2. Recursively running the destructor of all of its fields. | ||
* The fields of a [struct], [tuple] or [enum variant] are dropped in | ||
declaration order. \* | ||
* The elements of an [array] or owned [slice][array] are dropped from the | ||
first element to the last. \* | ||
* The captured values of a [closure] are dropped in an unspecified order. | ||
* [Trait objects] run the destructor of the underlying type. | ||
* Other types don't result in any further drops. | ||
|
||
\* This order was stabilized in [RFC 1857]. | ||
|
||
Variables are dropped in reverse order of declaration. Variables declared in | ||
the same pattern drop in an unspecified ordered. | ||
|
||
If a destructor must be run manually, such as when implementing your own smart | ||
pointer, [`std::ptr::drop_in_place`] can be used. | ||
|
||
Some examples: | ||
|
||
```rust | ||
struct ShowOnDrop(&'static str); | ||
|
||
impl Drop for ShowOnDrop { | ||
fn drop(&mut self) { | ||
println!("{}", self.0); | ||
} | ||
} | ||
|
||
{ | ||
let mut overwritten = ShowOnDrop("Drops when overwritten"); | ||
overwritten = ShowOnDrop("drops when scope ends"); | ||
} | ||
# println!(""); | ||
{ | ||
let declared_first = ShowOnDrop("Dropped last"); | ||
let declared_last = ShowOnDrop("Dropped first"); | ||
} | ||
# println!(""); | ||
{ | ||
// Tuple elements drop in forwards order | ||
let tuple = (ShowOnDrop("Tuple first"), ShowOnDrop("Tuple second")); | ||
} | ||
# println!(""); | ||
loop { | ||
// Tuple expression doesn't finish evaluating so temporaries drop in reverse order: | ||
let partial_tuple = (ShowOnDrop("Temp first"), ShowOnDrop("Temp second"), break); | ||
} | ||
# println!(""); | ||
{ | ||
let moved; | ||
// No destructor run on assignment. | ||
moved = ShowOnDrop("Drops when moved"); | ||
// drops now, but is then uninitialized | ||
moved; | ||
let uninitialized: ShowOnDrop; | ||
// Only first element drops | ||
let mut partially_initialized: (ShowOnDrop, ShowOnDrop); | ||
partially_initialized.0 = ShowOnDrop("Partial tuple first"); | ||
} | ||
``` | ||
|
||
## Not running destructors | ||
|
||
Not running destructors in Rust is safe even if it has a type that isn't | ||
`'static`. [`std::mem::ManuallyDrop`] provides a wrapper to prevent a | ||
variable or field from being dropped automatically. | ||
|
||
[initialized]: glossary.html#initialized | ||
[variable]: variables.html | ||
[temporary]: expressions.html#temporary-lifetimes | ||
[Assignment]: expressions/operator-expr.html#assignment-expressions | ||
[`std::ops::Drop::drop`]: ../std/ops/trait.Drop.html | ||
[RFC 1857]: https://github.com/rust-lang/rfcs/blob/master/text/1857-stabilize-drop-order.md | ||
[struct]: types.html#struct | ||
[tuple]: types.html#tuple-types | ||
[enum variant]: types.html#enumeration-types | ||
[array]: types.html#array-and-slice-types | ||
[closure]: types.html#closure-types | ||
[Trait objects]: types.html#trait-objects | ||
[`std::ptr::drop_in_place`]: ../std/ptr/fn.drop_in_place.html | ||
[`std::mem::forget`]: ../std/mem/fn.forget.html | ||
[`std::mem::ManuallyDrop`]: ../std/mem/union.ManuallyDrop.html |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a part of
block expressions
, but I'm not going to worry about that for this PR.