about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-05-29 21:00:26 +0000
committerbors <bors@rust-lang.org>2015-05-29 21:00:26 +0000
commitb77d60adb019bb5de05e884a99f3290ec4694137 (patch)
treefee3928d1551e6abffedc4cbb557f5119d2e8e20 /src/libcore
parent996fb8d001e52e9c8b558515f3706d39f4b6b700 (diff)
parented19a6e034b25e7e08f34714ee44b196c810f44e (diff)
downloadrust-b77d60adb019bb5de05e884a99f3290ec4694137.tar.gz
rust-b77d60adb019bb5de05e884a99f3290ec4694137.zip
Auto merge of #25888 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #25788, #25861, #25864, #25865, #25866, #25873, #25876, #25883, #25886
- Failed merges: 
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);
     }
 }