unsafe_box.rs (1970B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 #![allow(unsafe_code)] 6 7 use std::mem::ManuallyDrop; 8 use std::ops::Deref; 9 use std::ptr; 10 11 /// An unsafe box, derefs to `T`. 12 pub(super) struct UnsafeBox<T> { 13 inner: ManuallyDrop<Box<T>>, 14 } 15 16 impl<T> UnsafeBox<T> { 17 /// Creates a new unsafe box. 18 pub(super) fn from_box(value: Box<T>) -> Self { 19 Self { 20 inner: ManuallyDrop::new(value), 21 } 22 } 23 24 /// Creates a new box from a pointer. 25 /// 26 /// # Safety 27 /// 28 /// The input should point to a valid `T`. 29 pub(super) unsafe fn from_raw(ptr: *mut T) -> Self { 30 Self { 31 inner: ManuallyDrop::new(Box::from_raw(ptr)), 32 } 33 } 34 35 /// Creates a new unsafe box from an existing one. 36 /// 37 /// # Safety 38 /// 39 /// There is no refcounting or whatever else in an unsafe box, so this 40 /// operation can lead to double frees. 41 pub(super) unsafe fn clone(this: &Self) -> Self { 42 Self { 43 inner: ptr::read(&this.inner), 44 } 45 } 46 47 /// Returns a mutable reference to the inner value of this unsafe box. 48 /// 49 /// # Safety 50 /// 51 /// Given `Self::clone`, nothing prevents anyone from creating 52 /// multiple mutable references to the inner value, which is completely UB. 53 pub(crate) unsafe fn deref_mut(this: &mut Self) -> &mut T { 54 &mut this.inner 55 } 56 57 /// Drops the inner value of this unsafe box. 58 /// 59 /// # Safety 60 /// 61 /// Given this doesn't consume the unsafe box itself, this has the same 62 /// safety caveats as `ManuallyDrop::drop`. 63 pub(super) unsafe fn drop(this: &mut Self) { 64 ManuallyDrop::drop(&mut this.inner) 65 } 66 } 67 68 impl<T> Deref for UnsafeBox<T> { 69 type Target = T; 70 71 fn deref(&self) -> &Self::Target { 72 &self.inner 73 } 74 }