drop.rs.html -- source
Description: Source to the Rust file `src\libcore\ops\drop.rs`.
Keywords: rust, rustlang, rust-lang

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167

    /// Custom code within the destructor.
    ///
    /// When a value is no longer needed, Rust will run a "destructor" on that value.
    /// The most common way that a value is no longer needed is when it goes out of
    /// scope. Destructors may still run in other circumstances, but we're going to
    /// focus on scope for the examples here. To learn about some of those other cases,
    /// please see [the reference] section on destructors.
    ///
    /// [the reference]: https://doc.rust-lang.org/reference/destructors.html
    ///
    /// This destructor consists of two components:
    /// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
    /// - The automatically generated "drop glue" which recursively calls the destructors
    ///     of the all fields of this value.
    ///
    /// As Rust automatically calls the destructors of all contained fields,
    /// you don't have to implement `Drop` in most cases. But there are some cases where
    /// it is useful, for example for types which directly manage a resource.
    /// That resource may be memory, it may be a file descriptor, it may be a network socket.
    /// Once a value of that type is no longer going to be used, it should "clean up" its
    /// resource by freeing the memory or closing the file or socket. This is
    /// the job of a destructor, and therefore the job of `Drop::drop`.
    ///
    /// ## Examples
    ///
    /// To see destructors in action, let's take a look at the following program:
    ///
    /// ```rust
    /// struct HasDrop;
    ///
    /// impl Drop for HasDrop {
    ///     fn drop(&mut self) {
    ///         println!("Dropping HasDrop!");
    ///     }
    /// }
    ///
    /// struct HasTwoDrops {
    ///     one: HasDrop,
    ///     two: HasDrop,
    /// }
    ///
    /// impl Drop for HasTwoDrops {
    ///     fn drop(&mut self) {
    ///         println!("Dropping HasTwoDrops!");
    ///     }
    /// }
    ///
    /// fn main() {
    ///     let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
    ///     println!("Running!");
    /// }
    /// ```
    ///
    /// Rust will first call `Drop::drop` for `_x` and then for both `_x.one` and `_x.two`,
    /// meaning that running this will print
    ///
    /// ```text
    /// Running!
    /// Dropping HasTwoDrops!
    /// Dropping HasDrop!
    /// Dropping HasDrop!
    /// ```
    ///
    /// Even if we remove the implementation of `Drop` for `HasTwoDrop`, the destructors of its fields are still called.
    /// This would result in
    ///
    /// ```test
    /// Running!
    /// Dropping HasDrop!
    /// Dropping HasDrop!
    /// ```
    ///
    /// ## You cannot call `Drop::drop` yourself
    ///
    /// Because `Drop::drop` is used to clean up a value, it may be dangerous to use this value after
    /// the method has been called. As `Drop::drop` does not take ownership of its input,
    /// Rust prevents misuse by not allowing you to call `Drop::drop` directly.
    ///
    /// In other words, if you tried to explicitly call `Drop::drop` in the above example, you'd get a compiler error.
    ///
    /// If you'd like explicitly call the destructor of a value, [`std::mem::drop`] can be used instead.
    ///
    /// [`std::mem::drop`]: ../../std/mem/fn.drop.html
    ///
    /// ## Drop order
    ///
    /// Which of our two `HasDrop` drops first, though? For structs, it's the same
    /// order that they're declared: first `one`, then `two`. If you'd like to try
    /// this yourself, you can modify `HasDrop` above to contain some data, like an
    /// integer, and then use it in the `println!` inside of `Drop`. This behavior is
    /// guaranteed by the language.
    ///
    /// Unlike for structs, local variables are dropped in reverse order:
    ///
    /// ```rust
    /// struct Foo;
    ///
    /// impl Drop for Foo {
    ///     fn drop(&mut self) {
    ///         println!("Dropping Foo!")
    ///     }
    /// }
    ///
    /// struct Bar;
    ///
    /// impl Drop for Bar {
    ///     fn drop(&mut self) {
    ///         println!("Dropping Bar!")
    ///     }
    /// }
    ///
    /// fn main() {
    ///     let _foo = Foo;
    ///     let _bar = Bar;
    /// }
    /// ```
    ///
    /// This will print
    ///
    /// ```text
    /// Dropping Bar!
    /// Dropping Foo!
    /// ```
    ///
    /// Please see [the reference] for the full rules.
    ///
    /// [the reference]: https://doc.rust-lang.org/reference/destructors.html
    ///
    /// ## `Copy` and `Drop` are exclusive
    ///
    /// You cannot implement both [`Copy`] and `Drop` on the same type. Types that
    /// are `Copy` get implicitly duplicated by the compiler, making it very
    /// hard to predict when, and how often destructors will be executed. As such,
    /// these types cannot have destructors.
    ///
    /// [`Copy`]: ../../std/marker/trait.Copy.html
    #[lang = "drop"]
    #[stable(feature = "rust1", since = "1.0.0")]
    pub trait Drop {
        /// Executes the destructor for this type.
        ///
        /// This method is called implicitly when the value goes out of scope,
        /// and cannot be called explicitly (this is compiler error [E0040]).
        /// However, the [`std::mem::drop`] function in the prelude can be
        /// used to call the argument's `Drop` implementation.
        ///
        /// When this method has been called, `self` has not yet been deallocated.
        /// That only happens after the method is over.
        /// If this wasn't the case, `self` would be a dangling reference.
        ///
        /// # Panics
        ///
        /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
        /// in a `drop` implementation will likely abort.
        ///
        /// Note that even if this panics, the value is considered to be dropped;
        /// you must not cause `drop` to be called again. This is normally automatically
        /// handled by the compiler, but when using unsafe code, can sometimes occur
        /// unintentionally, particularly when using [`std::ptr::drop_in_place`].
        ///
        /// [E0040]: ../../error-index.html#E0040
        /// [`panic!`]: ../macro.panic.html
        /// [`std::mem::drop`]: ../../std/mem/fn.drop.html
        /// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html
        #[stable(feature = "rust1", since = "1.0.0")]
        fn drop(&mut self);
    }