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
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. /// Used to run some code when a value goes out of scope. /// This is sometimes called a 'destructor'. /// /// When a value goes out of scope, it will have its `drop` method called if /// its type implements `Drop`. Then, any fields the value contains will also /// be dropped recursively. /// /// Because of this recursive dropping, you do not need to implement this trait /// unless your type needs its own destructor logic. /// /// Refer to [the chapter on `Drop` in *The Rust Programming Language*][book] /// for some more elaboration. /// /// [book]: ../../book/second-edition/ch15-03-drop.html /// /// # Examples /// /// ## Implementing `Drop` /// /// The `drop` method is called when `_x` goes out of scope, and therefore /// `main` prints `Dropping!`. /// /// ``` /// struct HasDrop; /// /// impl Drop for HasDrop { /// fn drop(&mut self) { /// println!("Dropping!"); /// } /// } /// /// fn main() { /// let _x = HasDrop; /// } /// ``` /// /// ## Dropping is done recursively /// /// When `outer` goes out of scope, the `drop` method will be called first for /// `Outer`, then for `Inner`. Therefore, `main` prints `Dropping Outer!` and /// then `Dropping Inner!`. /// /// ``` /// struct Inner; /// struct Outer(Inner); /// /// impl Drop for Inner { /// fn drop(&mut self) { /// println!("Dropping Inner!"); /// } /// } /// /// impl Drop for Outer { /// fn drop(&mut self) { /// println!("Dropping Outer!"); /// } /// } /// /// fn main() { /// let _x = Outer(Inner); /// } /// ``` /// /// ## Variables are dropped in reverse order of declaration /// /// `_first` is declared first and `_second` is declared second, so `main` will /// print `Declared second!` and then `Declared first!`. /// /// ``` /// struct PrintOnDrop(&'static str); /// /// impl Drop for PrintOnDrop { /// fn drop(&mut self) { /// println!("{}", self.0); /// } /// } /// /// fn main() { /// let _first = PrintOnDrop("Declared first!"); /// let _second = PrintOnDrop("Declared second!"); /// } /// ``` #[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. /// /// [E0040]: ../../error-index.html#E0040 /// [`panic!`]: ../macro.panic.html /// [`std::mem::drop`]: ../../std/mem/fn.drop.html #[stable(feature = "rust1", since = "1.0.0")] fn drop(&mut self); }