1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 3 //! API to safely and fallibly initialize pinned `struct`s using in-place constructors. 4 //! 5 //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack 6 //! overflow. 7 //! 8 //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential 9 //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move. 10 //! 11 //! # Overview 12 //! 13 //! To initialize a `struct` with an in-place constructor you will need two things: 14 //! - an in-place constructor, 15 //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`], 16 //! [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]). 17 //! 18 //! To get an in-place constructor there are generally three options: 19 //! - directly creating an in-place constructor using the [`pin_init!`] macro, 20 //! - a custom function/macro returning an in-place constructor provided by someone else, 21 //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer. 22 //! 23 //! Aside from pinned initialization, this API also supports in-place construction without pinning, 24 //! the macros/types/functions are generally named like the pinned variants without the `pin` 25 //! prefix. 26 //! 27 //! # Examples 28 //! 29 //! ## Using the [`pin_init!`] macro 30 //! 31 //! If you want to use [`PinInit`], then you will have to annotate your `struct` with 32 //! `#[`[`pin_data`]`]`. It is a macro that uses `#[pin]` as a marker for 33 //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via 34 //! [`pin_init!`]. The syntax is almost the same as normal `struct` initializers. The difference is 35 //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place. 36 //! 37 //! ```rust 38 //! # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 39 //! use kernel::{prelude::*, sync::Mutex, new_mutex}; 40 //! # use core::pin::Pin; 41 //! #[pin_data] 42 //! struct Foo { 43 //! #[pin] 44 //! a: Mutex<usize>, 45 //! b: u32, 46 //! } 47 //! 48 //! let foo = pin_init!(Foo { 49 //! a <- new_mutex!(42, "Foo::a"), 50 //! b: 24, 51 //! }); 52 //! ``` 53 //! 54 //! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like 55 //! (or just the stack) to actually initialize a `Foo`: 56 //! 57 //! ```rust 58 //! # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 59 //! # use kernel::{prelude::*, sync::Mutex, new_mutex}; 60 //! # use core::pin::Pin; 61 //! # #[pin_data] 62 //! # struct Foo { 63 //! # #[pin] 64 //! # a: Mutex<usize>, 65 //! # b: u32, 66 //! # } 67 //! # let foo = pin_init!(Foo { 68 //! # a <- new_mutex!(42, "Foo::a"), 69 //! # b: 24, 70 //! # }); 71 //! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo); 72 //! ``` 73 //! 74 //! For more information see the [`pin_init!`] macro. 75 //! 76 //! ## Using a custom function/macro that returns an initializer 77 //! 78 //! Many types from the kernel supply a function/macro that returns an initializer, because the 79 //! above method only works for types where you can access the fields. 80 //! 81 //! ```rust 82 //! # use kernel::{new_mutex, sync::{Arc, Mutex}}; 83 //! let mtx: Result<Arc<Mutex<usize>>> = Arc::pin_init(new_mutex!(42, "example::mtx")); 84 //! ``` 85 //! 86 //! To declare an init macro/function you just return an [`impl PinInit<T, E>`]: 87 //! 88 //! ```rust 89 //! # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 90 //! # use kernel::{sync::Mutex, prelude::*, new_mutex, init::PinInit, try_pin_init}; 91 //! #[pin_data] 92 //! struct DriverData { 93 //! #[pin] 94 //! status: Mutex<i32>, 95 //! buffer: Box<[u8; 1_000_000]>, 96 //! } 97 //! 98 //! impl DriverData { 99 //! fn new() -> impl PinInit<Self, Error> { 100 //! try_pin_init!(Self { 101 //! status <- new_mutex!(0, "DriverData::status"), 102 //! buffer: Box::init(kernel::init::zeroed())?, 103 //! }) 104 //! } 105 //! } 106 //! ``` 107 //! 108 //! ## Manual creation of an initializer 109 //! 110 //! Often when working with primitives the previous approaches are not sufficient. That is where 111 //! [`pin_init_from_closure()`] comes in. This `unsafe` function allows you to create a 112 //! [`impl PinInit<T, E>`] directly from a closure. Of course you have to ensure that the closure 113 //! actually does the initialization in the correct way. Here are the things to look out for 114 //! (we are calling the parameter to the closure `slot`): 115 //! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so 116 //! `slot` now contains a valid bit pattern for the type `T`, 117 //! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so 118 //! you need to take care to clean up anything if your initialization fails mid-way, 119 //! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of 120 //! `slot` gets called. 121 //! 122 //! ```rust 123 //! use kernel::{prelude::*, init}; 124 //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; 125 //! # mod bindings { 126 //! # pub struct foo; 127 //! # pub unsafe fn init_foo(_ptr: *mut foo) {} 128 //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} 129 //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 } 130 //! # } 131 //! /// # Invariants 132 //! /// 133 //! /// `foo` is always initialized 134 //! #[pin_data(PinnedDrop)] 135 //! pub struct RawFoo { 136 //! #[pin] 137 //! foo: Opaque<bindings::foo>, 138 //! #[pin] 139 //! _p: PhantomPinned, 140 //! } 141 //! 142 //! impl RawFoo { 143 //! pub fn new(flags: u32) -> impl PinInit<Self, Error> { 144 //! // SAFETY: 145 //! // - when the closure returns `Ok(())`, then it has successfully initialized and 146 //! // enabled `foo`, 147 //! // - when it returns `Err(e)`, then it has cleaned up before 148 //! unsafe { 149 //! init::pin_init_from_closure(move |slot: *mut Self| { 150 //! // `slot` contains uninit memory, avoid creating a reference. 151 //! let foo = addr_of_mut!((*slot).foo); 152 //! 153 //! // Initialize the `foo` 154 //! bindings::init_foo(Opaque::raw_get(foo)); 155 //! 156 //! // Try to enable it. 157 //! let err = bindings::enable_foo(Opaque::raw_get(foo), flags); 158 //! if err != 0 { 159 //! // Enabling has failed, first clean up the foo and then return the error. 160 //! bindings::destroy_foo(Opaque::raw_get(foo)); 161 //! return Err(Error::from_kernel_errno(err)); 162 //! } 163 //! 164 //! // All fields of `RawFoo` have been initialized, since `_p` is a ZST. 165 //! Ok(()) 166 //! }) 167 //! } 168 //! } 169 //! } 170 //! 171 //! #[pinned_drop] 172 //! impl PinnedDrop for RawFoo { 173 //! fn drop(self: Pin<&mut Self>) { 174 //! // SAFETY: Since `foo` is initialized, destroying is safe. 175 //! unsafe { bindings::destroy_foo(self.foo.get()) }; 176 //! } 177 //! } 178 //! ``` 179 //! 180 //! [`sync`]: kernel::sync 181 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html 182 //! [structurally pinned fields]: 183 //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field 184 //! [stack]: crate::stack_pin_init 185 //! [`Arc<T>`]: crate::sync::Arc 186 //! [`impl PinInit<Foo>`]: PinInit 187 //! [`impl PinInit<T, E>`]: PinInit 188 //! [`impl Init<T, E>`]: Init 189 //! [`Opaque`]: kernel::types::Opaque 190 //! [`pin_data`]: ::macros::pin_data 191 192 use crate::{ 193 error::{self, Error}, 194 sync::UniqueArc, 195 }; 196 use alloc::boxed::Box; 197 use core::{ 198 alloc::AllocError, cell::Cell, convert::Infallible, marker::PhantomData, mem::MaybeUninit, 199 pin::Pin, ptr, 200 }; 201 202 #[doc(hidden)] 203 pub mod __internal; 204 #[doc(hidden)] 205 pub mod macros; 206 207 /// Initialize and pin a type directly on the stack. 208 /// 209 /// # Examples 210 /// 211 /// ```rust 212 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 213 /// # use kernel::{init, pin_init, stack_pin_init, init::*, sync::Mutex, new_mutex}; 214 /// # use macros::pin_data; 215 /// # use core::pin::Pin; 216 /// #[pin_data] 217 /// struct Foo { 218 /// #[pin] 219 /// a: Mutex<usize>, 220 /// b: Bar, 221 /// } 222 /// 223 /// #[pin_data] 224 /// struct Bar { 225 /// x: u32, 226 /// } 227 /// 228 /// stack_pin_init!(let foo = pin_init!(Foo { 229 /// a <- new_mutex!(42), 230 /// b: Bar { 231 /// x: 64, 232 /// }, 233 /// })); 234 /// let foo: Pin<&mut Foo> = foo; 235 /// pr_info!("a: {}", &*foo.a.lock()); 236 /// ``` 237 /// 238 /// # Syntax 239 /// 240 /// A normal `let` binding with optional type annotation. The expression is expected to implement 241 /// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error 242 /// type, then use [`stack_try_pin_init!`]. 243 #[macro_export] 244 macro_rules! stack_pin_init { 245 (let $var:ident $(: $t:ty)? = $val:expr) => { 246 let val = $val; 247 let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); 248 let mut $var = match $crate::init::__internal::StackInit::init($var, val) { 249 Ok(res) => res, 250 Err(x) => { 251 let x: ::core::convert::Infallible = x; 252 match x {} 253 } 254 }; 255 }; 256 } 257 258 /// Initialize and pin a type directly on the stack. 259 /// 260 /// # Examples 261 /// 262 /// ```rust 263 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 264 /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; 265 /// # use macros::pin_data; 266 /// # use core::{alloc::AllocError, pin::Pin}; 267 /// #[pin_data] 268 /// struct Foo { 269 /// #[pin] 270 /// a: Mutex<usize>, 271 /// b: Box<Bar>, 272 /// } 273 /// 274 /// struct Bar { 275 /// x: u32, 276 /// } 277 /// 278 /// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo { 279 /// a <- new_mutex!(42), 280 /// b: Box::try_new(Bar { 281 /// x: 64, 282 /// })?, 283 /// })); 284 /// let foo = foo.unwrap(); 285 /// pr_info!("a: {}", &*foo.a.lock()); 286 /// ``` 287 /// 288 /// ```rust 289 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 290 /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; 291 /// # use macros::pin_data; 292 /// # use core::{alloc::AllocError, pin::Pin}; 293 /// #[pin_data] 294 /// struct Foo { 295 /// #[pin] 296 /// a: Mutex<usize>, 297 /// b: Box<Bar>, 298 /// } 299 /// 300 /// struct Bar { 301 /// x: u32, 302 /// } 303 /// 304 /// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo { 305 /// a <- new_mutex!(42), 306 /// b: Box::try_new(Bar { 307 /// x: 64, 308 /// })?, 309 /// })); 310 /// pr_info!("a: {}", &*foo.a.lock()); 311 /// # Ok::<_, AllocError>(()) 312 /// ``` 313 /// 314 /// # Syntax 315 /// 316 /// A normal `let` binding with optional type annotation. The expression is expected to implement 317 /// [`PinInit`]/[`Init`]. This macro assigns a result to the given variable, adding a `?` after the 318 /// `=` will propagate this error. 319 #[macro_export] 320 macro_rules! stack_try_pin_init { 321 (let $var:ident $(: $t:ty)? = $val:expr) => { 322 let val = $val; 323 let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); 324 let mut $var = $crate::init::__internal::StackInit::init($var, val); 325 }; 326 (let $var:ident $(: $t:ty)? =? $val:expr) => { 327 let val = $val; 328 let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); 329 let mut $var = $crate::init::__internal::StackInit::init($var, val)?; 330 }; 331 } 332 333 /// Construct an in-place, pinned initializer for `struct`s. 334 /// 335 /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use 336 /// [`try_pin_init!`]. 337 /// 338 /// The syntax is almost identical to that of a normal `struct` initializer: 339 /// 340 /// ```rust 341 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 342 /// # use kernel::{init, pin_init, macros::pin_data, init::*}; 343 /// # use core::pin::Pin; 344 /// #[pin_data] 345 /// struct Foo { 346 /// a: usize, 347 /// b: Bar, 348 /// } 349 /// 350 /// #[pin_data] 351 /// struct Bar { 352 /// x: u32, 353 /// } 354 /// 355 /// # fn demo() -> impl PinInit<Foo> { 356 /// let a = 42; 357 /// 358 /// let initializer = pin_init!(Foo { 359 /// a, 360 /// b: Bar { 361 /// x: 64, 362 /// }, 363 /// }); 364 /// # initializer } 365 /// # Box::pin_init(demo()).unwrap(); 366 /// ``` 367 /// 368 /// Arbitrary Rust expressions can be used to set the value of a variable. 369 /// 370 /// The fields are initialized in the order that they appear in the initializer. So it is possible 371 /// to read already initialized fields using raw pointers. 372 /// 373 /// IMPORTANT: You are not allowed to create references to fields of the struct inside of the 374 /// initializer. 375 /// 376 /// # Init-functions 377 /// 378 /// When working with this API it is often desired to let others construct your types without 379 /// giving access to all fields. This is where you would normally write a plain function `new` 380 /// that would return a new instance of your type. With this API that is also possible. 381 /// However, there are a few extra things to keep in mind. 382 /// 383 /// To create an initializer function, simply declare it like this: 384 /// 385 /// ```rust 386 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 387 /// # use kernel::{init, pin_init, prelude::*, init::*}; 388 /// # use core::pin::Pin; 389 /// # #[pin_data] 390 /// # struct Foo { 391 /// # a: usize, 392 /// # b: Bar, 393 /// # } 394 /// # #[pin_data] 395 /// # struct Bar { 396 /// # x: u32, 397 /// # } 398 /// impl Foo { 399 /// fn new() -> impl PinInit<Self> { 400 /// pin_init!(Self { 401 /// a: 42, 402 /// b: Bar { 403 /// x: 64, 404 /// }, 405 /// }) 406 /// } 407 /// } 408 /// ``` 409 /// 410 /// Users of `Foo` can now create it like this: 411 /// 412 /// ```rust 413 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 414 /// # use kernel::{init, pin_init, macros::pin_data, init::*}; 415 /// # use core::pin::Pin; 416 /// # #[pin_data] 417 /// # struct Foo { 418 /// # a: usize, 419 /// # b: Bar, 420 /// # } 421 /// # #[pin_data] 422 /// # struct Bar { 423 /// # x: u32, 424 /// # } 425 /// # impl Foo { 426 /// # fn new() -> impl PinInit<Self> { 427 /// # pin_init!(Self { 428 /// # a: 42, 429 /// # b: Bar { 430 /// # x: 64, 431 /// # }, 432 /// # }) 433 /// # } 434 /// # } 435 /// let foo = Box::pin_init(Foo::new()); 436 /// ``` 437 /// 438 /// They can also easily embed it into their own `struct`s: 439 /// 440 /// ```rust 441 /// # #![allow(clippy::disallowed_names, clippy::new_ret_no_self)] 442 /// # use kernel::{init, pin_init, macros::pin_data, init::*}; 443 /// # use core::pin::Pin; 444 /// # #[pin_data] 445 /// # struct Foo { 446 /// # a: usize, 447 /// # b: Bar, 448 /// # } 449 /// # #[pin_data] 450 /// # struct Bar { 451 /// # x: u32, 452 /// # } 453 /// # impl Foo { 454 /// # fn new() -> impl PinInit<Self> { 455 /// # pin_init!(Self { 456 /// # a: 42, 457 /// # b: Bar { 458 /// # x: 64, 459 /// # }, 460 /// # }) 461 /// # } 462 /// # } 463 /// #[pin_data] 464 /// struct FooContainer { 465 /// #[pin] 466 /// foo1: Foo, 467 /// #[pin] 468 /// foo2: Foo, 469 /// other: u32, 470 /// } 471 /// 472 /// impl FooContainer { 473 /// fn new(other: u32) -> impl PinInit<Self> { 474 /// pin_init!(Self { 475 /// foo1 <- Foo::new(), 476 /// foo2 <- Foo::new(), 477 /// other, 478 /// }) 479 /// } 480 /// } 481 /// ``` 482 /// 483 /// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`. 484 /// This signifies that the given field is initialized in-place. As with `struct` initializers, just 485 /// writing the field (in this case `other`) without `:` or `<-` means `other: other,`. 486 /// 487 /// # Syntax 488 /// 489 /// As already mentioned in the examples above, inside of `pin_init!` a `struct` initializer with 490 /// the following modifications is expected: 491 /// - Fields that you want to initialize in-place have to use `<-` instead of `:`. 492 /// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`] 493 /// pointer named `this` inside of the initializer. 494 /// 495 /// For instance: 496 /// 497 /// ```rust 498 /// # use kernel::pin_init; 499 /// # use macros::pin_data; 500 /// # use core::{ptr::addr_of_mut, marker::PhantomPinned}; 501 /// #[pin_data] 502 /// struct Buf { 503 /// // `ptr` points into `buf`. 504 /// ptr: *mut u8, 505 /// buf: [u8; 64], 506 /// #[pin] 507 /// pin: PhantomPinned, 508 /// } 509 /// pin_init!(&this in Buf { 510 /// buf: [0; 64], 511 /// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() }, 512 /// pin: PhantomPinned, 513 /// }); 514 /// ``` 515 /// 516 /// [`try_pin_init!`]: kernel::try_pin_init 517 /// [`NonNull<Self>`]: core::ptr::NonNull 518 // For a detailed example of how this macro works, see the module documentation of the hidden 519 // module `__internal` inside of `init/__internal.rs`. 520 #[macro_export] 521 macro_rules! pin_init { 522 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 523 $($fields:tt)* 524 }) => { 525 $crate::try_pin_init!( 526 @this($($this)?), 527 @typ($t $(::<$($generics),*>)?), 528 @fields($($fields)*), 529 @error(::core::convert::Infallible), 530 ) 531 }; 532 } 533 534 /// Construct an in-place, fallible pinned initializer for `struct`s. 535 /// 536 /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`]. 537 /// 538 /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop 539 /// initialization and return the error. 540 /// 541 /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when 542 /// initialization fails, the memory can be safely deallocated without any further modifications. 543 /// 544 /// This macro defaults the error to [`Error`]. 545 /// 546 /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` 547 /// after the `struct` initializer to specify the error type you want to use. 548 /// 549 /// # Examples 550 /// 551 /// ```rust 552 /// # #![feature(new_uninit)] 553 /// use kernel::{init::{self, PinInit}, error::Error}; 554 /// #[pin_data] 555 /// struct BigBuf { 556 /// big: Box<[u8; 1024 * 1024 * 1024]>, 557 /// small: [u8; 1024 * 1024], 558 /// ptr: *mut u8, 559 /// } 560 /// 561 /// impl BigBuf { 562 /// fn new() -> impl PinInit<Self, Error> { 563 /// try_pin_init!(Self { 564 /// big: Box::init(init::zeroed())?, 565 /// small: [0; 1024 * 1024], 566 /// ptr: core::ptr::null_mut(), 567 /// }? Error) 568 /// } 569 /// } 570 /// ``` 571 // For a detailed example of how this macro works, see the module documentation of the hidden 572 // module `__internal` inside of `init/__internal.rs`. 573 #[macro_export] 574 macro_rules! try_pin_init { 575 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 576 $($fields:tt)* 577 }) => { 578 $crate::try_pin_init!( 579 @this($($this)?), 580 @typ($t $(::<$($generics),*>)? ), 581 @fields($($fields)*), 582 @error($crate::error::Error), 583 ) 584 }; 585 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 586 $($fields:tt)* 587 }? $err:ty) => { 588 $crate::try_pin_init!( 589 @this($($this)?), 590 @typ($t $(::<$($generics),*>)? ), 591 @fields($($fields)*), 592 @error($err), 593 ) 594 }; 595 ( 596 @this($($this:ident)?), 597 @typ($t:ident $(::<$($generics:ty),*>)?), 598 @fields($($fields:tt)*), 599 @error($err:ty), 600 ) => {{ 601 // We do not want to allow arbitrary returns, so we declare this type as the `Ok` return 602 // type and shadow it later when we insert the arbitrary user code. That way there will be 603 // no possibility of returning without `unsafe`. 604 struct __InitOk; 605 // Get the pin data from the supplied type. 606 let data = unsafe { 607 use $crate::init::__internal::HasPinData; 608 $t$(::<$($generics),*>)?::__pin_data() 609 }; 610 // Ensure that `data` really is of type `PinData` and help with type inference: 611 let init = $crate::init::__internal::PinData::make_closure::<_, __InitOk, $err>( 612 data, 613 move |slot| { 614 { 615 // Shadow the structure so it cannot be used to return early. 616 struct __InitOk; 617 // Create the `this` so it can be referenced by the user inside of the 618 // expressions creating the individual fields. 619 $(let $this = unsafe { ::core::ptr::NonNull::new_unchecked(slot) };)? 620 // Initialize every field. 621 $crate::try_pin_init!(init_slot: 622 @data(data), 623 @slot(slot), 624 @munch_fields($($fields)*,), 625 ); 626 // We use unreachable code to ensure that all fields have been mentioned exactly 627 // once, this struct initializer will still be type-checked and complain with a 628 // very natural error message if a field is forgotten/mentioned more than once. 629 #[allow(unreachable_code, clippy::diverging_sub_expression)] 630 if false { 631 $crate::try_pin_init!(make_initializer: 632 @slot(slot), 633 @type_name($t), 634 @munch_fields($($fields)*,), 635 @acc(), 636 ); 637 } 638 // Forget all guards, since initialization was a success. 639 $crate::try_pin_init!(forget_guards: 640 @munch_fields($($fields)*,), 641 ); 642 } 643 Ok(__InitOk) 644 } 645 ); 646 let init = move |slot| -> ::core::result::Result<(), $err> { 647 init(slot).map(|__InitOk| ()) 648 }; 649 let init = unsafe { $crate::init::pin_init_from_closure::<_, $err>(init) }; 650 init 651 }}; 652 (init_slot: 653 @data($data:ident), 654 @slot($slot:ident), 655 @munch_fields($(,)?), 656 ) => { 657 // Endpoint of munching, no fields are left. 658 }; 659 (init_slot: 660 @data($data:ident), 661 @slot($slot:ident), 662 // In-place initialization syntax. 663 @munch_fields($field:ident <- $val:expr, $($rest:tt)*), 664 ) => { 665 let $field = $val; 666 // Call the initializer. 667 // 668 // SAFETY: `slot` is valid, because we are inside of an initializer closure, we 669 // return when an error/panic occurs. 670 // We also use the `data` to require the correct trait (`Init` or `PinInit`) for `$field`. 671 unsafe { $data.$field(::core::ptr::addr_of_mut!((*$slot).$field), $field)? }; 672 // Create the drop guard. 673 // 674 // We only give access to `&DropGuard`, so it cannot be forgotten via safe code. 675 // 676 // SAFETY: We forget the guard later when initialization has succeeded. 677 let $field = &unsafe { 678 $crate::init::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) 679 }; 680 681 $crate::try_pin_init!(init_slot: 682 @data($data), 683 @slot($slot), 684 @munch_fields($($rest)*), 685 ); 686 }; 687 (init_slot: 688 @data($data:ident), 689 @slot($slot:ident), 690 // Direct value init, this is safe for every field. 691 @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), 692 ) => { 693 $(let $field = $val;)? 694 // Initialize the field. 695 // 696 // SAFETY: The memory at `slot` is uninitialized. 697 unsafe { ::core::ptr::write(::core::ptr::addr_of_mut!((*$slot).$field), $field) }; 698 // Create the drop guard: 699 // 700 // We only give access to `&DropGuard`, so it cannot be accidentally forgotten. 701 // 702 // SAFETY: We forget the guard later when initialization has succeeded. 703 let $field = &unsafe { 704 $crate::init::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) 705 }; 706 707 $crate::try_pin_init!(init_slot: 708 @data($data), 709 @slot($slot), 710 @munch_fields($($rest)*), 711 ); 712 }; 713 (make_initializer: 714 @slot($slot:ident), 715 @type_name($t:ident), 716 @munch_fields($(,)?), 717 @acc($($acc:tt)*), 718 ) => { 719 // Endpoint, nothing more to munch, create the initializer. 720 // Since we are in the `if false` branch, this will never get executed. We abuse `slot` to 721 // get the correct type inference here: 722 unsafe { 723 ::core::ptr::write($slot, $t { 724 $($acc)* 725 }); 726 } 727 }; 728 (make_initializer: 729 @slot($slot:ident), 730 @type_name($t:ident), 731 @munch_fields($field:ident <- $val:expr, $($rest:tt)*), 732 @acc($($acc:tt)*), 733 ) => { 734 $crate::try_pin_init!(make_initializer: 735 @slot($slot), 736 @type_name($t), 737 @munch_fields($($rest)*), 738 @acc($($acc)* $field: ::core::panic!(),), 739 ); 740 }; 741 (make_initializer: 742 @slot($slot:ident), 743 @type_name($t:ident), 744 @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), 745 @acc($($acc:tt)*), 746 ) => { 747 $crate::try_pin_init!(make_initializer: 748 @slot($slot), 749 @type_name($t), 750 @munch_fields($($rest)*), 751 @acc($($acc)* $field: ::core::panic!(),), 752 ); 753 }; 754 (forget_guards: 755 @munch_fields($(,)?), 756 ) => { 757 // Munching finished. 758 }; 759 (forget_guards: 760 @munch_fields($field:ident <- $val:expr, $($rest:tt)*), 761 ) => { 762 unsafe { $crate::init::__internal::DropGuard::forget($field) }; 763 764 $crate::try_pin_init!(forget_guards: 765 @munch_fields($($rest)*), 766 ); 767 }; 768 (forget_guards: 769 @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), 770 ) => { 771 unsafe { $crate::init::__internal::DropGuard::forget($field) }; 772 773 $crate::try_pin_init!(forget_guards: 774 @munch_fields($($rest)*), 775 ); 776 }; 777 } 778 779 /// Construct an in-place initializer for `struct`s. 780 /// 781 /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use 782 /// [`try_init!`]. 783 /// 784 /// The syntax is identical to [`pin_init!`] and its safety caveats also apply: 785 /// - `unsafe` code must guarantee either full initialization or return an error and allow 786 /// deallocation of the memory. 787 /// - the fields are initialized in the order given in the initializer. 788 /// - no references to fields are allowed to be created inside of the initializer. 789 /// 790 /// This initializer is for initializing data in-place that might later be moved. If you want to 791 /// pin-initialize, use [`pin_init!`]. 792 // For a detailed example of how this macro works, see the module documentation of the hidden 793 // module `__internal` inside of `init/__internal.rs`. 794 #[macro_export] 795 macro_rules! init { 796 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 797 $($fields:tt)* 798 }) => { 799 $crate::try_init!( 800 @this($($this)?), 801 @typ($t $(::<$($generics),*>)?), 802 @fields($($fields)*), 803 @error(::core::convert::Infallible), 804 ) 805 } 806 } 807 808 /// Construct an in-place fallible initializer for `struct`s. 809 /// 810 /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use 811 /// [`init!`]. 812 /// 813 /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, 814 /// append `? $type` after the `struct` initializer. 815 /// The safety caveats from [`try_pin_init!`] also apply: 816 /// - `unsafe` code must guarantee either full initialization or return an error and allow 817 /// deallocation of the memory. 818 /// - the fields are initialized in the order given in the initializer. 819 /// - no references to fields are allowed to be created inside of the initializer. 820 /// 821 /// # Examples 822 /// 823 /// ```rust 824 /// use kernel::{init::PinInit, error::Error, InPlaceInit}; 825 /// struct BigBuf { 826 /// big: Box<[u8; 1024 * 1024 * 1024]>, 827 /// small: [u8; 1024 * 1024], 828 /// } 829 /// 830 /// impl BigBuf { 831 /// fn new() -> impl Init<Self, Error> { 832 /// try_init!(Self { 833 /// big: Box::init(zeroed())?, 834 /// small: [0; 1024 * 1024], 835 /// }? Error) 836 /// } 837 /// } 838 /// ``` 839 // For a detailed example of how this macro works, see the module documentation of the hidden 840 // module `__internal` inside of `init/__internal.rs`. 841 #[macro_export] 842 macro_rules! try_init { 843 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 844 $($fields:tt)* 845 }) => { 846 $crate::try_init!( 847 @this($($this)?), 848 @typ($t $(::<$($generics),*>)?), 849 @fields($($fields)*), 850 @error($crate::error::Error), 851 ) 852 }; 853 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { 854 $($fields:tt)* 855 }? $err:ty) => { 856 $crate::try_init!( 857 @this($($this)?), 858 @typ($t $(::<$($generics),*>)?), 859 @fields($($fields)*), 860 @error($err), 861 ) 862 }; 863 ( 864 @this($($this:ident)?), 865 @typ($t:ident $(::<$($generics:ty),*>)?), 866 @fields($($fields:tt)*), 867 @error($err:ty), 868 ) => {{ 869 // We do not want to allow arbitrary returns, so we declare this type as the `Ok` return 870 // type and shadow it later when we insert the arbitrary user code. That way there will be 871 // no possibility of returning without `unsafe`. 872 struct __InitOk; 873 // Get the init data from the supplied type. 874 let data = unsafe { 875 use $crate::init::__internal::HasInitData; 876 $t$(::<$($generics),*>)?::__init_data() 877 }; 878 // Ensure that `data` really is of type `InitData` and help with type inference: 879 let init = $crate::init::__internal::InitData::make_closure::<_, __InitOk, $err>( 880 data, 881 move |slot| { 882 { 883 // Shadow the structure so it cannot be used to return early. 884 struct __InitOk; 885 // Create the `this` so it can be referenced by the user inside of the 886 // expressions creating the individual fields. 887 $(let $this = unsafe { ::core::ptr::NonNull::new_unchecked(slot) };)? 888 // Initialize every field. 889 $crate::try_init!(init_slot: 890 @slot(slot), 891 @munch_fields($($fields)*,), 892 ); 893 // We use unreachable code to ensure that all fields have been mentioned exactly 894 // once, this struct initializer will still be type-checked and complain with a 895 // very natural error message if a field is forgotten/mentioned more than once. 896 #[allow(unreachable_code, clippy::diverging_sub_expression)] 897 if false { 898 $crate::try_init!(make_initializer: 899 @slot(slot), 900 @type_name($t), 901 @munch_fields($($fields)*,), 902 @acc(), 903 ); 904 } 905 // Forget all guards, since initialization was a success. 906 $crate::try_init!(forget_guards: 907 @munch_fields($($fields)*,), 908 ); 909 } 910 Ok(__InitOk) 911 } 912 ); 913 let init = move |slot| -> ::core::result::Result<(), $err> { 914 init(slot).map(|__InitOk| ()) 915 }; 916 let init = unsafe { $crate::init::init_from_closure::<_, $err>(init) }; 917 init 918 }}; 919 (init_slot: 920 @slot($slot:ident), 921 @munch_fields( $(,)?), 922 ) => { 923 // Endpoint of munching, no fields are left. 924 }; 925 (init_slot: 926 @slot($slot:ident), 927 @munch_fields($field:ident <- $val:expr, $($rest:tt)*), 928 ) => { 929 let $field = $val; 930 // Call the initializer. 931 // 932 // SAFETY: `slot` is valid, because we are inside of an initializer closure, we 933 // return when an error/panic occurs. 934 unsafe { 935 $crate::init::Init::__init($field, ::core::ptr::addr_of_mut!((*$slot).$field))?; 936 } 937 // Create the drop guard. 938 // 939 // We only give access to `&DropGuard`, so it cannot be accidentally forgotten. 940 // 941 // SAFETY: We forget the guard later when initialization has succeeded. 942 let $field = &unsafe { 943 $crate::init::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) 944 }; 945 946 $crate::try_init!(init_slot: 947 @slot($slot), 948 @munch_fields($($rest)*), 949 ); 950 }; 951 (init_slot: 952 @slot($slot:ident), 953 // Direct value init. 954 @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), 955 ) => { 956 $(let $field = $val;)? 957 // Call the initializer. 958 // 959 // SAFETY: The memory at `slot` is uninitialized. 960 unsafe { ::core::ptr::write(::core::ptr::addr_of_mut!((*$slot).$field), $field) }; 961 // Create the drop guard. 962 // 963 // We only give access to `&DropGuard`, so it cannot be accidentally forgotten. 964 // 965 // SAFETY: We forget the guard later when initialization has succeeded. 966 let $field = &unsafe { 967 $crate::init::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) 968 }; 969 970 $crate::try_init!(init_slot: 971 @slot($slot), 972 @munch_fields($($rest)*), 973 ); 974 }; 975 (make_initializer: 976 @slot($slot:ident), 977 @type_name($t:ident), 978 @munch_fields( $(,)?), 979 @acc($($acc:tt)*), 980 ) => { 981 // Endpoint, nothing more to munch, create the initializer. 982 // Since we are in the `if false` branch, this will never get executed. We abuse `slot` to 983 // get the correct type inference here: 984 unsafe { 985 ::core::ptr::write($slot, $t { 986 $($acc)* 987 }); 988 } 989 }; 990 (make_initializer: 991 @slot($slot:ident), 992 @type_name($t:ident), 993 @munch_fields($field:ident <- $val:expr, $($rest:tt)*), 994 @acc($($acc:tt)*), 995 ) => { 996 $crate::try_init!(make_initializer: 997 @slot($slot), 998 @type_name($t), 999 @munch_fields($($rest)*), 1000 @acc($($acc)*$field: ::core::panic!(),), 1001 ); 1002 }; 1003 (make_initializer: 1004 @slot($slot:ident), 1005 @type_name($t:ident), 1006 @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), 1007 @acc($($acc:tt)*), 1008 ) => { 1009 $crate::try_init!(make_initializer: 1010 @slot($slot), 1011 @type_name($t), 1012 @munch_fields($($rest)*), 1013 @acc($($acc)*$field: ::core::panic!(),), 1014 ); 1015 }; 1016 (forget_guards: 1017 @munch_fields($(,)?), 1018 ) => { 1019 // Munching finished. 1020 }; 1021 (forget_guards: 1022 @munch_fields($field:ident <- $val:expr, $($rest:tt)*), 1023 ) => { 1024 unsafe { $crate::init::__internal::DropGuard::forget($field) }; 1025 1026 $crate::try_init!(forget_guards: 1027 @munch_fields($($rest)*), 1028 ); 1029 }; 1030 (forget_guards: 1031 @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), 1032 ) => { 1033 unsafe { $crate::init::__internal::DropGuard::forget($field) }; 1034 1035 $crate::try_init!(forget_guards: 1036 @munch_fields($($rest)*), 1037 ); 1038 }; 1039 } 1040 1041 /// A pin-initializer for the type `T`. 1042 /// 1043 /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can 1044 /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the 1045 /// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this. 1046 /// 1047 /// Also see the [module description](self). 1048 /// 1049 /// # Safety 1050 /// 1051 /// When implementing this type you will need to take great care. Also there are probably very few 1052 /// cases where a manual implementation is necessary. Use [`pin_init_from_closure`] where possible. 1053 /// 1054 /// The [`PinInit::__pinned_init`] function 1055 /// - returns `Ok(())` if it initialized every field of `slot`, 1056 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: 1057 /// - `slot` can be deallocated without UB occurring, 1058 /// - `slot` does not need to be dropped, 1059 /// - `slot` is not partially initialized. 1060 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. 1061 /// 1062 /// [`Arc<T>`]: crate::sync::Arc 1063 /// [`Arc::pin_init`]: crate::sync::Arc::pin_init 1064 #[must_use = "An initializer must be used in order to create its value."] 1065 pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized { 1066 /// Initializes `slot`. 1067 /// 1068 /// # Safety 1069 /// 1070 /// - `slot` is a valid pointer to uninitialized memory. 1071 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to 1072 /// deallocate. 1073 /// - `slot` will not move until it is dropped, i.e. it will be pinned. 1074 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>; 1075 } 1076 1077 /// An initializer for `T`. 1078 /// 1079 /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can 1080 /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the 1081 /// [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because 1082 /// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well. 1083 /// 1084 /// Also see the [module description](self). 1085 /// 1086 /// # Safety 1087 /// 1088 /// When implementing this type you will need to take great care. Also there are probably very few 1089 /// cases where a manual implementation is necessary. Use [`init_from_closure`] where possible. 1090 /// 1091 /// The [`Init::__init`] function 1092 /// - returns `Ok(())` if it initialized every field of `slot`, 1093 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: 1094 /// - `slot` can be deallocated without UB occurring, 1095 /// - `slot` does not need to be dropped, 1096 /// - `slot` is not partially initialized. 1097 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. 1098 /// 1099 /// The `__pinned_init` function from the supertrait [`PinInit`] needs to execute the exact same 1100 /// code as `__init`. 1101 /// 1102 /// Contrary to its supertype [`PinInit<T, E>`] the caller is allowed to 1103 /// move the pointee after initialization. 1104 /// 1105 /// [`Arc<T>`]: crate::sync::Arc 1106 #[must_use = "An initializer must be used in order to create its value."] 1107 pub unsafe trait Init<T: ?Sized, E = Infallible>: Sized { 1108 /// Initializes `slot`. 1109 /// 1110 /// # Safety 1111 /// 1112 /// - `slot` is a valid pointer to uninitialized memory. 1113 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to 1114 /// deallocate. 1115 unsafe fn __init(self, slot: *mut T) -> Result<(), E>; 1116 } 1117 1118 // SAFETY: Every in-place initializer can also be used as a pin-initializer. 1119 unsafe impl<T: ?Sized, E, I> PinInit<T, E> for I 1120 where 1121 I: Init<T, E>, 1122 { 1123 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { 1124 // SAFETY: `__init` meets the same requirements as `__pinned_init`, except that it does not 1125 // require `slot` to not move after init. 1126 unsafe { self.__init(slot) } 1127 } 1128 } 1129 1130 /// Creates a new [`PinInit<T, E>`] from the given closure. 1131 /// 1132 /// # Safety 1133 /// 1134 /// The closure: 1135 /// - returns `Ok(())` if it initialized every field of `slot`, 1136 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: 1137 /// - `slot` can be deallocated without UB occurring, 1138 /// - `slot` does not need to be dropped, 1139 /// - `slot` is not partially initialized. 1140 /// - may assume that the `slot` does not move if `T: !Unpin`, 1141 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. 1142 #[inline] 1143 pub const unsafe fn pin_init_from_closure<T: ?Sized, E>( 1144 f: impl FnOnce(*mut T) -> Result<(), E>, 1145 ) -> impl PinInit<T, E> { 1146 __internal::InitClosure(f, PhantomData) 1147 } 1148 1149 /// Creates a new [`Init<T, E>`] from the given closure. 1150 /// 1151 /// # Safety 1152 /// 1153 /// The closure: 1154 /// - returns `Ok(())` if it initialized every field of `slot`, 1155 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means: 1156 /// - `slot` can be deallocated without UB occurring, 1157 /// - `slot` does not need to be dropped, 1158 /// - `slot` is not partially initialized. 1159 /// - the `slot` may move after initialization. 1160 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. 1161 #[inline] 1162 pub const unsafe fn init_from_closure<T: ?Sized, E>( 1163 f: impl FnOnce(*mut T) -> Result<(), E>, 1164 ) -> impl Init<T, E> { 1165 __internal::InitClosure(f, PhantomData) 1166 } 1167 1168 /// An initializer that leaves the memory uninitialized. 1169 /// 1170 /// The initializer is a no-op. The `slot` memory is not changed. 1171 #[inline] 1172 pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> { 1173 // SAFETY: The memory is allowed to be uninitialized. 1174 unsafe { init_from_closure(|_| Ok(())) } 1175 } 1176 1177 // SAFETY: Every type can be initialized by-value. 1178 unsafe impl<T> Init<T> for T { 1179 unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible> { 1180 unsafe { slot.write(self) }; 1181 Ok(()) 1182 } 1183 } 1184 1185 /// Smart pointer that can initialize memory in-place. 1186 pub trait InPlaceInit<T>: Sized { 1187 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this 1188 /// type. 1189 /// 1190 /// If `T: !Unpin` it will not be able to move afterwards. 1191 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> 1192 where 1193 E: From<AllocError>; 1194 1195 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this 1196 /// type. 1197 /// 1198 /// If `T: !Unpin` it will not be able to move afterwards. 1199 fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>> 1200 where 1201 Error: From<E>, 1202 { 1203 // SAFETY: We delegate to `init` and only change the error type. 1204 let init = unsafe { 1205 pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) 1206 }; 1207 Self::try_pin_init(init) 1208 } 1209 1210 /// Use the given initializer to in-place initialize a `T`. 1211 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> 1212 where 1213 E: From<AllocError>; 1214 1215 /// Use the given initializer to in-place initialize a `T`. 1216 fn init<E>(init: impl Init<T, E>) -> error::Result<Self> 1217 where 1218 Error: From<E>, 1219 { 1220 // SAFETY: We delegate to `init` and only change the error type. 1221 let init = unsafe { 1222 init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) 1223 }; 1224 Self::try_init(init) 1225 } 1226 } 1227 1228 impl<T> InPlaceInit<T> for Box<T> { 1229 #[inline] 1230 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> 1231 where 1232 E: From<AllocError>, 1233 { 1234 let mut this = Box::try_new_uninit()?; 1235 let slot = this.as_mut_ptr(); 1236 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 1237 // slot is valid and will not be moved, because we pin it later. 1238 unsafe { init.__pinned_init(slot)? }; 1239 // SAFETY: All fields have been initialized. 1240 Ok(unsafe { this.assume_init() }.into()) 1241 } 1242 1243 #[inline] 1244 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> 1245 where 1246 E: From<AllocError>, 1247 { 1248 let mut this = Box::try_new_uninit()?; 1249 let slot = this.as_mut_ptr(); 1250 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 1251 // slot is valid. 1252 unsafe { init.__init(slot)? }; 1253 // SAFETY: All fields have been initialized. 1254 Ok(unsafe { this.assume_init() }) 1255 } 1256 } 1257 1258 impl<T> InPlaceInit<T> for UniqueArc<T> { 1259 #[inline] 1260 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> 1261 where 1262 E: From<AllocError>, 1263 { 1264 let mut this = UniqueArc::try_new_uninit()?; 1265 let slot = this.as_mut_ptr(); 1266 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 1267 // slot is valid and will not be moved, because we pin it later. 1268 unsafe { init.__pinned_init(slot)? }; 1269 // SAFETY: All fields have been initialized. 1270 Ok(unsafe { this.assume_init() }.into()) 1271 } 1272 1273 #[inline] 1274 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> 1275 where 1276 E: From<AllocError>, 1277 { 1278 let mut this = UniqueArc::try_new_uninit()?; 1279 let slot = this.as_mut_ptr(); 1280 // SAFETY: When init errors/panics, slot will get deallocated but not dropped, 1281 // slot is valid. 1282 unsafe { init.__init(slot)? }; 1283 // SAFETY: All fields have been initialized. 1284 Ok(unsafe { this.assume_init() }) 1285 } 1286 } 1287 1288 /// Trait facilitating pinned destruction. 1289 /// 1290 /// Use [`pinned_drop`] to implement this trait safely: 1291 /// 1292 /// ```rust 1293 /// # use kernel::sync::Mutex; 1294 /// use kernel::macros::pinned_drop; 1295 /// use core::pin::Pin; 1296 /// #[pin_data(PinnedDrop)] 1297 /// struct Foo { 1298 /// #[pin] 1299 /// mtx: Mutex<usize>, 1300 /// } 1301 /// 1302 /// #[pinned_drop] 1303 /// impl PinnedDrop for Foo { 1304 /// fn drop(self: Pin<&mut Self>) { 1305 /// pr_info!("Foo is being dropped!"); 1306 /// } 1307 /// } 1308 /// ``` 1309 /// 1310 /// # Safety 1311 /// 1312 /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl. 1313 /// 1314 /// [`pinned_drop`]: kernel::macros::pinned_drop 1315 pub unsafe trait PinnedDrop: __internal::HasPinData { 1316 /// Executes the pinned destructor of this type. 1317 /// 1318 /// While this function is marked safe, it is actually unsafe to call it manually. For this 1319 /// reason it takes an additional parameter. This type can only be constructed by `unsafe` code 1320 /// and thus prevents this function from being called where it should not. 1321 /// 1322 /// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute 1323 /// automatically. 1324 fn drop(self: Pin<&mut Self>, only_call_from_drop: __internal::OnlyCallFromDrop); 1325 } 1326