1 use crate::ops::{Deref, DerefMut};
4 /// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
6 /// This wrapper is 0-cost.
8 /// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
9 /// As a consequence, it has *no effect* on the assumptions that the compiler makes
10 /// about all values being initialized at their type. In particular, initializing
11 /// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior.
12 /// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
16 /// This wrapper helps with explicitly documenting the drop order dependencies between fields of
20 /// use std::mem::ManuallyDrop;
25 /// // Immediately clear there’s something non-trivial going on with these fields.
26 /// peach: ManuallyDrop<Peach>,
27 /// melon: Melon, // Field that’s independent of the other two.
28 /// banana: ManuallyDrop<Banana>,
31 /// impl Drop for FruitBox {
32 /// fn drop(&mut self) {
34 /// // Explicit ordering in which field destructors are run specified in the intuitive
35 /// // location – the destructor of the structure containing the fields.
36 /// // Moreover, one can now reorder fields within the struct however much they want.
37 /// ManuallyDrop::drop(&mut self.peach);
38 /// ManuallyDrop::drop(&mut self.banana);
40 /// // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
41 /// // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
46 /// [`mem::zeroed`]: fn.zeroed.html
47 /// [`MaybeUninit<T>`]: union.MaybeUninit.html
48 #[stable(feature = "manually_drop", since = "1.20.0")]
49 #[lang = "manually_drop"]
50 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
52 pub struct ManuallyDrop<T: ?Sized> {
56 impl<T> ManuallyDrop<T> {
57 /// Wrap a value to be manually dropped.
62 /// use std::mem::ManuallyDrop;
63 /// ManuallyDrop::new(Box::new(()));
65 #[stable(feature = "manually_drop", since = "1.20.0")]
66 #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
68 pub const fn new(value: T) -> ManuallyDrop<T> {
69 ManuallyDrop { value }
72 /// Extracts the value from the `ManuallyDrop` container.
74 /// This allows the value to be dropped again.
79 /// use std::mem::ManuallyDrop;
80 /// let x = ManuallyDrop::new(Box::new(()));
81 /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
83 #[stable(feature = "manually_drop", since = "1.20.0")]
84 #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
86 pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
90 /// Takes the value from the `ManuallyDrop<T>` container out.
92 /// This method is primarily intended for moving out values in drop.
93 /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
94 /// you can use this method to take the value and use it however desired.
96 /// Whenever possible, it is preferable to use [`into_inner`][`ManuallyDrop::into_inner`]
97 /// instead, which prevents duplicating the content of the `ManuallyDrop<T>`.
101 /// This function semantically moves out the contained value without preventing further usage,
102 /// leaving the state of this container unchanged.
103 /// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
105 /// [`ManuallyDrop::drop`]: #method.drop
106 /// [`ManuallyDrop::into_inner`]: #method.into_inner
107 #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
108 #[stable(feature = "manually_drop_take", since = "1.42.0")]
110 pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
111 ptr::read(&slot.value)
115 impl<T: ?Sized> ManuallyDrop<T> {
116 /// Manually drops the contained value.
118 /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
122 /// This function runs the destructor of the contained value and thus the wrapped value
123 /// now represents uninitialized data. It is up to the user of this method to ensure the
124 /// uninitialized data is not actually used.
125 /// In particular, this function can only be called at most once
126 /// for a given instance of `ManuallyDrop<T>`.
128 /// [`ManuallyDrop::into_inner`]: #method.into_inner
129 #[stable(feature = "manually_drop", since = "1.20.0")]
131 pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
132 ptr::drop_in_place(&mut slot.value)
136 #[stable(feature = "manually_drop", since = "1.20.0")]
137 impl<T: ?Sized> Deref for ManuallyDrop<T> {
140 fn deref(&self) -> &T {
145 #[stable(feature = "manually_drop", since = "1.20.0")]
146 impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
148 fn deref_mut(&mut self) -> &mut T {