| 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 | #[const_trait ] |
| 207 | #[rustc_const_unstable (feature = "const_destruct" , issue = "133214" )] |
| 208 | pub trait Drop { |
| 209 | /// Executes the destructor for this type. |
| 210 | /// |
| 211 | /// This method is called implicitly when the value goes out of scope, |
| 212 | /// and cannot be called explicitly (this is compiler error [E0040]). |
| 213 | /// However, the [`mem::drop`] function in the prelude can be |
| 214 | /// used to call the argument's `Drop` implementation. |
| 215 | /// |
| 216 | /// When this method has been called, `self` has not yet been deallocated. |
| 217 | /// That only happens after the method is over. |
| 218 | /// If this wasn't the case, `self` would be a dangling reference. |
| 219 | /// |
| 220 | /// # Panics |
| 221 | /// |
| 222 | /// Implementations should generally avoid [`panic!`]ing, because `drop()` may itself be called |
| 223 | /// during unwinding due to a panic, and if the `drop()` panics in that situation (a “double |
| 224 | /// panic”), this will likely abort the program. It is possible to check [`panicking()`] first, |
| 225 | /// which may be desirable for a `Drop` implementation that is reporting a bug of the kind |
| 226 | /// “you didn't finish using this before it was dropped”; but most types should simply clean up |
| 227 | /// their owned allocations or other resources and return normally from `drop()`, regardless of |
| 228 | /// what state they are in. |
| 229 | /// |
| 230 | /// Note that even if this panics, the value is considered to be dropped; |
| 231 | /// you must not cause `drop` to be called again. This is normally automatically |
| 232 | /// handled by the compiler, but when using unsafe code, can sometimes occur |
| 233 | /// unintentionally, particularly when using [`ptr::drop_in_place`]. |
| 234 | /// |
| 235 | /// [E0040]: ../../error_codes/E0040.html |
| 236 | /// [`panic!`]: crate::panic! |
| 237 | /// [`panicking()`]: ../../std/thread/fn.panicking.html |
| 238 | /// [`mem::drop`]: drop |
| 239 | /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place |
| 240 | #[stable (feature = "rust1" , since = "1.0.0" )] |
| 241 | fn drop(&mut self); |
| 242 | } |
| 243 | |
| 244 | /// Fallback function to call surface level `Drop::drop` function |
| 245 | #[allow (drop_bounds)] |
| 246 | #[lang = "fallback_surface_drop" ] |
| 247 | pub(crate) fn fallback_surface_drop<T: Drop + ?Sized>(x: &mut T) { |
| 248 | <T as Drop>::drop(self:x) |
| 249 | } |
| 250 | |