Function core::mem::forget [] [src]

pub fn forget<T>(t: T)
1.0.0

Leaks a value into the void, consuming ownership and never running its destructor.

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.

There's only a few reasons to use this function. They mainly come up in unsafe code or FFI code.

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:

Example

Leak some heap memory by never deallocating it:

fn main() { use std::mem; let heap_memory = Box::new(3); mem::forget(heap_memory); }
use std::mem;

let heap_memory = Box::new(3);
mem::forget(heap_memory);

Leak an I/O object, never closing the file:

fn main() { use std::mem; use std::fs::File; let file = File::open("foo.txt").unwrap(); mem::forget(file); }
use std::mem;
use std::fs::File;

let file = File::open("foo.txt").unwrap();
mem::forget(file);

The mem::swap function uses mem::forget to good effect:

fn main() { use std::mem; use std::ptr; #[allow(dead_code)] 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); } } }
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);
    }
}