]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops/drop.rs
Clear out std, not std tools
[rust.git] / src / libcore / ops / drop.rs
1 /// Used to run some code when a value goes out of scope.
2 /// This is sometimes called a 'destructor'.
3 ///
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
6 /// be dropped recursively.
7 ///
8 /// Because of this recursive dropping, you do not need to implement this trait
9 /// unless your type needs its own destructor logic.
10 ///
11 /// Refer to [the chapter on `Drop` in *The Rust Programming Language*][book]
12 /// for some more elaboration.
13 ///
14 /// [book]: ../../book/ch15-03-drop.html
15 ///
16 /// # Examples
17 ///
18 /// ## Implementing `Drop`
19 ///
20 /// The `drop` method is called when `_x` goes out of scope, and therefore
21 /// `main` prints `Dropping!`.
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 ///
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!`.
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 ///
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!`.
68 ///
69 /// ```
70 /// struct PrintOnDrop(&'static str);
71 ///
72 /// impl Drop for PrintOnDrop {
73 ///     fn drop(&mut self) {
74 ///         println!("{}", self.0);
75 ///     }
76 /// }
77 ///
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 {
86     /// Executes the destructor for this type.
87     ///
88     /// This method is called implicitly when the value goes out of scope,
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.
92     ///
93     /// When this method has been called, `self` has not yet been deallocated.
94     /// That only happens after the method is over.
95     /// If this wasn't the case, `self` would be a dangling reference.
96     ///
97     /// # Panics
98     ///
99     /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
100     /// in a `drop` implementation will likely abort.
101     ///
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     ///
107     /// [E0040]: ../../error-index.html#E0040
108     /// [`panic!`]: ../macro.panic.html
109     /// [`std::mem::drop`]: ../../std/mem/fn.drop.html
110     /// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html
111     #[stable(feature = "rust1", since = "1.0.0")]
112     fn drop(&mut self);
113 }