2 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")]
67 pub const fn new(value: T) -> ManuallyDrop<T> {
68 ManuallyDrop { value }
71 /// Extracts the value from the `ManuallyDrop` container.
73 /// This allows the value to be dropped again.
78 /// use std::mem::ManuallyDrop;
79 /// let x = ManuallyDrop::new(Box::new(()));
80 /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
82 #[stable(feature = "manually_drop", since = "1.20.0")]
84 pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
88 /// Takes the contained value out.
90 /// This method is primarily intended for moving out values in drop.
91 /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
92 /// you can use this method to take the value and use it however desired.
93 /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
95 /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
99 /// This function semantically moves out the contained value without preventing further usage.
100 /// It is up to the user of this method to ensure that this container is not used again.
102 /// [`ManuallyDrop::drop`]: #method.drop
103 /// [`ManuallyDrop::into_inner`]: #method.into_inner
104 #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
105 #[unstable(feature = "manually_drop_take", issue = "55422")]
107 pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
108 ManuallyDrop::into_inner(ptr::read(slot))
112 impl<T: ?Sized> ManuallyDrop<T> {
113 /// Manually drops the contained value.
115 /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
119 /// This function runs the destructor of the contained value and thus the wrapped value
120 /// now represents uninitialized data. It is up to the user of this method to ensure the
121 /// uninitialized data is not actually used.
122 /// In particular, this function can only be called called at most once
123 /// for a given instance of `ManuallyDrop<T>`.
125 /// [`ManuallyDrop::into_inner`]: #method.into_inner
126 #[stable(feature = "manually_drop", since = "1.20.0")]
128 pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
129 ptr::drop_in_place(&mut slot.value)
133 #[stable(feature = "manually_drop", since = "1.20.0")]
134 impl<T: ?Sized> Deref for ManuallyDrop<T> {
137 fn deref(&self) -> &T {
142 #[stable(feature = "manually_drop", since = "1.20.0")]
143 impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
145 fn deref_mut(&mut self) -> &mut T {