1 | use crate::ops::{Deref, DerefMut}; |
2 | use 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)] |
50 | pub struct ManuallyDrop<T: ?Sized> { |
51 | value: T, |
52 | } |
53 | |
54 | impl<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 | |
117 | impl<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" )] |
149 | impl<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" )] |
158 | impl<T: ?Sized> DerefMut for ManuallyDrop<T> { |
159 | #[inline (always)] |
160 | fn deref_mut(&mut self) -> &mut T { |
161 | &mut self.value |
162 | } |
163 | } |
164 | |