about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2015-05-29 15:24:46 -0400
committerSteve Klabnik <steve@steveklabnik.com>2015-05-29 15:24:46 -0400
commit1999d759f7076d935dc433f3bd6dabd1f0634762 (patch)
tree17729d8466e6991b618e3d579509393aa1794592 /src/libcore
parente9e2a11a6ae73c20312cb213cd32ce8c19ab5bc7 (diff)
parent8746b1ac6f3c95383a19ad2ab365a62140516206 (diff)
downloadrust-1999d759f7076d935dc433f3bd6dabd1f0634762.tar.gz
rust-1999d759f7076d935dc433f3bd6dabd1f0634762.zip
Rollup merge of #25861 - tringenbach:master, r=steveklabnik
This adds an example from mem::swap, and provides some suggested uses of this
function.

This is my attempt to summarize the answers to a question I asked on reddit http://www.reddit.com/r/rust/comments/37jcul/what_is_forget_for/ and add the answers to the documentation so that no one else has to google or ask the question again.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/mem.rs54
1 files changed, 48 insertions, 6 deletions
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 7749d053285..26c6e899df1 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -52,20 +52,61 @@ pub use intrinsics::transmute;
 /// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally)
 /// * Panicking destructors are likely to leak local resources
 ///
+/// # When To Use
+///
+/// There's only a few reasons to use this function. They mainly come
+/// up in unsafe code or FFI code.
+///
+/// * You have an uninitialized value, perhaps for performance reasons, and
+///   need to prevent the destructor from running on it.
+/// * You have two copies of a value (like `std::mem::swap`), but need the
+///   destructor to only run once to prevent a double free.
+/// * Transferring resources across FFI boundries.
+///
 /// # Example
 ///
-/// ```rust,no_run
+/// Leak some heap memory by never deallocating it.
+///
+/// ```rust
 /// use std::mem;
-/// use std::fs::File;
 ///
-/// // Leak some heap memory by never deallocating it
 /// let heap_memory = Box::new(3);
 /// mem::forget(heap_memory);
+/// ```
+///
+/// Leak an I/O object, never closing the file.
+///
+/// ```rust,no_run
+/// use std::mem;
+/// use std::fs::File;
 ///
-/// // Leak an I/O object, never closing the file
 /// let file = File::open("foo.txt").unwrap();
 /// mem::forget(file);
 /// ```
+///
+/// The swap function uses forget to good effect.
+///
+/// ```rust
+/// use std::mem;
+/// use std::ptr;
+///
+/// fn swap<T>(x: &mut T, y: &mut T) {
+///     unsafe {
+///         // Give ourselves some scratch space to work with
+///         let mut t: T = mem::uninitialized();
+///
+///         // Perform the swap, `&mut` pointers never alias
+///         ptr::copy_nonoverlapping(&*x, &mut t, 1);
+///         ptr::copy_nonoverlapping(&*y, x, 1);
+///         ptr::copy_nonoverlapping(&t, y, 1);
+///
+///         // y and t now point to the same thing, but we need to completely
+///         // forget `t` because we do not want to run the destructor for `T`
+///         // on its value, which is still owned somewhere outside this function.
+///         mem::forget(t);
+///     }
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn forget<T>(t: T) {
     unsafe { intrinsics::forget(t) }
@@ -267,8 +308,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
         ptr::copy_nonoverlapping(&*y, x, 1);
         ptr::copy_nonoverlapping(&t, y, 1);
 
-        // y and t now point to the same thing, but we need to completely forget `t`
-        // because it's no longer relevant.
+        // y and t now point to the same thing, but we need to completely
+        // forget `t` because we do not want to run the destructor for `T`
+        // on its value, which is still owned somewhere outside this function.
         forget(t);
     }
 }