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 | /// and [`ManuallyDrop`] are considered to never have a destructor, no matter their field type. |
176 | /// - If `T` has drop glue, then, for all types `U` that are *owned* by any field of `T`, |
177 | /// recursively add the types and lifetimes that need to be live when `U` gets dropped. The set of |
178 | /// owned types is determined by recursively traversing `T`: |
179 | /// - Recursively descend through `PhantomData`, `Box`, tuples, and arrays (including arrays of |
180 | /// length 0). |
181 | /// - Stop at reference and raw pointer types as well as function pointers and function items; |
182 | /// they do not own anything. |
183 | /// - Stop at non-composite types (type parameters that remain generic in the current context and |
184 | /// base types such as integers and `bool`); these types are owned. |
185 | /// - When hitting an ADT with `impl Drop`, stop there; this type is owned. |
186 | /// - When hitting an ADT without `impl Drop`, recursively descend to its fields. (For an `enum`, |
187 | /// consider all fields of all variants.) |
188 | /// - Furthermore, if `T` implements `Drop`, then all generic (lifetime and type) parameters of `T` |
189 | /// must be live. |
190 | /// |
191 | /// In the above example, the last clause implies that `'a` must be live when `S<'a>` is dropped, |
192 | /// and hence the example is rejected. If we remove the `impl Drop`, the liveness requirement |
193 | /// disappears and the example is accepted. |
194 | /// |
195 | /// There exists an unstable way for a type to opt-out of the last clause; this is called "drop |
196 | /// check eyepatch" or `may_dangle`. For more details on this nightly-only feature, see the |
197 | /// [discussion in the Nomicon][nomicon]. |
198 | /// |
199 | /// [`ManuallyDrop`]: crate::mem::ManuallyDrop |
200 | /// [`PhantomData`]: crate::marker::PhantomData |
201 | /// [drop check]: ../../nomicon/dropck.html |
202 | /// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle |
203 | #[lang = "drop" ] |
204 | #[stable (feature = "rust1" , since = "1.0.0" )] |
205 | // FIXME(effects) #[const_trait] |
206 | pub trait Drop { |
207 | /// Executes the destructor for this type. |
208 | /// |
209 | /// This method is called implicitly when the value goes out of scope, |
210 | /// and cannot be called explicitly (this is compiler error [E0040]). |
211 | /// However, the [`mem::drop`] function in the prelude can be |
212 | /// used to call the argument's `Drop` implementation. |
213 | /// |
214 | /// When this method has been called, `self` has not yet been deallocated. |
215 | /// That only happens after the method is over. |
216 | /// If this wasn't the case, `self` would be a dangling reference. |
217 | /// |
218 | /// # Panics |
219 | /// |
220 | /// Implementations should generally avoid [`panic!`]ing, because `drop()` may itself be called |
221 | /// during unwinding due to a panic, and if the `drop()` panics in that situation (a “double |
222 | /// panic”), this will likely abort the program. It is possible to check [`panicking()`] first, |
223 | /// which may be desirable for a `Drop` implementation that is reporting a bug of the kind |
224 | /// “you didn't finish using this before it was dropped”; but most types should simply clean up |
225 | /// their owned allocations or other resources and return normally from `drop()`, regardless of |
226 | /// what state they are in. |
227 | /// |
228 | /// Note that even if this panics, the value is considered to be dropped; |
229 | /// you must not cause `drop` to be called again. This is normally automatically |
230 | /// handled by the compiler, but when using unsafe code, can sometimes occur |
231 | /// unintentionally, particularly when using [`ptr::drop_in_place`]. |
232 | /// |
233 | /// [E0040]: ../../error_codes/E0040.html |
234 | /// [`panic!`]: crate::panic! |
235 | /// [`panicking()`]: ../../std/thread/fn.panicking.html |
236 | /// [`mem::drop`]: drop |
237 | /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place |
238 | #[stable (feature = "rust1" , since = "1.0.0" )] |
239 | fn drop(&mut self); |
240 | } |
241 | |
242 | /// Fallback function to call surface level `Drop::drop` function |
243 | #[cfg (not(bootstrap))] |
244 | #[allow (drop_bounds)] |
245 | #[lang = "fallback_surface_drop" ] |
246 | pub(crate) fn fallback_surface_drop<T: Drop + ?Sized>(x: &mut T) { |
247 | <T as Drop>::drop(self:x) |
248 | } |
249 | |