1use crate::ops::{Deref, DerefMut};
2use crate::ptr;
3
4/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
5/// This wrapper is 0-cost.
6///
7/// `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
8/// `T`, and is subject to the same layout optimizations as `T`. As a consequence,
9/// it has *no effect* on the assumptions that the compiler makes about its
10/// contents. For example, initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`]
11/// is undefined behavior. If you need to handle uninitialized data, use
12/// [`MaybeUninit<T>`] instead.
13///
14/// Note that accessing the value inside a `ManuallyDrop<T>` is safe.
15/// This means that a `ManuallyDrop<T>` whose content has been dropped must not
16/// be exposed through a public safe API.
17/// Correspondingly, `ManuallyDrop::drop` is unsafe.
18///
19/// # `ManuallyDrop` and drop order.
20///
21/// Rust has a well-defined [drop order] of values. To make sure that fields or
22/// locals are dropped in a specific order, reorder the declarations such that
23/// the implicit drop order is the correct one.
24///
25/// It is possible to use `ManuallyDrop` to control the drop order, but this
26/// requires unsafe code and is hard to do correctly in the presence of
27/// unwinding.
28///
29/// For example, if you want to make sure that a specific field is dropped after
30/// the others, make it the last field of a struct:
31///
32/// ```
33/// struct Context;
34///
35/// struct Widget {
36/// children: Vec<Widget>,
37/// // `context` will be dropped after `children`.
38/// // Rust guarantees that fields are dropped in the order of declaration.
39/// context: Context,
40/// }
41/// ```
42///
43/// [drop order]: https://doc.rust-lang.org/reference/destructors.html
44/// [`mem::zeroed`]: crate::mem::zeroed
45/// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
46#[stable(feature = "manually_drop", since = "1.20.0")]
47#[lang = "manually_drop"]
48#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
49#[repr(transparent)]
50pub struct ManuallyDrop<T: ?Sized> {
51 value: T,
52}
53
54impl<T> ManuallyDrop<T> {
55 /// Wrap a value to be manually dropped.
56 ///
57 /// # Examples
58 ///
59 /// ```rust
60 /// use std::mem::ManuallyDrop;
61 /// let mut x = ManuallyDrop::new(String::from("Hello World!"));
62 /// x.truncate(5); // You can still safely operate on the value
63 /// assert_eq!(*x, "Hello");
64 /// // But `Drop` will not be run here
65 /// ```
66 #[must_use = "if you don't need the wrapper, you can use `mem::forget` instead"]
67 #[stable(feature = "manually_drop", since = "1.20.0")]
68 #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")]
69 #[inline(always)]
70 pub const fn new(value: T) -> ManuallyDrop<T> {
71 ManuallyDrop { value }
72 }
73
74 /// Extracts the value from the `ManuallyDrop` container.
75 ///
76 /// This allows the value to be dropped again.
77 ///
78 /// # Examples
79 ///
80 /// ```rust
81 /// use std::mem::ManuallyDrop;
82 /// let x = ManuallyDrop::new(Box::new(()));
83 /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
84 /// ```
85 #[stable(feature = "manually_drop", since = "1.20.0")]
86 #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")]
87 #[inline(always)]
88 pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
89 slot.value
90 }
91
92 /// Takes the value from the `ManuallyDrop<T>` container out.
93 ///
94 /// This method is primarily intended for moving out values in drop.
95 /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
96 /// you can use this method to take the value and use it however desired.
97 ///
98 /// Whenever possible, it is preferable to use [`into_inner`][`ManuallyDrop::into_inner`]
99 /// instead, which prevents duplicating the content of the `ManuallyDrop<T>`.
100 ///
101 /// # Safety
102 ///
103 /// This function semantically moves out the contained value without preventing further usage,
104 /// leaving the state of this container unchanged.
105 /// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
106 ///
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")]
109 #[inline]
110 pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
111 // SAFETY: we are reading from a reference, which is guaranteed
112 // to be valid for reads.
113 unsafe { ptr::read(&slot.value) }
114 }
115}
116
117impl<T: ?Sized> ManuallyDrop<T> {
118 /// Manually drops the contained value. This is exactly equivalent to calling
119 /// [`ptr::drop_in_place`] with a pointer to the contained value. As such, unless
120 /// the contained value is a packed struct, the destructor will be called in-place
121 /// without moving the value, and thus can be used to safely drop [pinned] data.
122 ///
123 /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
124 ///
125 /// # Safety
126 ///
127 /// This function runs the destructor of the contained value. Other than changes made by
128 /// the destructor itself, the memory is left unchanged, and so as far as the compiler is
129 /// concerned still holds a bit-pattern which is valid for the type `T`.
130 ///
131 /// However, this "zombie" value should not be exposed to safe code, and this function
132 /// should not be called more than once. To use a value after it's been dropped, or drop
133 /// a value multiple times, can cause Undefined Behavior (depending on what `drop` does).
134 /// This is normally prevented by the type system, but users of `ManuallyDrop` must
135 /// uphold those guarantees without assistance from the compiler.
136 ///
137 /// [pinned]: crate::pin
138 #[stable(feature = "manually_drop", since = "1.20.0")]
139 #[inline]
140 pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
141 // SAFETY: we are dropping the value pointed to by a mutable reference
142 // which is guaranteed to be valid for writes.
143 // It is up to the caller to make sure that `slot` isn't dropped again.
144 unsafe { ptr::drop_in_place(&mut slot.value) }
145 }
146}
147
148#[stable(feature = "manually_drop", since = "1.20.0")]
149impl<T: ?Sized> Deref for ManuallyDrop<T> {
150 type Target = T;
151 #[inline(always)]
152 fn deref(&self) -> &T {
153 &self.value
154 }
155}
156
157#[stable(feature = "manually_drop", since = "1.20.0")]
158impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
159 #[inline(always)]
160 fn deref_mut(&mut self) -> &mut T {
161 &mut self.value
162 }
163}
164