1*c8cfa8d0SDanilo Krummrich // SPDX-License-Identifier: GPL-2.0 2*c8cfa8d0SDanilo Krummrich 3*c8cfa8d0SDanilo Krummrich //! Implementation of [`Box`]. 4*c8cfa8d0SDanilo Krummrich 5*c8cfa8d0SDanilo Krummrich #[allow(unused_imports)] // Used in doc comments. 6*c8cfa8d0SDanilo Krummrich use super::allocator::{KVmalloc, Kmalloc, Vmalloc}; 7*c8cfa8d0SDanilo Krummrich use super::{AllocError, Allocator, Flags}; 8*c8cfa8d0SDanilo Krummrich use core::alloc::Layout; 9*c8cfa8d0SDanilo Krummrich use core::fmt; 10*c8cfa8d0SDanilo Krummrich use core::marker::PhantomData; 11*c8cfa8d0SDanilo Krummrich use core::mem::ManuallyDrop; 12*c8cfa8d0SDanilo Krummrich use core::mem::MaybeUninit; 13*c8cfa8d0SDanilo Krummrich use core::ops::{Deref, DerefMut}; 14*c8cfa8d0SDanilo Krummrich use core::pin::Pin; 15*c8cfa8d0SDanilo Krummrich use core::ptr::NonNull; 16*c8cfa8d0SDanilo Krummrich use core::result::Result; 17*c8cfa8d0SDanilo Krummrich 18*c8cfa8d0SDanilo Krummrich use crate::init::{InPlaceInit, InPlaceWrite, Init, PinInit}; 19*c8cfa8d0SDanilo Krummrich use crate::types::ForeignOwnable; 20*c8cfa8d0SDanilo Krummrich 21*c8cfa8d0SDanilo Krummrich /// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. 22*c8cfa8d0SDanilo Krummrich /// 23*c8cfa8d0SDanilo Krummrich /// This is the kernel's version of the Rust stdlib's `Box`. There are several differences, 24*c8cfa8d0SDanilo Krummrich /// for example no `noalias` attribute is emitted and partially moving out of a `Box` is not 25*c8cfa8d0SDanilo Krummrich /// supported. There are also several API differences, e.g. `Box` always requires an [`Allocator`] 26*c8cfa8d0SDanilo Krummrich /// implementation to be passed as generic, page [`Flags`] when allocating memory and all functions 27*c8cfa8d0SDanilo Krummrich /// that may allocate memory are fallible. 28*c8cfa8d0SDanilo Krummrich /// 29*c8cfa8d0SDanilo Krummrich /// `Box` works with any of the kernel's allocators, e.g. [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`]. 30*c8cfa8d0SDanilo Krummrich /// There are aliases for `Box` with these allocators ([`KBox`], [`VBox`], [`KVBox`]). 31*c8cfa8d0SDanilo Krummrich /// 32*c8cfa8d0SDanilo Krummrich /// When dropping a [`Box`], the value is also dropped and the heap memory is automatically freed. 33*c8cfa8d0SDanilo Krummrich /// 34*c8cfa8d0SDanilo Krummrich /// # Examples 35*c8cfa8d0SDanilo Krummrich /// 36*c8cfa8d0SDanilo Krummrich /// ``` 37*c8cfa8d0SDanilo Krummrich /// let b = KBox::<u64>::new(24_u64, GFP_KERNEL)?; 38*c8cfa8d0SDanilo Krummrich /// 39*c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 40*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 41*c8cfa8d0SDanilo Krummrich /// ``` 42*c8cfa8d0SDanilo Krummrich /// 43*c8cfa8d0SDanilo Krummrich /// ``` 44*c8cfa8d0SDanilo Krummrich /// # use kernel::bindings; 45*c8cfa8d0SDanilo Krummrich /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 46*c8cfa8d0SDanilo Krummrich /// struct Huge([u8; SIZE]); 47*c8cfa8d0SDanilo Krummrich /// 48*c8cfa8d0SDanilo Krummrich /// assert!(KBox::<Huge>::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err()); 49*c8cfa8d0SDanilo Krummrich /// ``` 50*c8cfa8d0SDanilo Krummrich /// 51*c8cfa8d0SDanilo Krummrich /// ``` 52*c8cfa8d0SDanilo Krummrich /// # use kernel::bindings; 53*c8cfa8d0SDanilo Krummrich /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 54*c8cfa8d0SDanilo Krummrich /// struct Huge([u8; SIZE]); 55*c8cfa8d0SDanilo Krummrich /// 56*c8cfa8d0SDanilo Krummrich /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 57*c8cfa8d0SDanilo Krummrich /// ``` 58*c8cfa8d0SDanilo Krummrich /// 59*c8cfa8d0SDanilo Krummrich /// # Invariants 60*c8cfa8d0SDanilo Krummrich /// 61*c8cfa8d0SDanilo Krummrich /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 62*c8cfa8d0SDanilo Krummrich /// zero-sized types, is a dangling, well aligned pointer. 63*c8cfa8d0SDanilo Krummrich #[repr(transparent)] 64*c8cfa8d0SDanilo Krummrich pub struct Box<T: ?Sized, A: Allocator>(NonNull<T>, PhantomData<A>); 65*c8cfa8d0SDanilo Krummrich 66*c8cfa8d0SDanilo Krummrich /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 67*c8cfa8d0SDanilo Krummrich /// 68*c8cfa8d0SDanilo Krummrich /// # Examples 69*c8cfa8d0SDanilo Krummrich /// 70*c8cfa8d0SDanilo Krummrich /// ``` 71*c8cfa8d0SDanilo Krummrich /// let b = KBox::new(24_u64, GFP_KERNEL)?; 72*c8cfa8d0SDanilo Krummrich /// 73*c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 74*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 75*c8cfa8d0SDanilo Krummrich /// ``` 76*c8cfa8d0SDanilo Krummrich pub type KBox<T> = Box<T, super::allocator::Kmalloc>; 77*c8cfa8d0SDanilo Krummrich 78*c8cfa8d0SDanilo Krummrich /// Type alias for [`Box`] with a [`Vmalloc`] allocator. 79*c8cfa8d0SDanilo Krummrich /// 80*c8cfa8d0SDanilo Krummrich /// # Examples 81*c8cfa8d0SDanilo Krummrich /// 82*c8cfa8d0SDanilo Krummrich /// ``` 83*c8cfa8d0SDanilo Krummrich /// let b = VBox::new(24_u64, GFP_KERNEL)?; 84*c8cfa8d0SDanilo Krummrich /// 85*c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 86*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 87*c8cfa8d0SDanilo Krummrich /// ``` 88*c8cfa8d0SDanilo Krummrich pub type VBox<T> = Box<T, super::allocator::Vmalloc>; 89*c8cfa8d0SDanilo Krummrich 90*c8cfa8d0SDanilo Krummrich /// Type alias for [`Box`] with a [`KVmalloc`] allocator. 91*c8cfa8d0SDanilo Krummrich /// 92*c8cfa8d0SDanilo Krummrich /// # Examples 93*c8cfa8d0SDanilo Krummrich /// 94*c8cfa8d0SDanilo Krummrich /// ``` 95*c8cfa8d0SDanilo Krummrich /// let b = KVBox::new(24_u64, GFP_KERNEL)?; 96*c8cfa8d0SDanilo Krummrich /// 97*c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 98*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 99*c8cfa8d0SDanilo Krummrich /// ``` 100*c8cfa8d0SDanilo Krummrich pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 101*c8cfa8d0SDanilo Krummrich 102*c8cfa8d0SDanilo Krummrich // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. 103*c8cfa8d0SDanilo Krummrich unsafe impl<T, A> Send for Box<T, A> 104*c8cfa8d0SDanilo Krummrich where 105*c8cfa8d0SDanilo Krummrich T: Send + ?Sized, 106*c8cfa8d0SDanilo Krummrich A: Allocator, 107*c8cfa8d0SDanilo Krummrich { 108*c8cfa8d0SDanilo Krummrich } 109*c8cfa8d0SDanilo Krummrich 110*c8cfa8d0SDanilo Krummrich // SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`. 111*c8cfa8d0SDanilo Krummrich unsafe impl<T, A> Sync for Box<T, A> 112*c8cfa8d0SDanilo Krummrich where 113*c8cfa8d0SDanilo Krummrich T: Sync + ?Sized, 114*c8cfa8d0SDanilo Krummrich A: Allocator, 115*c8cfa8d0SDanilo Krummrich { 116*c8cfa8d0SDanilo Krummrich } 117*c8cfa8d0SDanilo Krummrich 118*c8cfa8d0SDanilo Krummrich impl<T, A> Box<T, A> 119*c8cfa8d0SDanilo Krummrich where 120*c8cfa8d0SDanilo Krummrich T: ?Sized, 121*c8cfa8d0SDanilo Krummrich A: Allocator, 122*c8cfa8d0SDanilo Krummrich { 123*c8cfa8d0SDanilo Krummrich /// Creates a new `Box<T, A>` from a raw pointer. 124*c8cfa8d0SDanilo Krummrich /// 125*c8cfa8d0SDanilo Krummrich /// # Safety 126*c8cfa8d0SDanilo Krummrich /// 127*c8cfa8d0SDanilo Krummrich /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently 128*c8cfa8d0SDanilo Krummrich /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the 129*c8cfa8d0SDanilo Krummrich /// `Box`. 130*c8cfa8d0SDanilo Krummrich /// 131*c8cfa8d0SDanilo Krummrich /// For ZSTs, `raw` must be a dangling, well aligned pointer. 132*c8cfa8d0SDanilo Krummrich #[inline] 133*c8cfa8d0SDanilo Krummrich pub const unsafe fn from_raw(raw: *mut T) -> Self { 134*c8cfa8d0SDanilo Krummrich // INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function. 135*c8cfa8d0SDanilo Krummrich // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer. 136*c8cfa8d0SDanilo Krummrich Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData) 137*c8cfa8d0SDanilo Krummrich } 138*c8cfa8d0SDanilo Krummrich 139*c8cfa8d0SDanilo Krummrich /// Consumes the `Box<T, A>` and returns a raw pointer. 140*c8cfa8d0SDanilo Krummrich /// 141*c8cfa8d0SDanilo Krummrich /// This will not run the destructor of `T` and for non-ZSTs the allocation will stay alive 142*c8cfa8d0SDanilo Krummrich /// indefinitely. Use [`Box::from_raw`] to recover the [`Box`], drop the value and free the 143*c8cfa8d0SDanilo Krummrich /// allocation, if any. 144*c8cfa8d0SDanilo Krummrich /// 145*c8cfa8d0SDanilo Krummrich /// # Examples 146*c8cfa8d0SDanilo Krummrich /// 147*c8cfa8d0SDanilo Krummrich /// ``` 148*c8cfa8d0SDanilo Krummrich /// let x = KBox::new(24, GFP_KERNEL)?; 149*c8cfa8d0SDanilo Krummrich /// let ptr = KBox::into_raw(x); 150*c8cfa8d0SDanilo Krummrich /// // SAFETY: `ptr` comes from a previous call to `KBox::into_raw`. 151*c8cfa8d0SDanilo Krummrich /// let x = unsafe { KBox::from_raw(ptr) }; 152*c8cfa8d0SDanilo Krummrich /// 153*c8cfa8d0SDanilo Krummrich /// assert_eq!(*x, 24); 154*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 155*c8cfa8d0SDanilo Krummrich /// ``` 156*c8cfa8d0SDanilo Krummrich #[inline] 157*c8cfa8d0SDanilo Krummrich pub fn into_raw(b: Self) -> *mut T { 158*c8cfa8d0SDanilo Krummrich ManuallyDrop::new(b).0.as_ptr() 159*c8cfa8d0SDanilo Krummrich } 160*c8cfa8d0SDanilo Krummrich 161*c8cfa8d0SDanilo Krummrich /// Consumes and leaks the `Box<T, A>` and returns a mutable reference. 162*c8cfa8d0SDanilo Krummrich /// 163*c8cfa8d0SDanilo Krummrich /// See [`Box::into_raw`] for more details. 164*c8cfa8d0SDanilo Krummrich #[inline] 165*c8cfa8d0SDanilo Krummrich pub fn leak<'a>(b: Self) -> &'a mut T { 166*c8cfa8d0SDanilo Krummrich // SAFETY: `Box::into_raw` always returns a properly aligned and dereferenceable pointer 167*c8cfa8d0SDanilo Krummrich // which points to an initialized instance of `T`. 168*c8cfa8d0SDanilo Krummrich unsafe { &mut *Box::into_raw(b) } 169*c8cfa8d0SDanilo Krummrich } 170*c8cfa8d0SDanilo Krummrich } 171*c8cfa8d0SDanilo Krummrich 172*c8cfa8d0SDanilo Krummrich impl<T, A> Box<MaybeUninit<T>, A> 173*c8cfa8d0SDanilo Krummrich where 174*c8cfa8d0SDanilo Krummrich A: Allocator, 175*c8cfa8d0SDanilo Krummrich { 176*c8cfa8d0SDanilo Krummrich /// Converts a `Box<MaybeUninit<T>, A>` to a `Box<T, A>`. 177*c8cfa8d0SDanilo Krummrich /// 178*c8cfa8d0SDanilo Krummrich /// It is undefined behavior to call this function while the value inside of `b` is not yet 179*c8cfa8d0SDanilo Krummrich /// fully initialized. 180*c8cfa8d0SDanilo Krummrich /// 181*c8cfa8d0SDanilo Krummrich /// # Safety 182*c8cfa8d0SDanilo Krummrich /// 183*c8cfa8d0SDanilo Krummrich /// Callers must ensure that the value inside of `b` is in an initialized state. 184*c8cfa8d0SDanilo Krummrich pub unsafe fn assume_init(self) -> Box<T, A> { 185*c8cfa8d0SDanilo Krummrich let raw = Self::into_raw(self); 186*c8cfa8d0SDanilo Krummrich 187*c8cfa8d0SDanilo Krummrich // SAFETY: `raw` comes from a previous call to `Box::into_raw`. By the safety requirements 188*c8cfa8d0SDanilo Krummrich // of this function, the value inside the `Box` is in an initialized state. Hence, it is 189*c8cfa8d0SDanilo Krummrich // safe to reconstruct the `Box` as `Box<T, A>`. 190*c8cfa8d0SDanilo Krummrich unsafe { Box::from_raw(raw.cast()) } 191*c8cfa8d0SDanilo Krummrich } 192*c8cfa8d0SDanilo Krummrich 193*c8cfa8d0SDanilo Krummrich /// Writes the value and converts to `Box<T, A>`. 194*c8cfa8d0SDanilo Krummrich pub fn write(mut self, value: T) -> Box<T, A> { 195*c8cfa8d0SDanilo Krummrich (*self).write(value); 196*c8cfa8d0SDanilo Krummrich 197*c8cfa8d0SDanilo Krummrich // SAFETY: We've just initialized `b`'s value. 198*c8cfa8d0SDanilo Krummrich unsafe { self.assume_init() } 199*c8cfa8d0SDanilo Krummrich } 200*c8cfa8d0SDanilo Krummrich } 201*c8cfa8d0SDanilo Krummrich 202*c8cfa8d0SDanilo Krummrich impl<T, A> Box<T, A> 203*c8cfa8d0SDanilo Krummrich where 204*c8cfa8d0SDanilo Krummrich A: Allocator, 205*c8cfa8d0SDanilo Krummrich { 206*c8cfa8d0SDanilo Krummrich /// Creates a new `Box<T, A>` and initializes its contents with `x`. 207*c8cfa8d0SDanilo Krummrich /// 208*c8cfa8d0SDanilo Krummrich /// New memory is allocated with `A`. The allocation may fail, in which case an error is 209*c8cfa8d0SDanilo Krummrich /// returned. For ZSTs no memory is allocated. 210*c8cfa8d0SDanilo Krummrich pub fn new(x: T, flags: Flags) -> Result<Self, AllocError> { 211*c8cfa8d0SDanilo Krummrich let b = Self::new_uninit(flags)?; 212*c8cfa8d0SDanilo Krummrich Ok(Box::write(b, x)) 213*c8cfa8d0SDanilo Krummrich } 214*c8cfa8d0SDanilo Krummrich 215*c8cfa8d0SDanilo Krummrich /// Creates a new `Box<T, A>` with uninitialized contents. 216*c8cfa8d0SDanilo Krummrich /// 217*c8cfa8d0SDanilo Krummrich /// New memory is allocated with `A`. The allocation may fail, in which case an error is 218*c8cfa8d0SDanilo Krummrich /// returned. For ZSTs no memory is allocated. 219*c8cfa8d0SDanilo Krummrich /// 220*c8cfa8d0SDanilo Krummrich /// # Examples 221*c8cfa8d0SDanilo Krummrich /// 222*c8cfa8d0SDanilo Krummrich /// ``` 223*c8cfa8d0SDanilo Krummrich /// let b = KBox::<u64>::new_uninit(GFP_KERNEL)?; 224*c8cfa8d0SDanilo Krummrich /// let b = KBox::write(b, 24); 225*c8cfa8d0SDanilo Krummrich /// 226*c8cfa8d0SDanilo Krummrich /// assert_eq!(*b, 24_u64); 227*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 228*c8cfa8d0SDanilo Krummrich /// ``` 229*c8cfa8d0SDanilo Krummrich pub fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError> { 230*c8cfa8d0SDanilo Krummrich let layout = Layout::new::<MaybeUninit<T>>(); 231*c8cfa8d0SDanilo Krummrich let ptr = A::alloc(layout, flags)?; 232*c8cfa8d0SDanilo Krummrich 233*c8cfa8d0SDanilo Krummrich // INVARIANT: `ptr` is either a dangling pointer or points to memory allocated with `A`, 234*c8cfa8d0SDanilo Krummrich // which is sufficient in size and alignment for storing a `T`. 235*c8cfa8d0SDanilo Krummrich Ok(Box(ptr.cast(), PhantomData)) 236*c8cfa8d0SDanilo Krummrich } 237*c8cfa8d0SDanilo Krummrich 238*c8cfa8d0SDanilo Krummrich /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then `x` will be 239*c8cfa8d0SDanilo Krummrich /// pinned in memory and can't be moved. 240*c8cfa8d0SDanilo Krummrich #[inline] 241*c8cfa8d0SDanilo Krummrich pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError> 242*c8cfa8d0SDanilo Krummrich where 243*c8cfa8d0SDanilo Krummrich A: 'static, 244*c8cfa8d0SDanilo Krummrich { 245*c8cfa8d0SDanilo Krummrich Ok(Self::new(x, flags)?.into()) 246*c8cfa8d0SDanilo Krummrich } 247*c8cfa8d0SDanilo Krummrich 248*c8cfa8d0SDanilo Krummrich /// Forgets the contents (does not run the destructor), but keeps the allocation. 249*c8cfa8d0SDanilo Krummrich fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> { 250*c8cfa8d0SDanilo Krummrich let ptr = Self::into_raw(this); 251*c8cfa8d0SDanilo Krummrich 252*c8cfa8d0SDanilo Krummrich // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. 253*c8cfa8d0SDanilo Krummrich unsafe { Box::from_raw(ptr.cast()) } 254*c8cfa8d0SDanilo Krummrich } 255*c8cfa8d0SDanilo Krummrich 256*c8cfa8d0SDanilo Krummrich /// Drops the contents, but keeps the allocation. 257*c8cfa8d0SDanilo Krummrich /// 258*c8cfa8d0SDanilo Krummrich /// # Examples 259*c8cfa8d0SDanilo Krummrich /// 260*c8cfa8d0SDanilo Krummrich /// ``` 261*c8cfa8d0SDanilo Krummrich /// let value = KBox::new([0; 32], GFP_KERNEL)?; 262*c8cfa8d0SDanilo Krummrich /// assert_eq!(*value, [0; 32]); 263*c8cfa8d0SDanilo Krummrich /// let value = KBox::drop_contents(value); 264*c8cfa8d0SDanilo Krummrich /// // Now we can re-use `value`: 265*c8cfa8d0SDanilo Krummrich /// let value = KBox::write(value, [1; 32]); 266*c8cfa8d0SDanilo Krummrich /// assert_eq!(*value, [1; 32]); 267*c8cfa8d0SDanilo Krummrich /// # Ok::<(), Error>(()) 268*c8cfa8d0SDanilo Krummrich /// ``` 269*c8cfa8d0SDanilo Krummrich pub fn drop_contents(this: Self) -> Box<MaybeUninit<T>, A> { 270*c8cfa8d0SDanilo Krummrich let ptr = this.0.as_ptr(); 271*c8cfa8d0SDanilo Krummrich 272*c8cfa8d0SDanilo Krummrich // SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the 273*c8cfa8d0SDanilo Krummrich // value stored in `this` again. 274*c8cfa8d0SDanilo Krummrich unsafe { core::ptr::drop_in_place(ptr) }; 275*c8cfa8d0SDanilo Krummrich 276*c8cfa8d0SDanilo Krummrich Self::forget_contents(this) 277*c8cfa8d0SDanilo Krummrich } 278*c8cfa8d0SDanilo Krummrich 279*c8cfa8d0SDanilo Krummrich /// Moves the `Box`'s value out of the `Box` and consumes the `Box`. 280*c8cfa8d0SDanilo Krummrich pub fn into_inner(b: Self) -> T { 281*c8cfa8d0SDanilo Krummrich // SAFETY: By the type invariant `&*b` is valid for `read`. 282*c8cfa8d0SDanilo Krummrich let value = unsafe { core::ptr::read(&*b) }; 283*c8cfa8d0SDanilo Krummrich let _ = Self::forget_contents(b); 284*c8cfa8d0SDanilo Krummrich value 285*c8cfa8d0SDanilo Krummrich } 286*c8cfa8d0SDanilo Krummrich } 287*c8cfa8d0SDanilo Krummrich 288*c8cfa8d0SDanilo Krummrich impl<T, A> From<Box<T, A>> for Pin<Box<T, A>> 289*c8cfa8d0SDanilo Krummrich where 290*c8cfa8d0SDanilo Krummrich T: ?Sized, 291*c8cfa8d0SDanilo Krummrich A: Allocator, 292*c8cfa8d0SDanilo Krummrich { 293*c8cfa8d0SDanilo Krummrich /// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then 294*c8cfa8d0SDanilo Krummrich /// `*b` will be pinned in memory and can't be moved. 295*c8cfa8d0SDanilo Krummrich /// 296*c8cfa8d0SDanilo Krummrich /// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory. 297*c8cfa8d0SDanilo Krummrich fn from(b: Box<T, A>) -> Self { 298*c8cfa8d0SDanilo Krummrich // SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long 299*c8cfa8d0SDanilo Krummrich // as `T` does not implement `Unpin`. 300*c8cfa8d0SDanilo Krummrich unsafe { Pin::new_unchecked(b) } 301*c8cfa8d0SDanilo Krummrich } 302*c8cfa8d0SDanilo Krummrich } 303*c8cfa8d0SDanilo Krummrich 304*c8cfa8d0SDanilo Krummrich impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A> 305*c8cfa8d0SDanilo Krummrich where 306*c8cfa8d0SDanilo Krummrich A: Allocator + 'static, 307*c8cfa8d0SDanilo Krummrich { 308*c8cfa8d0SDanilo Krummrich type Initialized = Box<T, A>; 309*c8cfa8d0SDanilo Krummrich 310*c8cfa8d0SDanilo Krummrich fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { 311*c8cfa8d0SDanilo Krummrich let slot = self.as_mut_ptr(); 312*c8cfa8d0SDanilo Krummrich // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 313*c8cfa8d0SDanilo Krummrich // slot is valid. 314*c8cfa8d0SDanilo Krummrich unsafe { init.__init(slot)? }; 315*c8cfa8d0SDanilo Krummrich // SAFETY: All fields have been initialized. 316*c8cfa8d0SDanilo Krummrich Ok(unsafe { Box::assume_init(self) }) 317*c8cfa8d0SDanilo Krummrich } 318*c8cfa8d0SDanilo Krummrich 319*c8cfa8d0SDanilo Krummrich fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { 320*c8cfa8d0SDanilo Krummrich let slot = self.as_mut_ptr(); 321*c8cfa8d0SDanilo Krummrich // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 322*c8cfa8d0SDanilo Krummrich // slot is valid and will not be moved, because we pin it later. 323*c8cfa8d0SDanilo Krummrich unsafe { init.__pinned_init(slot)? }; 324*c8cfa8d0SDanilo Krummrich // SAFETY: All fields have been initialized. 325*c8cfa8d0SDanilo Krummrich Ok(unsafe { Box::assume_init(self) }.into()) 326*c8cfa8d0SDanilo Krummrich } 327*c8cfa8d0SDanilo Krummrich } 328*c8cfa8d0SDanilo Krummrich 329*c8cfa8d0SDanilo Krummrich impl<T, A> InPlaceInit<T> for Box<T, A> 330*c8cfa8d0SDanilo Krummrich where 331*c8cfa8d0SDanilo Krummrich A: Allocator + 'static, 332*c8cfa8d0SDanilo Krummrich { 333*c8cfa8d0SDanilo Krummrich type PinnedSelf = Pin<Self>; 334*c8cfa8d0SDanilo Krummrich 335*c8cfa8d0SDanilo Krummrich #[inline] 336*c8cfa8d0SDanilo Krummrich fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E> 337*c8cfa8d0SDanilo Krummrich where 338*c8cfa8d0SDanilo Krummrich E: From<AllocError>, 339*c8cfa8d0SDanilo Krummrich { 340*c8cfa8d0SDanilo Krummrich Box::<_, A>::new_uninit(flags)?.write_pin_init(init) 341*c8cfa8d0SDanilo Krummrich } 342*c8cfa8d0SDanilo Krummrich 343*c8cfa8d0SDanilo Krummrich #[inline] 344*c8cfa8d0SDanilo Krummrich fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 345*c8cfa8d0SDanilo Krummrich where 346*c8cfa8d0SDanilo Krummrich E: From<AllocError>, 347*c8cfa8d0SDanilo Krummrich { 348*c8cfa8d0SDanilo Krummrich Box::<_, A>::new_uninit(flags)?.write_init(init) 349*c8cfa8d0SDanilo Krummrich } 350*c8cfa8d0SDanilo Krummrich } 351*c8cfa8d0SDanilo Krummrich 352*c8cfa8d0SDanilo Krummrich impl<T: 'static, A> ForeignOwnable for Box<T, A> 353*c8cfa8d0SDanilo Krummrich where 354*c8cfa8d0SDanilo Krummrich A: Allocator, 355*c8cfa8d0SDanilo Krummrich { 356*c8cfa8d0SDanilo Krummrich type Borrowed<'a> = &'a T; 357*c8cfa8d0SDanilo Krummrich 358*c8cfa8d0SDanilo Krummrich fn into_foreign(self) -> *const core::ffi::c_void { 359*c8cfa8d0SDanilo Krummrich Box::into_raw(self) as _ 360*c8cfa8d0SDanilo Krummrich } 361*c8cfa8d0SDanilo Krummrich 362*c8cfa8d0SDanilo Krummrich unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { 363*c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 364*c8cfa8d0SDanilo Krummrich // call to `Self::into_foreign`. 365*c8cfa8d0SDanilo Krummrich unsafe { Box::from_raw(ptr as _) } 366*c8cfa8d0SDanilo Krummrich } 367*c8cfa8d0SDanilo Krummrich 368*c8cfa8d0SDanilo Krummrich unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> &'a T { 369*c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements of this method ensure that the object remains alive and 370*c8cfa8d0SDanilo Krummrich // immutable for the duration of 'a. 371*c8cfa8d0SDanilo Krummrich unsafe { &*ptr.cast() } 372*c8cfa8d0SDanilo Krummrich } 373*c8cfa8d0SDanilo Krummrich } 374*c8cfa8d0SDanilo Krummrich 375*c8cfa8d0SDanilo Krummrich impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 376*c8cfa8d0SDanilo Krummrich where 377*c8cfa8d0SDanilo Krummrich A: Allocator, 378*c8cfa8d0SDanilo Krummrich { 379*c8cfa8d0SDanilo Krummrich type Borrowed<'a> = Pin<&'a T>; 380*c8cfa8d0SDanilo Krummrich 381*c8cfa8d0SDanilo Krummrich fn into_foreign(self) -> *const core::ffi::c_void { 382*c8cfa8d0SDanilo Krummrich // SAFETY: We are still treating the box as pinned. 383*c8cfa8d0SDanilo Krummrich Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }) as _ 384*c8cfa8d0SDanilo Krummrich } 385*c8cfa8d0SDanilo Krummrich 386*c8cfa8d0SDanilo Krummrich unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { 387*c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 388*c8cfa8d0SDanilo Krummrich // call to `Self::into_foreign`. 389*c8cfa8d0SDanilo Krummrich unsafe { Pin::new_unchecked(Box::from_raw(ptr as _)) } 390*c8cfa8d0SDanilo Krummrich } 391*c8cfa8d0SDanilo Krummrich 392*c8cfa8d0SDanilo Krummrich unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Pin<&'a T> { 393*c8cfa8d0SDanilo Krummrich // SAFETY: The safety requirements for this function ensure that the object is still alive, 394*c8cfa8d0SDanilo Krummrich // so it is safe to dereference the raw pointer. 395*c8cfa8d0SDanilo Krummrich // The safety requirements of `from_foreign` also ensure that the object remains alive for 396*c8cfa8d0SDanilo Krummrich // the lifetime of the returned value. 397*c8cfa8d0SDanilo Krummrich let r = unsafe { &*ptr.cast() }; 398*c8cfa8d0SDanilo Krummrich 399*c8cfa8d0SDanilo Krummrich // SAFETY: This pointer originates from a `Pin<Box<T>>`. 400*c8cfa8d0SDanilo Krummrich unsafe { Pin::new_unchecked(r) } 401*c8cfa8d0SDanilo Krummrich } 402*c8cfa8d0SDanilo Krummrich } 403*c8cfa8d0SDanilo Krummrich 404*c8cfa8d0SDanilo Krummrich impl<T, A> Deref for Box<T, A> 405*c8cfa8d0SDanilo Krummrich where 406*c8cfa8d0SDanilo Krummrich T: ?Sized, 407*c8cfa8d0SDanilo Krummrich A: Allocator, 408*c8cfa8d0SDanilo Krummrich { 409*c8cfa8d0SDanilo Krummrich type Target = T; 410*c8cfa8d0SDanilo Krummrich 411*c8cfa8d0SDanilo Krummrich fn deref(&self) -> &T { 412*c8cfa8d0SDanilo Krummrich // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 413*c8cfa8d0SDanilo Krummrich // instance of `T`. 414*c8cfa8d0SDanilo Krummrich unsafe { self.0.as_ref() } 415*c8cfa8d0SDanilo Krummrich } 416*c8cfa8d0SDanilo Krummrich } 417*c8cfa8d0SDanilo Krummrich 418*c8cfa8d0SDanilo Krummrich impl<T, A> DerefMut for Box<T, A> 419*c8cfa8d0SDanilo Krummrich where 420*c8cfa8d0SDanilo Krummrich T: ?Sized, 421*c8cfa8d0SDanilo Krummrich A: Allocator, 422*c8cfa8d0SDanilo Krummrich { 423*c8cfa8d0SDanilo Krummrich fn deref_mut(&mut self) -> &mut T { 424*c8cfa8d0SDanilo Krummrich // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 425*c8cfa8d0SDanilo Krummrich // instance of `T`. 426*c8cfa8d0SDanilo Krummrich unsafe { self.0.as_mut() } 427*c8cfa8d0SDanilo Krummrich } 428*c8cfa8d0SDanilo Krummrich } 429*c8cfa8d0SDanilo Krummrich 430*c8cfa8d0SDanilo Krummrich impl<T, A> fmt::Debug for Box<T, A> 431*c8cfa8d0SDanilo Krummrich where 432*c8cfa8d0SDanilo Krummrich T: ?Sized + fmt::Debug, 433*c8cfa8d0SDanilo Krummrich A: Allocator, 434*c8cfa8d0SDanilo Krummrich { 435*c8cfa8d0SDanilo Krummrich fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 436*c8cfa8d0SDanilo Krummrich fmt::Debug::fmt(&**self, f) 437*c8cfa8d0SDanilo Krummrich } 438*c8cfa8d0SDanilo Krummrich } 439*c8cfa8d0SDanilo Krummrich 440*c8cfa8d0SDanilo Krummrich impl<T, A> Drop for Box<T, A> 441*c8cfa8d0SDanilo Krummrich where 442*c8cfa8d0SDanilo Krummrich T: ?Sized, 443*c8cfa8d0SDanilo Krummrich A: Allocator, 444*c8cfa8d0SDanilo Krummrich { 445*c8cfa8d0SDanilo Krummrich fn drop(&mut self) { 446*c8cfa8d0SDanilo Krummrich let layout = Layout::for_value::<T>(self); 447*c8cfa8d0SDanilo Krummrich 448*c8cfa8d0SDanilo Krummrich // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant. 449*c8cfa8d0SDanilo Krummrich unsafe { core::ptr::drop_in_place::<T>(self.deref_mut()) }; 450*c8cfa8d0SDanilo Krummrich 451*c8cfa8d0SDanilo Krummrich // SAFETY: 452*c8cfa8d0SDanilo Krummrich // - `self.0` was previously allocated with `A`. 453*c8cfa8d0SDanilo Krummrich // - `layout` is equal to the `Layout´ `self.0` was allocated with. 454*c8cfa8d0SDanilo Krummrich unsafe { A::free(self.0.cast(), layout) }; 455*c8cfa8d0SDanilo Krummrich } 456*c8cfa8d0SDanilo Krummrich } 457