]>
Commit | Line | Data |
---|---|---|
3b2f2976 | 1 | /// Used to run some code when a value goes out of scope. |
041b39d2 XL |
2 | /// This is sometimes called a 'destructor'. |
3 | /// | |
3b2f2976 XL |
4 | /// When a value goes out of scope, it will have its `drop` method called if |
5 | /// its type implements `Drop`. Then, any fields the value contains will also | |
041b39d2 XL |
6 | /// be dropped recursively. |
7 | /// | |
3b2f2976 | 8 | /// Because of this recursive dropping, you do not need to implement this trait |
041b39d2 XL |
9 | /// unless your type needs its own destructor logic. |
10 | /// | |
3b2f2976 XL |
11 | /// Refer to [the chapter on `Drop` in *The Rust Programming Language*][book] |
12 | /// for some more elaboration. | |
13 | /// | |
0731742a | 14 | /// [book]: ../../book/ch15-03-drop.html |
3b2f2976 | 15 | /// |
041b39d2 XL |
16 | /// # Examples |
17 | /// | |
3b2f2976 XL |
18 | /// ## Implementing `Drop` |
19 | /// | |
20 | /// The `drop` method is called when `_x` goes out of scope, and therefore | |
21 | /// `main` prints `Dropping!`. | |
041b39d2 XL |
22 | /// |
23 | /// ``` | |
24 | /// struct HasDrop; | |
25 | /// | |
26 | /// impl Drop for HasDrop { | |
27 | /// fn drop(&mut self) { | |
28 | /// println!("Dropping!"); | |
29 | /// } | |
30 | /// } | |
31 | /// | |
32 | /// fn main() { | |
33 | /// let _x = HasDrop; | |
34 | /// } | |
35 | /// ``` | |
36 | /// | |
3b2f2976 XL |
37 | /// ## Dropping is done recursively |
38 | /// | |
39 | /// When `outer` goes out of scope, the `drop` method will be called first for | |
40 | /// `Outer`, then for `Inner`. Therefore, `main` prints `Dropping Outer!` and | |
41 | /// then `Dropping Inner!`. | |
041b39d2 XL |
42 | /// |
43 | /// ``` | |
44 | /// struct Inner; | |
45 | /// struct Outer(Inner); | |
46 | /// | |
47 | /// impl Drop for Inner { | |
48 | /// fn drop(&mut self) { | |
49 | /// println!("Dropping Inner!"); | |
50 | /// } | |
51 | /// } | |
52 | /// | |
53 | /// impl Drop for Outer { | |
54 | /// fn drop(&mut self) { | |
55 | /// println!("Dropping Outer!"); | |
56 | /// } | |
57 | /// } | |
58 | /// | |
59 | /// fn main() { | |
60 | /// let _x = Outer(Inner); | |
61 | /// } | |
62 | /// ``` | |
63 | /// | |
3b2f2976 XL |
64 | /// ## Variables are dropped in reverse order of declaration |
65 | /// | |
66 | /// `_first` is declared first and `_second` is declared second, so `main` will | |
67 | /// print `Declared second!` and then `Declared first!`. | |
041b39d2 XL |
68 | /// |
69 | /// ``` | |
70 | /// struct PrintOnDrop(&'static str); | |
71 | /// | |
3b2f2976 XL |
72 | /// impl Drop for PrintOnDrop { |
73 | /// fn drop(&mut self) { | |
74 | /// println!("{}", self.0); | |
75 | /// } | |
76 | /// } | |
77 | /// | |
041b39d2 XL |
78 | /// fn main() { |
79 | /// let _first = PrintOnDrop("Declared first!"); | |
80 | /// let _second = PrintOnDrop("Declared second!"); | |
81 | /// } | |
82 | /// ``` | |
83 | #[lang = "drop"] | |
84 | #[stable(feature = "rust1", since = "1.0.0")] | |
85 | pub trait Drop { | |
3b2f2976 XL |
86 | /// Executes the destructor for this type. |
87 | /// | |
0531ce1d | 88 | /// This method is called implicitly when the value goes out of scope, |
3b2f2976 XL |
89 | /// and cannot be called explicitly (this is compiler error [E0040]). |
90 | /// However, the [`std::mem::drop`] function in the prelude can be | |
91 | /// used to call the argument's `Drop` implementation. | |
041b39d2 XL |
92 | /// |
93 | /// When this method has been called, `self` has not yet been deallocated. | |
3b2f2976 XL |
94 | /// That only happens after the method is over. |
95 | /// If this wasn't the case, `self` would be a dangling reference. | |
041b39d2 | 96 | /// |
3b2f2976 | 97 | /// # Panics |
041b39d2 | 98 | /// |
3b2f2976 XL |
99 | /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`] |
100 | /// in a `drop` implementation will likely abort. | |
041b39d2 | 101 | /// |
dfeec247 XL |
102 | /// Note that even if this panics, the value is considered to be dropped; |
103 | /// you must not cause `drop` to be called again. This is normally automatically | |
104 | /// handled by the compiler, but when using unsafe code, can sometimes occur | |
105 | /// unintentionally, particularly when using [`std::ptr::drop_in_place`]. | |
106 | /// | |
041b39d2 | 107 | /// [E0040]: ../../error-index.html#E0040 |
3b2f2976 | 108 | /// [`panic!`]: ../macro.panic.html |
041b39d2 | 109 | /// [`std::mem::drop`]: ../../std/mem/fn.drop.html |
dfeec247 | 110 | /// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html |
041b39d2 XL |
111 | #[stable(feature = "rust1", since = "1.0.0")] |
112 | fn drop(&mut self); | |
113 | } |