| 1 | use crate::ops::{Deref, DerefMut, DerefPure}; |
| 2 | use crate::ptr; |
| 3 | |
| 4 | /// A wrapper to inhibit the compiler from automatically calling `T`’s |
| 5 | /// destructor. 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 |
| 9 | /// consequence, it has *no effect* on the assumptions that the compiler makes |
| 10 | /// about its contents. For example, initializing a `ManuallyDrop<&mut T>` with |
| 11 | /// [`mem::zeroed`] is undefined behavior. If you need to handle uninitialized |
| 12 | /// data, use [`MaybeUninit<T>`] instead. |
| 13 | /// |
| 14 | /// Note that accessing the value inside a `ManuallyDrop<T>` is safe. This means |
| 15 | /// that a `ManuallyDrop<T>` whose content has been dropped must not be exposed |
| 16 | /// through a public safe API. Correspondingly, `ManuallyDrop::drop` is unsafe. |
| 17 | /// |
| 18 | /// # `ManuallyDrop` and drop order |
| 19 | /// |
| 20 | /// Rust has a well-defined [drop order] of values. To make sure that fields or |
| 21 | /// locals are dropped in a specific order, reorder the declarations such that |
| 22 | /// the implicit drop order is the correct one. |
| 23 | /// |
| 24 | /// It is possible to use `ManuallyDrop` to control the drop order, but this |
| 25 | /// requires unsafe code and is hard to do correctly in the presence of |
| 26 | /// unwinding. |
| 27 | /// |
| 28 | /// For example, if you want to make sure that a specific field is dropped after |
| 29 | /// the others, make it the last field of a struct: |
| 30 | /// |
| 31 | /// ``` |
| 32 | /// struct Context; |
| 33 | /// |
| 34 | /// struct Widget { |
| 35 | /// children: Vec<Widget>, |
| 36 | /// // `context` will be dropped after `children`. |
| 37 | /// // Rust guarantees that fields are dropped in the order of declaration. |
| 38 | /// context: Context, |
| 39 | /// } |
| 40 | /// ``` |
| 41 | /// |
| 42 | /// # Interaction with `Box` |
| 43 | /// |
| 44 | /// Currently, if you have a `ManuallyDrop<T>`, where the type `T` is a `Box` or |
| 45 | /// contains a `Box` inside, then dropping the `T` followed by moving the |
| 46 | /// `ManuallyDrop<T>` is [considered to be undefined |
| 47 | /// behavior](https://github.com/rust-lang/unsafe-code-guidelines/issues/245). |
| 48 | /// That is, the following code causes undefined behavior: |
| 49 | /// |
| 50 | /// ```no_run |
| 51 | /// use std::mem::ManuallyDrop; |
| 52 | /// |
| 53 | /// let mut x = ManuallyDrop::new(Box::new(42)); |
| 54 | /// unsafe { |
| 55 | /// ManuallyDrop::drop(&mut x); |
| 56 | /// } |
| 57 | /// let y = x; // Undefined behavior! |
| 58 | /// ``` |
| 59 | /// |
| 60 | /// This is [likely to change in the |
| 61 | /// future](https://rust-lang.github.io/rfcs/3336-maybe-dangling.html). In the |
| 62 | /// meantime, consider using [`MaybeUninit`] instead. |
| 63 | /// |
| 64 | /// # Safety hazards when storing `ManuallyDrop` in a struct or an enum. |
| 65 | /// |
| 66 | /// Special care is needed when all of the conditions below are met: |
| 67 | /// * A struct or enum contains a `ManuallyDrop`. |
| 68 | /// * The `ManuallyDrop` is not inside a `union`. |
| 69 | /// * The struct or enum is part of public API, or is stored in a struct or an |
| 70 | /// enum that is part of public API. |
| 71 | /// * There is code that drops the contents of the `ManuallyDrop` field, and |
| 72 | /// this code is outside the struct or enum's `Drop` implementation. |
| 73 | /// |
| 74 | /// In particular, the following hazards may occur: |
| 75 | /// |
| 76 | /// #### Storing generic types |
| 77 | /// |
| 78 | /// If the `ManuallyDrop` contains a client-supplied generic type, the client |
| 79 | /// might provide a `Box` as that type. This would cause undefined behavior when |
| 80 | /// the struct or enum is later moved, as mentioned in the previous section. For |
| 81 | /// example, the following code causes undefined behavior: |
| 82 | /// |
| 83 | /// ```no_run |
| 84 | /// use std::mem::ManuallyDrop; |
| 85 | /// |
| 86 | /// pub struct BadOption<T> { |
| 87 | /// // Invariant: Has been dropped if `is_some` is false. |
| 88 | /// value: ManuallyDrop<T>, |
| 89 | /// is_some: bool, |
| 90 | /// } |
| 91 | /// impl<T> BadOption<T> { |
| 92 | /// pub fn new(value: T) -> Self { |
| 93 | /// Self { value: ManuallyDrop::new(value), is_some: true } |
| 94 | /// } |
| 95 | /// pub fn change_to_none(&mut self) { |
| 96 | /// if self.is_some { |
| 97 | /// self.is_some = false; |
| 98 | /// unsafe { |
| 99 | /// // SAFETY: `value` hasn't been dropped yet, as per the invariant |
| 100 | /// // (This is actually unsound!) |
| 101 | /// ManuallyDrop::drop(&mut self.value); |
| 102 | /// } |
| 103 | /// } |
| 104 | /// } |
| 105 | /// } |
| 106 | /// |
| 107 | /// // In another crate: |
| 108 | /// |
| 109 | /// let mut option = BadOption::new(Box::new(42)); |
| 110 | /// option.change_to_none(); |
| 111 | /// let option2 = option; // Undefined behavior! |
| 112 | /// ``` |
| 113 | /// |
| 114 | /// #### Deriving traits |
| 115 | /// |
| 116 | /// Deriving `Debug`, `Clone`, `PartialEq`, `PartialOrd`, `Ord`, or `Hash` on |
| 117 | /// the struct or enum could be unsound, since the derived implementations of |
| 118 | /// these traits would access the `ManuallyDrop` field. For example, the |
| 119 | /// following code causes undefined behavior: |
| 120 | /// |
| 121 | /// ```no_run |
| 122 | /// use std::mem::ManuallyDrop; |
| 123 | /// |
| 124 | /// // This derive is unsound in combination with the `ManuallyDrop::drop` call. |
| 125 | /// #[derive(Debug)] |
| 126 | /// pub struct Foo { |
| 127 | /// value: ManuallyDrop<String>, |
| 128 | /// } |
| 129 | /// impl Foo { |
| 130 | /// pub fn new() -> Self { |
| 131 | /// let mut temp = Self { |
| 132 | /// value: ManuallyDrop::new(String::from("Unsafe rust is hard." )) |
| 133 | /// }; |
| 134 | /// unsafe { |
| 135 | /// // SAFETY: `value` hasn't been dropped yet. |
| 136 | /// ManuallyDrop::drop(&mut temp.value); |
| 137 | /// } |
| 138 | /// temp |
| 139 | /// } |
| 140 | /// } |
| 141 | /// |
| 142 | /// // In another crate: |
| 143 | /// |
| 144 | /// let foo = Foo::new(); |
| 145 | /// println!("{:?}" , foo); // Undefined behavior! |
| 146 | /// ``` |
| 147 | /// |
| 148 | /// [drop order]: https://doc.rust-lang.org/reference/destructors.html |
| 149 | /// [`mem::zeroed`]: crate::mem::zeroed |
| 150 | /// [`MaybeUninit<T>`]: crate::mem::MaybeUninit |
| 151 | /// [`MaybeUninit`]: crate::mem::MaybeUninit |
| 152 | #[stable (feature = "manually_drop" , since = "1.20.0" )] |
| 153 | #[lang = "manually_drop" ] |
| 154 | #[derive (Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 155 | #[repr (transparent)] |
| 156 | #[rustc_pub_transparent] |
| 157 | pub struct ManuallyDrop<T: ?Sized> { |
| 158 | value: T, |
| 159 | } |
| 160 | |
| 161 | impl<T> ManuallyDrop<T> { |
| 162 | /// Wrap a value to be manually dropped. |
| 163 | /// |
| 164 | /// # Examples |
| 165 | /// |
| 166 | /// ```rust |
| 167 | /// use std::mem::ManuallyDrop; |
| 168 | /// let mut x = ManuallyDrop::new(String::from("Hello World!" )); |
| 169 | /// x.truncate(5); // You can still safely operate on the value |
| 170 | /// assert_eq!(*x, "Hello" ); |
| 171 | /// // But `Drop` will not be run here |
| 172 | /// # // FIXME(https://github.com/rust-lang/miri/issues/3670): |
| 173 | /// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak. |
| 174 | /// # let _ = ManuallyDrop::into_inner(x); |
| 175 | /// ``` |
| 176 | #[must_use = "if you don't need the wrapper, you can use `mem::forget` instead" ] |
| 177 | #[stable (feature = "manually_drop" , since = "1.20.0" )] |
| 178 | #[rustc_const_stable (feature = "const_manually_drop" , since = "1.32.0" )] |
| 179 | #[inline (always)] |
| 180 | pub const fn new(value: T) -> ManuallyDrop<T> { |
| 181 | ManuallyDrop { value } |
| 182 | } |
| 183 | |
| 184 | /// Extracts the value from the `ManuallyDrop` container. |
| 185 | /// |
| 186 | /// This allows the value to be dropped again. |
| 187 | /// |
| 188 | /// # Examples |
| 189 | /// |
| 190 | /// ```rust |
| 191 | /// use std::mem::ManuallyDrop; |
| 192 | /// let x = ManuallyDrop::new(Box::new(())); |
| 193 | /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`. |
| 194 | /// ``` |
| 195 | #[stable (feature = "manually_drop" , since = "1.20.0" )] |
| 196 | #[rustc_const_stable (feature = "const_manually_drop" , since = "1.32.0" )] |
| 197 | #[inline (always)] |
| 198 | pub const fn into_inner(slot: ManuallyDrop<T>) -> T { |
| 199 | slot.value |
| 200 | } |
| 201 | |
| 202 | /// Takes the value from the `ManuallyDrop<T>` container out. |
| 203 | /// |
| 204 | /// This method is primarily intended for moving out values in drop. |
| 205 | /// Instead of using [`ManuallyDrop::drop`] to manually drop the value, |
| 206 | /// you can use this method to take the value and use it however desired. |
| 207 | /// |
| 208 | /// Whenever possible, it is preferable to use [`into_inner`][`ManuallyDrop::into_inner`] |
| 209 | /// instead, which prevents duplicating the content of the `ManuallyDrop<T>`. |
| 210 | /// |
| 211 | /// # Safety |
| 212 | /// |
| 213 | /// This function semantically moves out the contained value without preventing further usage, |
| 214 | /// leaving the state of this container unchanged. |
| 215 | /// It is your responsibility to ensure that this `ManuallyDrop` is not used again. |
| 216 | /// |
| 217 | #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead" ] |
| 218 | #[stable (feature = "manually_drop_take" , since = "1.42.0" )] |
| 219 | #[inline ] |
| 220 | pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T { |
| 221 | // SAFETY: we are reading from a reference, which is guaranteed |
| 222 | // to be valid for reads. |
| 223 | unsafe { ptr::read(&slot.value) } |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | impl<T: ?Sized> ManuallyDrop<T> { |
| 228 | /// Manually drops the contained value. |
| 229 | /// |
| 230 | /// This is exactly equivalent to calling [`ptr::drop_in_place`] with a |
| 231 | /// pointer to the contained value. As such, unless the contained value is a |
| 232 | /// packed struct, the destructor will be called in-place without moving the |
| 233 | /// value, and thus can be used to safely drop [pinned] data. |
| 234 | /// |
| 235 | /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead. |
| 236 | /// |
| 237 | /// # Safety |
| 238 | /// |
| 239 | /// This function runs the destructor of the contained value. Other than changes made by |
| 240 | /// the destructor itself, the memory is left unchanged, and so as far as the compiler is |
| 241 | /// concerned still holds a bit-pattern which is valid for the type `T`. |
| 242 | /// |
| 243 | /// However, this "zombie" value should not be exposed to safe code, and this function |
| 244 | /// should not be called more than once. To use a value after it's been dropped, or drop |
| 245 | /// a value multiple times, can cause Undefined Behavior (depending on what `drop` does). |
| 246 | /// This is normally prevented by the type system, but users of `ManuallyDrop` must |
| 247 | /// uphold those guarantees without assistance from the compiler. |
| 248 | /// |
| 249 | /// [pinned]: crate::pin |
| 250 | #[stable (feature = "manually_drop" , since = "1.20.0" )] |
| 251 | #[inline ] |
| 252 | pub unsafe fn drop(slot: &mut ManuallyDrop<T>) { |
| 253 | // SAFETY: we are dropping the value pointed to by a mutable reference |
| 254 | // which is guaranteed to be valid for writes. |
| 255 | // It is up to the caller to make sure that `slot` isn't dropped again. |
| 256 | unsafe { ptr::drop_in_place(&mut slot.value) } |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | #[stable (feature = "manually_drop" , since = "1.20.0" )] |
| 261 | impl<T: ?Sized> Deref for ManuallyDrop<T> { |
| 262 | type Target = T; |
| 263 | #[inline (always)] |
| 264 | fn deref(&self) -> &T { |
| 265 | &self.value |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | #[stable (feature = "manually_drop" , since = "1.20.0" )] |
| 270 | impl<T: ?Sized> DerefMut for ManuallyDrop<T> { |
| 271 | #[inline (always)] |
| 272 | fn deref_mut(&mut self) -> &mut T { |
| 273 | &mut self.value |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | #[unstable (feature = "deref_pure_trait" , issue = "87121" )] |
| 278 | unsafe impl<T: ?Sized> DerefPure for ManuallyDrop<T> {} |
| 279 | |