1 //! Newtype wrappers over raw pointers that document ownership. We use these in 2 //! various places instead of safe references because our type-punning would 3 //! trigger UB otherwise. 4 5 use core::{marker::PhantomData, ptr::NonNull}; 6 use std_alloc::boxed::Box; 7 8 /// A raw, owned pointer. 9 /// 10 /// You are required to call `T`'s `Drop` and deallocate the pointer, this won't 11 /// automatically do it for you like `Box`. 12 #[repr(transparent)] 13 pub(crate) struct OwnedPtr<T> 14 where 15 T: ?Sized, 16 { 17 ptr: NonNull<T>, 18 } 19 20 impl<T> OwnedPtr<T> { new(ptr: NonNull<T>) -> Self21 pub(crate) fn new(ptr: NonNull<T>) -> Self { 22 OwnedPtr { ptr } 23 } 24 cast<U>(self) -> OwnedPtr<U>25 pub(crate) fn cast<U>(self) -> OwnedPtr<U> { 26 OwnedPtr::new(self.ptr.cast()) 27 } 28 29 /// Make a raw copy of this pointer. raw_copy(&self) -> Self30 pub(crate) fn raw_copy(&self) -> Self { 31 Self::new(self.ptr) 32 } 33 into_non_null(self) -> NonNull<T>34 pub(crate) fn into_non_null(self) -> NonNull<T> { 35 self.ptr 36 } 37 38 /// # Safety 39 /// 40 /// It must be valid to call `NonNull::<T>::as_ref` on our underlying pointer. as_ref(&self) -> &T41 pub(crate) unsafe fn as_ref(&self) -> &T { 42 unsafe { self.ptr.as_ref() } 43 } 44 45 /// # Safety 46 /// 47 /// It must be valid to call `Box::<T>::from_raw` on our underlying pointer. into_box(self) -> Box<T>48 pub(crate) unsafe fn into_box(self) -> Box<T> { 49 // Safety: same as our safety contract. 50 unsafe { Box::from_raw(self.ptr.as_ptr()) } 51 } 52 } 53 54 /// A raw pointer that is semantically a shared borrow. 55 #[repr(transparent)] 56 pub(crate) struct SharedPtr<'a, T> 57 where 58 T: ?Sized, 59 { 60 ptr: NonNull<T>, 61 _lifetime: PhantomData<&'a T>, 62 } 63 64 impl<'a, T> core::fmt::Debug for SharedPtr<'a, T> 65 where 66 T: ?Sized, 67 { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result68 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 69 f.debug_struct("SharedPtr").field("ptr", &self.ptr).finish() 70 } 71 } 72 73 impl<T> Clone for SharedPtr<'_, T> 74 where 75 T: ?Sized, 76 { clone(&self) -> Self77 fn clone(&self) -> Self { 78 *self 79 } 80 } 81 82 impl<'a, T> SharedPtr<'a, T> 83 where 84 T: ?Sized, 85 { new(ptr: NonNull<T>) -> Self86 pub(crate) fn new(ptr: NonNull<T>) -> Self { 87 SharedPtr { 88 ptr, 89 _lifetime: PhantomData, 90 } 91 } 92 cast<U>(self) -> SharedPtr<'a, U>93 pub(crate) fn cast<U>(self) -> SharedPtr<'a, U> { 94 SharedPtr::new(self.ptr.cast()) 95 } 96 97 /// # Safety 98 /// 99 /// It must be valid to call `NonNull::<T>::as_ref` on the underlying 100 /// pointer. as_ref(self) -> &'a T101 pub(crate) unsafe fn as_ref(self) -> &'a T { 102 unsafe { self.ptr.as_ref() } 103 } 104 } 105 106 impl<T> Copy for SharedPtr<'_, T> where T: ?Sized {} 107 108 /// A raw pointer that is semantically an exclusive borrow. 109 #[repr(transparent)] 110 pub(crate) struct MutPtr<'a, T> 111 where 112 T: ?Sized, 113 { 114 ptr: NonNull<T>, 115 _lifetime: PhantomData<&'a mut T>, 116 } 117 118 impl<'a, T> MutPtr<'a, T> 119 where 120 T: ?Sized, 121 { new(ptr: NonNull<T>) -> Self122 pub(crate) fn new(ptr: NonNull<T>) -> Self { 123 MutPtr { 124 ptr, 125 _lifetime: PhantomData, 126 } 127 } 128 129 /// Make a raw copy of this pointer. raw_copy(&self) -> Self130 pub(crate) fn raw_copy(&self) -> Self { 131 Self::new(self.ptr) 132 } 133 cast<U>(self) -> MutPtr<'a, U>134 pub(crate) fn cast<U>(self) -> MutPtr<'a, U> { 135 MutPtr::new(self.ptr.cast()) 136 } 137 138 /// # Safety 139 /// 140 /// It must be valid to call `NonNull::<T>::as_ref` on the underlying pointer. as_ref(&self) -> &'a T141 pub(crate) unsafe fn as_ref(&self) -> &'a T { 142 unsafe { self.ptr.as_ref() } 143 } 144 145 /// # Safety 146 /// 147 /// It must be valid to call `NonNull::<T>::as_mut` on the underlying pointer. as_mut(&mut self) -> &'a mut T148 pub(crate) unsafe fn as_mut(&mut self) -> &'a mut T { 149 unsafe { self.ptr.as_mut() } 150 } 151 } 152