1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Implementation of [`Box`]. 4 5 #[allow(unused_imports)] // Used in doc comments. 6 use super::allocator::{KVmalloc, Kmalloc, Vmalloc}; 7 use super::{AllocError, Allocator, Flags}; 8 use core::alloc::Layout; 9 use core::borrow::{Borrow, BorrowMut}; 10 use core::fmt; 11 use core::marker::PhantomData; 12 use core::mem::ManuallyDrop; 13 use core::mem::MaybeUninit; 14 use core::ops::{Deref, DerefMut}; 15 use core::pin::Pin; 16 use core::ptr::NonNull; 17 use core::result::Result; 18 19 use crate::ffi::c_void; 20 use crate::init::InPlaceInit; 21 use crate::types::ForeignOwnable; 22 use pin_init::{InPlaceWrite, Init, PinInit, ZeroableOption}; 23 24 /// The kernel's [`Box`] type -- a heap allocation for a single value of type `T`. 25 /// 26 /// This is the kernel's version of the Rust stdlib's `Box`. There are several differences, 27 /// for example no `noalias` attribute is emitted and partially moving out of a `Box` is not 28 /// supported. There are also several API differences, e.g. `Box` always requires an [`Allocator`] 29 /// implementation to be passed as generic, page [`Flags`] when allocating memory and all functions 30 /// that may allocate memory are fallible. 31 /// 32 /// `Box` works with any of the kernel's allocators, e.g. [`Kmalloc`], [`Vmalloc`] or [`KVmalloc`]. 33 /// There are aliases for `Box` with these allocators ([`KBox`], [`VBox`], [`KVBox`]). 34 /// 35 /// When dropping a [`Box`], the value is also dropped and the heap memory is automatically freed. 36 /// 37 /// # Examples 38 /// 39 /// ``` 40 /// let b = KBox::<u64>::new(24_u64, GFP_KERNEL)?; 41 /// 42 /// assert_eq!(*b, 24_u64); 43 /// # Ok::<(), Error>(()) 44 /// ``` 45 /// 46 /// ``` 47 /// # use kernel::bindings; 48 /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 49 /// struct Huge([u8; SIZE]); 50 /// 51 /// assert!(KBox::<Huge>::new_uninit(GFP_KERNEL | __GFP_NOWARN).is_err()); 52 /// ``` 53 /// 54 /// ``` 55 /// # use kernel::bindings; 56 /// const SIZE: usize = bindings::KMALLOC_MAX_SIZE as usize + 1; 57 /// struct Huge([u8; SIZE]); 58 /// 59 /// assert!(KVBox::<Huge>::new_uninit(GFP_KERNEL).is_ok()); 60 /// ``` 61 /// 62 /// [`Box`]es can also be used to store trait objects by coercing their type: 63 /// 64 /// ``` 65 /// trait FooTrait {} 66 /// 67 /// struct FooStruct; 68 /// impl FooTrait for FooStruct {} 69 /// 70 /// let _ = KBox::new(FooStruct, GFP_KERNEL)? as KBox<dyn FooTrait>; 71 /// # Ok::<(), Error>(()) 72 /// ``` 73 /// 74 /// # Invariants 75 /// 76 /// `self.0` is always properly aligned and either points to memory allocated with `A` or, for 77 /// zero-sized types, is a dangling, well aligned pointer. 78 #[repr(transparent)] 79 #[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))] 80 pub struct Box<#[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, pointee)] T: ?Sized, A: Allocator>( 81 NonNull<T>, 82 PhantomData<A>, 83 ); 84 85 // This is to allow coercion from `Box<T, A>` to `Box<U, A>` if `T` can be converted to the 86 // dynamically-sized type (DST) `U`. 87 #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))] 88 impl<T, U, A> core::ops::CoerceUnsized<Box<U, A>> for Box<T, A> 89 where 90 T: ?Sized + core::marker::Unsize<U>, 91 U: ?Sized, 92 A: Allocator, 93 { 94 } 95 96 // This is to allow `Box<U, A>` to be dispatched on when `Box<T, A>` can be coerced into `Box<U, 97 // A>`. 98 #[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))] 99 impl<T, U, A> core::ops::DispatchFromDyn<Box<U, A>> for Box<T, A> 100 where 101 T: ?Sized + core::marker::Unsize<U>, 102 U: ?Sized, 103 A: Allocator, 104 { 105 } 106 107 /// Type alias for [`Box`] with a [`Kmalloc`] allocator. 108 /// 109 /// # Examples 110 /// 111 /// ``` 112 /// let b = KBox::new(24_u64, GFP_KERNEL)?; 113 /// 114 /// assert_eq!(*b, 24_u64); 115 /// # Ok::<(), Error>(()) 116 /// ``` 117 pub type KBox<T> = Box<T, super::allocator::Kmalloc>; 118 119 /// Type alias for [`Box`] with a [`Vmalloc`] allocator. 120 /// 121 /// # Examples 122 /// 123 /// ``` 124 /// let b = VBox::new(24_u64, GFP_KERNEL)?; 125 /// 126 /// assert_eq!(*b, 24_u64); 127 /// # Ok::<(), Error>(()) 128 /// ``` 129 pub type VBox<T> = Box<T, super::allocator::Vmalloc>; 130 131 /// Type alias for [`Box`] with a [`KVmalloc`] allocator. 132 /// 133 /// # Examples 134 /// 135 /// ``` 136 /// let b = KVBox::new(24_u64, GFP_KERNEL)?; 137 /// 138 /// assert_eq!(*b, 24_u64); 139 /// # Ok::<(), Error>(()) 140 /// ``` 141 pub type KVBox<T> = Box<T, super::allocator::KVmalloc>; 142 143 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee: 144 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>). 145 unsafe impl<T, A: Allocator> ZeroableOption for Box<T, A> {} 146 147 // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`. 148 unsafe impl<T, A> Send for Box<T, A> 149 where 150 T: Send + ?Sized, 151 A: Allocator, 152 { 153 } 154 155 // SAFETY: `Box` is `Sync` if `T` is `Sync` because the `Box` owns a `T`. 156 unsafe impl<T, A> Sync for Box<T, A> 157 where 158 T: Sync + ?Sized, 159 A: Allocator, 160 { 161 } 162 163 impl<T, A> Box<T, A> 164 where 165 T: ?Sized, 166 A: Allocator, 167 { 168 /// Creates a new `Box<T, A>` from a raw pointer. 169 /// 170 /// # Safety 171 /// 172 /// For non-ZSTs, `raw` must point at an allocation allocated with `A` that is sufficiently 173 /// aligned for and holds a valid `T`. The caller passes ownership of the allocation to the 174 /// `Box`. 175 /// 176 /// For ZSTs, `raw` must be a dangling, well aligned pointer. 177 #[inline] from_raw(raw: *mut T) -> Self178 pub const unsafe fn from_raw(raw: *mut T) -> Self { 179 // INVARIANT: Validity of `raw` is guaranteed by the safety preconditions of this function. 180 // SAFETY: By the safety preconditions of this function, `raw` is not a NULL pointer. 181 Self(unsafe { NonNull::new_unchecked(raw) }, PhantomData) 182 } 183 184 /// Consumes the `Box<T, A>` and returns a raw pointer. 185 /// 186 /// This will not run the destructor of `T` and for non-ZSTs the allocation will stay alive 187 /// indefinitely. Use [`Box::from_raw`] to recover the [`Box`], drop the value and free the 188 /// allocation, if any. 189 /// 190 /// # Examples 191 /// 192 /// ``` 193 /// let x = KBox::new(24, GFP_KERNEL)?; 194 /// let ptr = KBox::into_raw(x); 195 /// // SAFETY: `ptr` comes from a previous call to `KBox::into_raw`. 196 /// let x = unsafe { KBox::from_raw(ptr) }; 197 /// 198 /// assert_eq!(*x, 24); 199 /// # Ok::<(), Error>(()) 200 /// ``` 201 #[inline] into_raw(b: Self) -> *mut T202 pub fn into_raw(b: Self) -> *mut T { 203 ManuallyDrop::new(b).0.as_ptr() 204 } 205 206 /// Consumes and leaks the `Box<T, A>` and returns a mutable reference. 207 /// 208 /// See [`Box::into_raw`] for more details. 209 #[inline] leak<'a>(b: Self) -> &'a mut T210 pub fn leak<'a>(b: Self) -> &'a mut T { 211 // SAFETY: `Box::into_raw` always returns a properly aligned and dereferenceable pointer 212 // which points to an initialized instance of `T`. 213 unsafe { &mut *Box::into_raw(b) } 214 } 215 } 216 217 impl<T, A> Box<MaybeUninit<T>, A> 218 where 219 A: Allocator, 220 { 221 /// Converts a `Box<MaybeUninit<T>, A>` to a `Box<T, A>`. 222 /// 223 /// It is undefined behavior to call this function while the value inside of `b` is not yet 224 /// fully initialized. 225 /// 226 /// # Safety 227 /// 228 /// Callers must ensure that the value inside of `b` is in an initialized state. assume_init(self) -> Box<T, A>229 pub unsafe fn assume_init(self) -> Box<T, A> { 230 let raw = Self::into_raw(self); 231 232 // SAFETY: `raw` comes from a previous call to `Box::into_raw`. By the safety requirements 233 // of this function, the value inside the `Box` is in an initialized state. Hence, it is 234 // safe to reconstruct the `Box` as `Box<T, A>`. 235 unsafe { Box::from_raw(raw.cast()) } 236 } 237 238 /// Writes the value and converts to `Box<T, A>`. write(mut self, value: T) -> Box<T, A>239 pub fn write(mut self, value: T) -> Box<T, A> { 240 (*self).write(value); 241 242 // SAFETY: We've just initialized `b`'s value. 243 unsafe { self.assume_init() } 244 } 245 } 246 247 impl<T, A> Box<T, A> 248 where 249 A: Allocator, 250 { 251 /// Creates a new `Box<T, A>` and initializes its contents with `x`. 252 /// 253 /// New memory is allocated with `A`. The allocation may fail, in which case an error is 254 /// returned. For ZSTs no memory is allocated. new(x: T, flags: Flags) -> Result<Self, AllocError>255 pub fn new(x: T, flags: Flags) -> Result<Self, AllocError> { 256 let b = Self::new_uninit(flags)?; 257 Ok(Box::write(b, x)) 258 } 259 260 /// Creates a new `Box<T, A>` with uninitialized contents. 261 /// 262 /// New memory is allocated with `A`. The allocation may fail, in which case an error is 263 /// returned. For ZSTs no memory is allocated. 264 /// 265 /// # Examples 266 /// 267 /// ``` 268 /// let b = KBox::<u64>::new_uninit(GFP_KERNEL)?; 269 /// let b = KBox::write(b, 24); 270 /// 271 /// assert_eq!(*b, 24_u64); 272 /// # Ok::<(), Error>(()) 273 /// ``` new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError>274 pub fn new_uninit(flags: Flags) -> Result<Box<MaybeUninit<T>, A>, AllocError> { 275 let layout = Layout::new::<MaybeUninit<T>>(); 276 let ptr = A::alloc(layout, flags)?; 277 278 // INVARIANT: `ptr` is either a dangling pointer or points to memory allocated with `A`, 279 // which is sufficient in size and alignment for storing a `T`. 280 Ok(Box(ptr.cast(), PhantomData)) 281 } 282 283 /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then `x` will be 284 /// pinned in memory and can't be moved. 285 #[inline] pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError> where A: 'static,286 pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError> 287 where 288 A: 'static, 289 { 290 Ok(Self::new(x, flags)?.into()) 291 } 292 293 /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement 294 /// [`Unpin`], then `x` will be pinned in memory and can't be moved. into_pin(this: Self) -> Pin<Self>295 pub fn into_pin(this: Self) -> Pin<Self> { 296 this.into() 297 } 298 299 /// Forgets the contents (does not run the destructor), but keeps the allocation. forget_contents(this: Self) -> Box<MaybeUninit<T>, A>300 fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> { 301 let ptr = Self::into_raw(this); 302 303 // SAFETY: `ptr` is valid, because it came from `Box::into_raw`. 304 unsafe { Box::from_raw(ptr.cast()) } 305 } 306 307 /// Drops the contents, but keeps the allocation. 308 /// 309 /// # Examples 310 /// 311 /// ``` 312 /// let value = KBox::new([0; 32], GFP_KERNEL)?; 313 /// assert_eq!(*value, [0; 32]); 314 /// let value = KBox::drop_contents(value); 315 /// // Now we can re-use `value`: 316 /// let value = KBox::write(value, [1; 32]); 317 /// assert_eq!(*value, [1; 32]); 318 /// # Ok::<(), Error>(()) 319 /// ``` drop_contents(this: Self) -> Box<MaybeUninit<T>, A>320 pub fn drop_contents(this: Self) -> Box<MaybeUninit<T>, A> { 321 let ptr = this.0.as_ptr(); 322 323 // SAFETY: `ptr` is valid, because it came from `this`. After this call we never access the 324 // value stored in `this` again. 325 unsafe { core::ptr::drop_in_place(ptr) }; 326 327 Self::forget_contents(this) 328 } 329 330 /// Moves the `Box`'s value out of the `Box` and consumes the `Box`. into_inner(b: Self) -> T331 pub fn into_inner(b: Self) -> T { 332 // SAFETY: By the type invariant `&*b` is valid for `read`. 333 let value = unsafe { core::ptr::read(&*b) }; 334 let _ = Self::forget_contents(b); 335 value 336 } 337 } 338 339 impl<T, A> From<Box<T, A>> for Pin<Box<T, A>> 340 where 341 T: ?Sized, 342 A: Allocator, 343 { 344 /// Converts a `Box<T, A>` into a `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then 345 /// `*b` will be pinned in memory and can't be moved. 346 /// 347 /// This moves `b` into `Pin` without moving `*b` or allocating and copying any memory. from(b: Box<T, A>) -> Self348 fn from(b: Box<T, A>) -> Self { 349 // SAFETY: The value wrapped inside a `Pin<Box<T, A>>` cannot be moved or replaced as long 350 // as `T` does not implement `Unpin`. 351 unsafe { Pin::new_unchecked(b) } 352 } 353 } 354 355 impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A> 356 where 357 A: Allocator + 'static, 358 { 359 type Initialized = Box<T, A>; 360 write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E>361 fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { 362 let slot = self.as_mut_ptr(); 363 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 364 // slot is valid. 365 unsafe { init.__init(slot)? }; 366 // SAFETY: All fields have been initialized. 367 Ok(unsafe { Box::assume_init(self) }) 368 } 369 write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>370 fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { 371 let slot = self.as_mut_ptr(); 372 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 373 // slot is valid and will not be moved, because we pin it later. 374 unsafe { init.__pinned_init(slot)? }; 375 // SAFETY: All fields have been initialized. 376 Ok(unsafe { Box::assume_init(self) }.into()) 377 } 378 } 379 380 impl<T, A> InPlaceInit<T> for Box<T, A> 381 where 382 A: Allocator + 'static, 383 { 384 type PinnedSelf = Pin<Self>; 385 386 #[inline] try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E> where E: From<AllocError>,387 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Pin<Self>, E> 388 where 389 E: From<AllocError>, 390 { 391 Box::<_, A>::new_uninit(flags)?.write_pin_init(init) 392 } 393 394 #[inline] try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> where E: From<AllocError>,395 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> 396 where 397 E: From<AllocError>, 398 { 399 Box::<_, A>::new_uninit(flags)?.write_init(init) 400 } 401 } 402 403 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 404 // pointer to `T`. 405 unsafe impl<T: 'static, A> ForeignOwnable for Box<T, A> 406 where 407 A: Allocator, 408 { 409 const FOREIGN_ALIGN: usize = core::mem::align_of::<T>(); 410 type Borrowed<'a> = &'a T; 411 type BorrowedMut<'a> = &'a mut T; 412 into_foreign(self) -> *mut c_void413 fn into_foreign(self) -> *mut c_void { 414 Box::into_raw(self).cast() 415 } 416 from_foreign(ptr: *mut c_void) -> Self417 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 418 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 419 // call to `Self::into_foreign`. 420 unsafe { Box::from_raw(ptr.cast()) } 421 } 422 borrow<'a>(ptr: *mut c_void) -> &'a T423 unsafe fn borrow<'a>(ptr: *mut c_void) -> &'a T { 424 // SAFETY: The safety requirements of this method ensure that the object remains alive and 425 // immutable for the duration of 'a. 426 unsafe { &*ptr.cast() } 427 } 428 borrow_mut<'a>(ptr: *mut c_void) -> &'a mut T429 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> &'a mut T { 430 let ptr = ptr.cast(); 431 // SAFETY: The safety requirements of this method ensure that the pointer is valid and that 432 // nothing else will access the value for the duration of 'a. 433 unsafe { &mut *ptr } 434 } 435 } 436 437 // SAFETY: The pointer returned by `into_foreign` comes from a well aligned 438 // pointer to `T`. 439 unsafe impl<T: 'static, A> ForeignOwnable for Pin<Box<T, A>> 440 where 441 A: Allocator, 442 { 443 const FOREIGN_ALIGN: usize = core::mem::align_of::<T>(); 444 type Borrowed<'a> = Pin<&'a T>; 445 type BorrowedMut<'a> = Pin<&'a mut T>; 446 into_foreign(self) -> *mut c_void447 fn into_foreign(self) -> *mut c_void { 448 // SAFETY: We are still treating the box as pinned. 449 Box::into_raw(unsafe { Pin::into_inner_unchecked(self) }).cast() 450 } 451 from_foreign(ptr: *mut c_void) -> Self452 unsafe fn from_foreign(ptr: *mut c_void) -> Self { 453 // SAFETY: The safety requirements of this function ensure that `ptr` comes from a previous 454 // call to `Self::into_foreign`. 455 unsafe { Pin::new_unchecked(Box::from_raw(ptr.cast())) } 456 } 457 borrow<'a>(ptr: *mut c_void) -> Pin<&'a T>458 unsafe fn borrow<'a>(ptr: *mut c_void) -> Pin<&'a T> { 459 // SAFETY: The safety requirements for this function ensure that the object is still alive, 460 // so it is safe to dereference the raw pointer. 461 // The safety requirements of `from_foreign` also ensure that the object remains alive for 462 // the lifetime of the returned value. 463 let r = unsafe { &*ptr.cast() }; 464 465 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 466 unsafe { Pin::new_unchecked(r) } 467 } 468 borrow_mut<'a>(ptr: *mut c_void) -> Pin<&'a mut T>469 unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Pin<&'a mut T> { 470 let ptr = ptr.cast(); 471 // SAFETY: The safety requirements for this function ensure that the object is still alive, 472 // so it is safe to dereference the raw pointer. 473 // The safety requirements of `from_foreign` also ensure that the object remains alive for 474 // the lifetime of the returned value. 475 let r = unsafe { &mut *ptr }; 476 477 // SAFETY: This pointer originates from a `Pin<Box<T>>`. 478 unsafe { Pin::new_unchecked(r) } 479 } 480 } 481 482 impl<T, A> Deref for Box<T, A> 483 where 484 T: ?Sized, 485 A: Allocator, 486 { 487 type Target = T; 488 deref(&self) -> &T489 fn deref(&self) -> &T { 490 // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 491 // instance of `T`. 492 unsafe { self.0.as_ref() } 493 } 494 } 495 496 impl<T, A> DerefMut for Box<T, A> 497 where 498 T: ?Sized, 499 A: Allocator, 500 { deref_mut(&mut self) -> &mut T501 fn deref_mut(&mut self) -> &mut T { 502 // SAFETY: `self.0` is always properly aligned, dereferenceable and points to an initialized 503 // instance of `T`. 504 unsafe { self.0.as_mut() } 505 } 506 } 507 508 /// # Examples 509 /// 510 /// ``` 511 /// # use core::borrow::Borrow; 512 /// # use kernel::alloc::KBox; 513 /// struct Foo<B: Borrow<u32>>(B); 514 /// 515 /// // Owned instance. 516 /// let owned = Foo(1); 517 /// 518 /// // Owned instance using `KBox`. 519 /// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?); 520 /// 521 /// let i = 1; 522 /// // Borrowed from `i`. 523 /// let borrowed = Foo(&i); 524 /// # Ok::<(), Error>(()) 525 /// ``` 526 impl<T, A> Borrow<T> for Box<T, A> 527 where 528 T: ?Sized, 529 A: Allocator, 530 { borrow(&self) -> &T531 fn borrow(&self) -> &T { 532 self.deref() 533 } 534 } 535 536 /// # Examples 537 /// 538 /// ``` 539 /// # use core::borrow::BorrowMut; 540 /// # use kernel::alloc::KBox; 541 /// struct Foo<B: BorrowMut<u32>>(B); 542 /// 543 /// // Owned instance. 544 /// let owned = Foo(1); 545 /// 546 /// // Owned instance using `KBox`. 547 /// let owned_kbox = Foo(KBox::new(1, GFP_KERNEL)?); 548 /// 549 /// let mut i = 1; 550 /// // Borrowed from `i`. 551 /// let borrowed = Foo(&mut i); 552 /// # Ok::<(), Error>(()) 553 /// ``` 554 impl<T, A> BorrowMut<T> for Box<T, A> 555 where 556 T: ?Sized, 557 A: Allocator, 558 { borrow_mut(&mut self) -> &mut T559 fn borrow_mut(&mut self) -> &mut T { 560 self.deref_mut() 561 } 562 } 563 564 impl<T, A> fmt::Display for Box<T, A> 565 where 566 T: ?Sized + fmt::Display, 567 A: Allocator, 568 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result569 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 570 <T as fmt::Display>::fmt(&**self, f) 571 } 572 } 573 574 impl<T, A> fmt::Debug for Box<T, A> 575 where 576 T: ?Sized + fmt::Debug, 577 A: Allocator, 578 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result579 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 580 <T as fmt::Debug>::fmt(&**self, f) 581 } 582 } 583 584 impl<T, A> Drop for Box<T, A> 585 where 586 T: ?Sized, 587 A: Allocator, 588 { drop(&mut self)589 fn drop(&mut self) { 590 let layout = Layout::for_value::<T>(self); 591 592 // SAFETY: The pointer in `self.0` is guaranteed to be valid by the type invariant. 593 unsafe { core::ptr::drop_in_place::<T>(self.deref_mut()) }; 594 595 // SAFETY: 596 // - `self.0` was previously allocated with `A`. 597 // - `layout` is equal to the `Layout´ `self.0` was allocated with. 598 unsafe { A::free(self.0.cast(), layout) }; 599 } 600 } 601