Skip to content

Commit e7fc4ad

Browse files
committed
Rollup merge of rust-lang#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.
2 parents 233ab2d + 8746b1a commit e7fc4ad

File tree

1 file changed

+48
-6
lines changed

1 file changed

+48
-6
lines changed

src/libcore/mem.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,61 @@ pub use intrinsics::transmute;
5252
/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally)
5353
/// * Panicking destructors are likely to leak local resources
5454
///
55+
/// # When To Use
56+
///
57+
/// There's only a few reasons to use this function. They mainly come
58+
/// up in unsafe code or FFI code.
59+
///
60+
/// * You have an uninitialized value, perhaps for performance reasons, and
61+
/// need to prevent the destructor from running on it.
62+
/// * You have two copies of a value (like `std::mem::swap`), but need the
63+
/// destructor to only run once to prevent a double free.
64+
/// * Transferring resources across FFI boundries.
65+
///
5566
/// # Example
5667
///
57-
/// ```rust,no_run
68+
/// Leak some heap memory by never deallocating it.
69+
///
70+
/// ```rust
5871
/// use std::mem;
59-
/// use std::fs::File;
6072
///
61-
/// // Leak some heap memory by never deallocating it
6273
/// let heap_memory = Box::new(3);
6374
/// mem::forget(heap_memory);
75+
/// ```
76+
///
77+
/// Leak an I/O object, never closing the file.
78+
///
79+
/// ```rust,no_run
80+
/// use std::mem;
81+
/// use std::fs::File;
6482
///
65-
/// // Leak an I/O object, never closing the file
6683
/// let file = File::open("foo.txt").unwrap();
6784
/// mem::forget(file);
6885
/// ```
86+
///
87+
/// The swap function uses forget to good effect.
88+
///
89+
/// ```rust
90+
/// use std::mem;
91+
/// use std::ptr;
92+
///
93+
/// fn swap<T>(x: &mut T, y: &mut T) {
94+
/// unsafe {
95+
/// // Give ourselves some scratch space to work with
96+
/// let mut t: T = mem::uninitialized();
97+
///
98+
/// // Perform the swap, `&mut` pointers never alias
99+
/// ptr::copy_nonoverlapping(&*x, &mut t, 1);
100+
/// ptr::copy_nonoverlapping(&*y, x, 1);
101+
/// ptr::copy_nonoverlapping(&t, y, 1);
102+
///
103+
/// // y and t now point to the same thing, but we need to completely
104+
/// // forget `t` because we do not want to run the destructor for `T`
105+
/// // on its value, which is still owned somewhere outside this function.
106+
/// mem::forget(t);
107+
/// }
108+
/// }
109+
/// ```
69110
#[stable(feature = "rust1", since = "1.0.0")]
70111
pub fn forget<T>(t: T) {
71112
unsafe { intrinsics::forget(t) }
@@ -267,8 +308,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
267308
ptr::copy_nonoverlapping(&*y, x, 1);
268309
ptr::copy_nonoverlapping(&t, y, 1);
269310

270-
// y and t now point to the same thing, but we need to completely forget `t`
271-
// because it's no longer relevant.
311+
// y and t now point to the same thing, but we need to completely
312+
// forget `t` because we do not want to run the destructor for `T`
313+
// on its value, which is still owned somewhere outside this function.
272314
forget(t);
273315
}
274316
}

0 commit comments

Comments
 (0)