mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
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
This commit is contained in:
parent
05d5fcaa5b
commit
dd59b1fb4c
@ -647,7 +647,7 @@ impl<T> Vec<T> {
|
|||||||
// zero-size types consume no memory, so we can't rely on the
|
// zero-size types consume no memory, so we can't rely on the
|
||||||
// address space running out
|
// address space running out
|
||||||
self.len = self.len.checked_add(1).expect("length overflow");
|
self.len = self.len.checked_add(1).expect("length overflow");
|
||||||
unsafe { mem::forget(value); }
|
mem::forget(value);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,7 +994,7 @@ impl<T> Vec<T> {
|
|||||||
num_u: 0,
|
num_u: 0,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
};
|
};
|
||||||
unsafe { mem::forget(vec); }
|
mem::forget(vec);
|
||||||
|
|
||||||
while pv.num_t != 0 {
|
while pv.num_t != 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -232,10 +232,6 @@ extern "rust-intrinsic" {
|
|||||||
pub fn uninit<T>() -> T;
|
pub fn uninit<T>() -> T;
|
||||||
|
|
||||||
/// Moves a value out of scope without running drop glue.
|
/// 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) -> ();
|
pub fn forget<T>(_: T) -> ();
|
||||||
|
|
||||||
/// Unsafely transforms a value of one type into a value of another type.
|
/// Unsafely transforms a value of one type into a value of another type.
|
||||||
|
@ -22,15 +22,54 @@ use ptr;
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use intrinsics::transmute;
|
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
|
/// This function will take ownership of its argument, but is distinct from the
|
||||||
/// to run any required cleanup or memory management operations on it.
|
/// `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
|
/// # Safety
|
||||||
/// not run any destructors.
|
///
|
||||||
|
/// 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")]
|
#[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.
|
/// Returns the size of a type in bytes.
|
||||||
///
|
///
|
||||||
|
@ -31,7 +31,7 @@ impl FileDesc {
|
|||||||
/// Extracts the actual filedescriptor without closing it.
|
/// Extracts the actual filedescriptor without closing it.
|
||||||
pub fn into_raw(self) -> c_int {
|
pub fn into_raw(self) -> c_int {
|
||||||
let fd = self.fd;
|
let fd = self.fd;
|
||||||
unsafe { mem::forget(self) };
|
mem::forget(self);
|
||||||
fd
|
fd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ impl Handle {
|
|||||||
|
|
||||||
pub fn into_raw(self) -> HANDLE {
|
pub fn into_raw(self) -> HANDLE {
|
||||||
let ret = self.0;
|
let ret = self.0;
|
||||||
unsafe { mem::forget(self) }
|
mem::forget(self);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user