summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-05-07 10:49:39 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-05-10 23:16:54 -0700
commit7b78086ba4c6bfc656bc0d8b3171aa9929f593dc (patch)
treec4cadace8c4dbab06b369050d522975e960af518 /src/libcore
parent8421c7cfc8507f37d906447afaaa80cb09ca2cbe (diff)
downloadrust-7b78086ba4c6bfc656bc0d8b3171aa9929f593dc.tar.gz
rust-7b78086ba4c6bfc656bc0d8b3171aa9929f593dc.zip
std: Mark `mem::forget` as a safe function
This commit is an implementation of [RFC 1066][rfc] where the conclusion was
that leaking a value is a safe operation in Rust code, so updating the signature
of this function follows suit.

[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1066-safe-mem-forget.md

Closes #25186
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/intrinsics.rs4
-rw-r--r--src/libcore/mem.rs51
2 files changed, 45 insertions, 10 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 8ed89adec5b..077d6367ff3 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -217,10 +217,6 @@ extern "rust-intrinsic" {
     pub fn uninit<T>() -> T;
 
     /// Moves a value out of scope without running drop glue.
-    ///
-    /// `forget` is unsafe because the caller is responsible for
-    /// ensuring the argument is deallocated already.
-    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn forget<T>(_: T) -> ();
 
     /// Unsafely transforms a value of one type into a value of another type.
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index c4128e79765..a149af3a440 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -22,15 +22,54 @@ use ptr;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use intrinsics::transmute;
 
-/// Moves a thing into the void.
+/// Leaks a value into the void, consuming ownership and never running its
+/// destructor.
 ///
-/// The forget function will take ownership of the provided value but neglect
-/// to run any required cleanup or memory management operations on it.
+/// This function will take ownership of its argument, but is distinct from the
+/// `mem::drop` function in that it **does not run the destructor**, leaking the
+/// value and any resources that it owns.
 ///
-/// This function is the unsafe version of the `drop` function because it does
-/// not run any destructors.
+/// # Safety
+///
+/// This function is not marked as `unsafe` as Rust does not guarantee that the
+/// `Drop` implementation for a value will always run. Note, however, that
+/// leaking resources such as memory or I/O objects is likely not desired, so
+/// this function is only recommended for specialized use cases.
+///
+/// The safety of this function implies that when writing `unsafe` code
+/// yourself care must be taken when leveraging a destructor that is required to
+/// run to preserve memory safety. There are known situations where the
+/// destructor may not run (such as if ownership of the object with the
+/// destructor is returned) which must be taken into account.
+///
+/// # Other forms of Leakage
+///
+/// It's important to point out that this function is not the only method by
+/// which a value can be leaked in safe Rust code. Other known sources of
+/// leakage are:
+///
+/// * `Rc` and `Arc` cycles
+/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally)
+/// * Panicking destructors are likely to leak local resources
+///
+/// # Example
+///
+/// ```rust,no_run
+/// 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
+/// let file = File::open("foo.txt").unwrap();
+/// mem::forget(file);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use intrinsics::forget;
+pub fn forget<T>(t: T) {
+    unsafe { intrinsics::forget(t) }
+}
 
 /// Returns the size of a type in bytes.
 ///