pub trait ManuallyDropMut {
    type Ret: ?Sized;

    fn manually_drop_mut(&mut self) -> &mut Self::Ret;
}
Expand description

Extension trait providing a cast to the ManuallyDrop type.

This is useful if you want to use an [Out] reference to something that is not Copy (potentially because it has drop glue, in which case you either don’t mind leaking / skipping that drop glue, or you know you will be manually handling it).

⚠️ Misusage of this function can thus lead to memory leaks ⚠️

Example

The following fails to compile because of the missing Copy bound:

use ::uninit::prelude::*;
use ::core::cell::Cell;

let mut cell = Cell::new(0);
cell.as_out().write(Cell::new(42)); // Error, not `Copy`
assert_eq!(cell.get(), 42);

We see here that the Copy bound can be too restrictive. By calling .manually_drop_mut(), we no longer need to satisfy this Copy bound; but then we need to be careful with memory leaks.

Since ::core::mem::needs_drop::<Cell<_>>() == false, there is nothing to worry about:

use ::uninit::prelude::*;
use ::core::cell::Cell;

let mut cell = Cell::new(0);
cell.manually_drop_mut().as_out().write(Cell::new(42)); // OK
assert_eq!(cell.get(), 42);

Counterexample

use ::uninit::prelude::*;
use ::std::rc::Rc;

let rc = Rc::new(());
assert_eq!(Rc::strong_count(&rc), 1);
let mut rc2 = Some(Rc::clone(&rc));
assert_eq!(Rc::strong_count(&rc), 2);
// This overwrites `rc2` without running any destructor whatsoever, hence
// leaking the `rc` clone.
rc2.manually_drop_mut().as_out().write(None);
assert_eq!(Rc::strong_count(&rc), 2);
assert!(Rc::try_unwrap(rc).is_err());

Required Associated Types

Required Methods

Implementations on Foreign Types

Implementors