1.0.0[][src]Function no_std_compat::mem::forget

pub fn forget<T>(t: T)

Takes ownership and "forgets" about the value without running its destructor.

Any resources the value manages, such as heap memory or a file handle, will linger forever in an unreachable state. However, it does not guarantee that pointers to this memory will remain valid.

  • If you want to leak memory, see Box::leak.
  • If you want to obtain a raw pointer to the memory, see Box::into_raw.
  • If you want to dispose of a value properly, running its destructor, see mem::drop.

Safety

forget is not marked as unsafe, because Rust's safety guarantees do not include a guarantee that destructors will always run. For example, a program can create a reference cycle using Rc, or call process::exit to exit without running destructors. Thus, allowing mem::forget from safe code does not fundamentally change Rust's safety guarantees.

That said, leaking resources such as memory or I/O objects is usually undesirable. The need comes up in some specialized use cases for FFI or unsafe code, but even then, ManuallyDrop is typically preferred.

Because forgetting a value is allowed, any unsafe code you write must allow for this possibility. You cannot return a value and expect that the caller will necessarily run the value's destructor.

Examples

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

use std::mem;
use std::fs::File;

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

The practical use cases for forget are rather specialized and mainly come up in unsafe or FFI code. However, ManuallyDrop is usually preferred for such cases, e.g.:

use std::mem::ManuallyDrop;

let v = vec![65, 122];
// Before we disassemble `v` into its raw parts, make sure it
// does not get dropped!
let mut v = ManuallyDrop::new(v);
// Now disassemble `v`. These operations cannot panic, so there cannot be a leak.
let ptr = v.as_mut_ptr();
let cap = v.capacity();
// Finally, build a `String`.
let s = unsafe { String::from_raw_parts(ptr, 2, cap) };
assert_eq!(s, "Az");
// `s` is implicitly dropped and its memory deallocated.

Using ManuallyDrop here has two advantages:

  • We do not "touch" v after disassembling it. For some types, operations such as passing ownership (to a funcion like mem::forget) requires them to actually be fully owned right now; that is a promise we do not want to make here as we are in the process of transferring ownership to the new String we are building.
  • In case of an unexpected panic, ManuallyDrop is not dropped, but if the panic occurs before mem::forget was called we might end up dropping invalid data, or double-dropping. In other words, ManuallyDrop errs on the side of leaking instead of erring on the side of dropping.