drop.rs - source
Description: Source of the Rust file `library/core/src/ops/drop.rs`.

#
core/ops/
drop.rs

    1/// Custom code within the destructor.
    2///
    3/// When a value is no longer needed, Rust will run a "destructor" on that value.
    4/// The most common way that a value is no longer needed is when it goes out of
    5/// scope. Destructors may still run in other circumstances, but we're going to
    6/// focus on scope for the examples here. To learn about some of those other cases,
    7/// please see [the reference] section on destructors.
    8///
    9/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
    10///
    11/// This destructor consists of two components:
    12/// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
    13/// - The automatically generated "drop glue" which recursively calls the destructors
    14///   of all the fields of this value.
    15///
    16/// As Rust automatically calls the destructors of all contained fields,
    17/// you don't have to implement `Drop` in most cases. But there are some cases where
    18/// it is useful, for example for types which directly manage a resource.
    19/// That resource may be memory, it may be a file descriptor, it may be a network socket.
    20/// Once a value of that type is no longer going to be used, it should "clean up" its
    21/// resource by freeing the memory or closing the file or socket. This is
    22/// the job of a destructor, and therefore the job of `Drop::drop`.
    23///
    24/// ## Examples
    25///
    26/// To see destructors in action, let's take a look at the following program:
    27///
    28/// ```rust
    29/// struct HasDrop;
    30///
    31/// impl Drop for HasDrop {
    32///     fn drop(&mut self) {
    33///         println!("Dropping HasDrop!");
    34///     }
    35/// }
    36///
    37/// struct HasTwoDrops {
    38///     one: HasDrop,
    39///     two: HasDrop,
    40/// }
    41///
    42/// impl Drop for HasTwoDrops {
    43///     fn drop(&mut self) {
    44///         println!("Dropping HasTwoDrops!");
    45///     }
    46/// }
    47///
    48/// fn main() {
    49///     let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
    50///     println!("Running!");
    51/// }
    52/// ```
    53///
    54/// Rust will first call `Drop::drop` for `_x` and then for both `_x.one` and `_x.two`,
    55/// meaning that running this will print
    56///
    57/// ```text
    58/// Running!
    59/// Dropping HasTwoDrops!
    60/// Dropping HasDrop!
    61/// Dropping HasDrop!
    62/// ```
    63///
    64/// Even if we remove the implementation of `Drop` for `HasTwoDrop`, the destructors of its fields are still called.
    65/// This would result in
    66///
    67/// ```test
    68/// Running!
    69/// Dropping HasDrop!
    70/// Dropping HasDrop!
    71/// ```
    72///
    73/// ## You cannot call `Drop::drop` yourself
    74///
    75/// Because `Drop::drop` is used to clean up a value, it may be dangerous to use this value after
    76/// the method has been called. As `Drop::drop` does not take ownership of its input,
    77/// Rust prevents misuse by not allowing you to call `Drop::drop` directly.
    78///
    79/// In other words, if you tried to explicitly call `Drop::drop` in the above example, you'd get a compiler error.
    80///
    81/// If you'd like to explicitly call the destructor of a value, [`mem::drop`] can be used instead.
    82///
    83/// [`mem::drop`]: drop
    84///
    85/// ## Drop order
    86///
    87/// Which of our two `HasDrop` drops first, though? For structs, it's the same
    88/// order that they're declared: first `one`, then `two`. If you'd like to try
    89/// this yourself, you can modify `HasDrop` above to contain some data, like an
    90/// integer, and then use it in the `println!` inside of `Drop`. This behavior is
    91/// guaranteed by the language.
    92///
    93/// Unlike for structs, local variables are dropped in reverse order:
    94///
    95/// ```rust
    96/// struct Foo;
    97///
    98/// impl Drop for Foo {
    99///     fn drop(&mut self) {
    100///         println!("Dropping Foo!")
    101///     }
    102/// }
    103///
    104/// struct Bar;
    105///
    106/// impl Drop for Bar {
    107///     fn drop(&mut self) {
    108///         println!("Dropping Bar!")
    109///     }
    110/// }
    111///
    112/// fn main() {
    113///     let _foo = Foo;
    114///     let _bar = Bar;
    115/// }
    116/// ```
    117///
    118/// This will print
    119///
    120/// ```text
    121/// Dropping Bar!
    122/// Dropping Foo!
    123/// ```
    124///
    125/// Please see [the reference] for the full rules.
    126///
    127/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
    128///
    129/// ## `Copy` and `Drop` are exclusive
    130///
    131/// You cannot implement both [`Copy`] and `Drop` on the same type. Types that
    132/// are `Copy` get implicitly duplicated by the compiler, making it very
    133/// hard to predict when, and how often destructors will be executed. As such,
    134/// these types cannot have destructors.
    135///
    136/// ## Drop check
    137///
    138/// Dropping interacts with the borrow checker in subtle ways: when a type `T` is being implicitly
    139/// dropped as some variable of this type goes out of scope, the borrow checker needs to ensure that
    140/// calling `T`'s destructor at this moment is safe. In particular, it also needs to be safe to
    141/// recursively drop all the fields of `T`. For example, it is crucial that code like the following
    142/// is being rejected:
    143///
    144/// ```compile_fail,E0597
    145/// use std::cell::Cell;
    146///
    147/// struct S<'a>(Cell<Option<&'a S<'a>>>, Box<i32>);
    148/// impl Drop for S<'_> {
    149///     fn drop(&mut self) {
    150///         if let Some(r) = self.0.get() {
    151///             // Print the contents of the `Box` in `r`.
    152///             println!("{}", r.1);
    153///         }
    154///     }
    155/// }
    156///
    157/// fn main() {
    158///     // Set up two `S` that point to each other.
    159///     let s1 = S(Cell::new(None), Box::new(42));
    160///     let s2 = S(Cell::new(Some(&s1)), Box::new(42));
    161///     s1.0.set(Some(&s2));
    162///     // Now they both get dropped. But whichever is the 2nd one
    163///     // to be dropped will access the `Box` in the first one,
    164///     // which is a use-after-free!
    165/// }
    166/// ```
    167///
    168/// The Nomicon discusses the need for [drop check in more detail][drop check].
    169///
    170/// To reject such code, the "drop check" analysis determines which types and lifetimes need to
    171/// still be live when `T` gets dropped. The exact details of this analysis are not yet
    172/// stably guaranteed and **subject to change**. Currently, the analysis works as follows:
    173/// - If `T` has no drop glue, then trivially nothing is required to be live. This is the case if
    174///   neither `T` nor any of its (recursive) fields have a destructor (`impl Drop`). [`PhantomData`],
    175///   arrays of length 0 and [`ManuallyDrop`] are considered to never have a destructor, no matter
    176///   their field type.
    177/// - If `T` has drop glue, then, for all types `U` that are *owned* by any field of `T`,
    178///   recursively add the types and lifetimes that need to be live when `U` gets dropped. The set of
    179///   owned types is determined by recursively traversing `T`:
    180///   - Recursively descend through `PhantomData`, `Box`, tuples, and arrays (excluding arrays of
    181///     length 0).
    182///   - Stop at reference and raw pointer types as well as function pointers and function items;
    183///     they do not own anything.
    184///   - Stop at non-composite types (type parameters that remain generic in the current context and
    185///     base types such as integers and `bool`); these types are owned.
    186///   - When hitting an ADT with `impl Drop`, stop there; this type is owned.
    187///   - When hitting an ADT without `impl Drop`, recursively descend to its fields. (For an `enum`,
    188///     consider all fields of all variants.)
    189/// - Furthermore, if `T` implements `Drop`, then all generic (lifetime and type) parameters of `T`
    190///   must be live.
    191///
    192/// In the above example, the last clause implies that `'a` must be live when `S<'a>` is dropped,
    193/// and hence the example is rejected. If we remove the `impl Drop`, the liveness requirement
    194/// disappears and the example is accepted.
    195///
    196/// There exists an unstable way for a type to opt-out of the last clause; this is called "drop
    197/// check eyepatch" or `may_dangle`. For more details on this nightly-only feature, see the
    198/// [discussion in the Nomicon][nomicon].
    199///
    200/// [`ManuallyDrop`]: crate::mem::ManuallyDrop
    201/// [`PhantomData`]: crate::marker::PhantomData
    202/// [drop check]: ../../nomicon/dropck.html
    203/// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle
    204#[lang = "drop"]
    205#[stable(feature = "rust1", since = "1.0.0")]
    206#[rustc_const_unstable(feature = "const_destruct", issue = "133214")]
    207pub const trait Drop {
    208    /// Executes the destructor for this type.
    209    ///
    210    /// This method is called implicitly when the value goes out of scope,
    211    /// and cannot be called explicitly (this is compiler error [E0040]).
    212    /// However, the [`mem::drop`] function in the prelude can be
    213    /// used to call the argument's `Drop` implementation.
    214    ///
    215    /// When this method has been called, `self` has not yet been deallocated.
    216    /// That only happens after the method is over.
    217    /// If this wasn't the case, `self` would be a dangling reference.
    218    ///
    219    /// # Panics
    220    ///
    221    /// Implementations should generally avoid [`panic!`]ing, because `drop()` may itself be called
    222    /// during unwinding due to a panic, and if the `drop()` panics in that situation (a “double
    223    /// panic”), this will likely abort the program. It is possible to check [`panicking()`] first,
    224    /// which may be desirable for a `Drop` implementation that is reporting a bug of the kind
    225    /// “you didn't finish using this before it was dropped”; but most types should simply clean up
    226    /// their owned allocations or other resources and return normally from `drop()`, regardless of
    227    /// what state they are in.
    228    ///
    229    /// Note that even if this panics, the value is considered to be dropped;
    230    /// you must not cause `drop` to be called again. This is normally automatically
    231    /// handled by the compiler, but when using unsafe code, can sometimes occur
    232    /// unintentionally, particularly when using [`ptr::drop_in_place`].
    233    ///
    234    /// [E0040]: ../../error_codes/E0040.html
    235    /// [`panic!`]: crate::panic!
    236    /// [`panicking()`]: ../../std/thread/fn.panicking.html
    237    /// [`mem::drop`]: drop
    238    /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
    239    #[stable(feature = "rust1", since = "1.0.0")]
    240    fn drop(&mut self);
    241}