From 14b767d07e15e66203429f674315727a47e01ed5 Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 22 May 2017 15:06:25 -0700 Subject: [PATCH 1/5] Add example of recursive drop to Drop trait. --- src/libcore/ops.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index fc3af096b1838..4c2d05accf389 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -153,6 +153,8 @@ use marker::Unsize; /// The `Drop` trait is used to run some code when a value goes out of scope. /// This is sometimes called a 'destructor'. /// +/// +/// /// # Examples /// /// A trivial implementation of `Drop`. The `drop` method is called when `_x` @@ -171,6 +173,32 @@ use marker::Unsize; /// let _x = HasDrop; /// } /// ``` +/// +/// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the +/// `drop` method will be called for `Outer` and then the `drop` method for +/// `Inner` will be called. 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); +/// } +/// ``` #[lang = "drop"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Drop { From ca909c836fb509bcda5471cdeef0dd9ccd00c54d Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 22 May 2017 15:15:04 -0700 Subject: [PATCH 2/5] Add example of variable declaration drop order to Drop trait. --- src/libcore/ops.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 4c2d05accf389..a2cdd646bd43a 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -199,6 +199,18 @@ use marker::Unsize; /// let _x = Outer(Inner); /// } /// ``` +/// +/// Because variables are dropped in the reverse order they are declared, +/// `main` will print `Declared second!` and then `Declared first!`. +/// +/// ``` +/// struct PrintOnDrop(&'static str); +/// +/// fn main() { +/// let _first = PrintOnDrop("Declared first!"); +/// let _second = PrintOnDrop("Declared second!"); +/// } +/// ``` #[lang = "drop"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Drop { From d7927ffb8f55e8a292c5d933325660141f0aab4e Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 22 May 2017 15:59:00 -0700 Subject: [PATCH 3/5] Add description of how values are dropped to Drop trait. --- src/libcore/ops.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index a2cdd646bd43a..f2385cfcd787b 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -153,7 +153,13 @@ use marker::Unsize; /// The `Drop` trait is 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, if it implements this trait, it will have +/// its `drop` method called. Then any fields the value contains will also +/// be dropped recursively. +/// +/// Because of the recursive dropping, even for types that do not implement +/// this trait, you do not need to implement this trait unless your type +/// needs its own destructor logic. /// /// # Examples /// From 5f4b0ffe59c1c0358ea3e5b9c1ad5fdb7b135b96 Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 22 May 2017 16:33:55 -0700 Subject: [PATCH 4/5] Fix trailing whitespace. --- src/libcore/ops.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index f2385cfcd787b..dd1990784c404 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -184,7 +184,7 @@ use marker::Unsize; /// `drop` method will be called for `Outer` and then the `drop` method for /// `Inner` will be called. Therefore `main` prints `Dropping Outer!` and then /// `Dropping Inner!`. -/// +/// /// ``` /// struct Inner; /// struct Outer(Inner); @@ -211,7 +211,7 @@ use marker::Unsize; /// /// ``` /// struct PrintOnDrop(&'static str); -/// +/// /// fn main() { /// let _first = PrintOnDrop("Declared first!"); /// let _second = PrintOnDrop("Declared second!"); From b41b2947d56ce8be0b927d59d766a23271b9dd37 Mon Sep 17 00:00:00 2001 From: Havvy Date: Mon, 22 May 2017 23:49:35 -0700 Subject: [PATCH 5/5] Suggested changes by birkenfeld --- src/libcore/ops.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index dd1990784c404..4fb1f1757bbf7 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -157,9 +157,8 @@ use marker::Unsize; /// its `drop` method called. Then any fields the value contains will also /// be dropped recursively. /// -/// Because of the recursive dropping, even for types that do not implement -/// this trait, you do not need to implement this trait unless your type -/// needs its own destructor logic. +/// Because of the recursive dropping, you do not need to implement this trait +/// unless your type needs its own destructor logic. /// /// # Examples /// @@ -181,9 +180,8 @@ use marker::Unsize; /// ``` /// /// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the -/// `drop` method will be called for `Outer` and then the `drop` method for -/// `Inner` will be called. Therefore `main` prints `Dropping Outer!` and then -/// `Dropping Inner!`. +/// `drop` method will be called first for `Outer`, then for `Inner`. Therefore +/// `main` prints `Dropping Outer!` and then `Dropping Inner!`. /// /// ``` /// struct Inner;