// SPDX-License-Identifier: Apache-2.0 OR MIT12//! Library to safely and fallibly initialize pinned `struct`s using in-place constructors.3//!4//! [Pinning][pinning] is Rust's way of ensuring data does not move.5//!6//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack7//! overflow.8//!9//! This library's main use-case is in [Rust-for-Linux]. Although this version can be used10//! standalone.11//!12//! There are cases when you want to in-place initialize a struct. For example when it is very big13//! and moving it from the stack is not an option, because it is bigger than the stack itself.14//! Another reason would be that you need the address of the object to initialize it. This stands15//! in direct conflict with Rust's normal process of first initializing an object and then moving16//! it into it's final memory location. For more information, see17//! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>.18//!19//! This library allows you to do in-place initialization safely.20//!21//! ## Nightly Needed for `alloc` feature22//!23//! This library requires the [`allocator_api` unstable feature] when the `alloc` feature is24//! enabled and thus this feature can only be used with a nightly compiler. When enabling the25//! `alloc` feature, the user will be required to activate `allocator_api` as well.26//!27//! [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html28//!29//! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler.30//! However, using the crate on stable compilers is possible by disabling `alloc`. In practice this31//! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std32//! mode.33//!34//! ## Nightly needed for `unsafe-pinned` feature35//!36//! This feature enables the `Wrapper` implementation on the unstable `core::pin::UnsafePinned` type.37//! This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735)38//! and therefore a nightly compiler. Note that this feature is not enabled by default.39//!40//! # Overview41//!42//! To initialize a `struct` with an in-place constructor you will need two things:43//! - an in-place constructor,44//! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],45//! [`Box<T>`] or any other smart pointer that supports this library).46//!47//! To get an in-place constructor there are generally three options:48//! - directly creating an in-place constructor using the [`pin_init!`] macro,49//! - a custom function/macro returning an in-place constructor provided by someone else,50//! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.51//!52//! Aside from pinned initialization, this library also supports in-place construction without53//! pinning, the macros/types/functions are generally named like the pinned variants without the54//! `pin_` prefix.55//!56//! # Examples57//!58//! Throughout the examples we will often make use of the `CMutex` type which can be found in59//! `../examples/mutex.rs`. It is essentially a userland rebuild of the `struct mutex` type from60//! the Linux kernel. It also uses a wait list and a basic spinlock. Importantly the wait list61//! requires it to be pinned to be locked and thus is a prime candidate for using this library.62//!63//! ## Using the [`pin_init!`] macro64//!65//! If you want to use [`PinInit`], then you will have to annotate your `struct` with66//! `#[`[`pin_data`]`]`. It is a macro that uses `#[pin]` as a marker for67//! [structurally pinned fields]. After doing this, you can then create an in-place constructor via68//! [`pin_init!`]. The syntax is almost the same as normal `struct` initializers. The difference is69//! that you need to write `<-` instead of `:` for fields that you want to initialize in-place.70//!71//! ```rust72//! # #![expect(clippy::disallowed_names)]73//! # #![feature(allocator_api)]74//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;75//! # use core::pin::Pin;76//! use pin_init::{pin_data, pin_init, InPlaceInit};77//!78//! #[pin_data]79//! struct Foo {80//! #[pin]81//! a: CMutex<usize>,82//! b: u32,83//! }84//!85//! let foo = pin_init!(Foo {86//! a <- CMutex::new(42),87//! b: 24,88//! });89//! # let _ = Box::pin_init(foo);90//! ```91//!92//! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like93//! (or just the stack) to actually initialize a `Foo`:94//!95//! ```rust96//! # #![expect(clippy::disallowed_names)]97//! # #![feature(allocator_api)]98//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;99//! # use core::{alloc::AllocError, pin::Pin};100//! # use pin_init::*;101//! #102//! # #[pin_data]103//! # struct Foo {104//! # #[pin]105//! # a: CMutex<usize>,106//! # b: u32,107//! # }108//! #109//! # let foo = pin_init!(Foo {110//! # a <- CMutex::new(42),111//! # b: 24,112//! # });113//! let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo);114//! ```115//!116//! For more information see the [`pin_init!`] macro.117//!118//! ## Using a custom function/macro that returns an initializer119//!120//! Many types that use this library supply a function/macro that returns an initializer, because121//! the above method only works for types where you can access the fields.122//!123//! ```rust124//! # #![feature(allocator_api)]125//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;126//! # use pin_init::*;127//! # use std::sync::Arc;128//! # use core::pin::Pin;129//! let mtx: Result<Pin<Arc<CMutex<usize>>>, _> = Arc::pin_init(CMutex::new(42));130//! ```131//!132//! To declare an init macro/function you just return an [`impl PinInit<T, E>`]:133//!134//! ```rust135//! # #![feature(allocator_api)]136//! # use pin_init::*;137//! # #[path = "../examples/error.rs"] mod error; use error::Error;138//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;139//! #[pin_data]140//! struct DriverData {141//! #[pin]142//! status: CMutex<i32>,143//! buffer: Box<[u8; 1_000_000]>,144//! }145//!146//! impl DriverData {147//! fn new() -> impl PinInit<Self, Error> {148//! try_pin_init!(Self {149//! status <- CMutex::new(0),150//! buffer: Box::init(pin_init::init_zeroed())?,151//! }? Error)152//! }153//! }154//! ```155//!156//! ## Manual creation of an initializer157//!158//! Often when working with primitives the previous approaches are not sufficient. That is where159//! [`pin_init_from_closure()`] comes in. This `unsafe` function allows you to create a160//! [`impl PinInit<T, E>`] directly from a closure. Of course you have to ensure that the closure161//! actually does the initialization in the correct way. Here are the things to look out for162//! (we are calling the parameter to the closure `slot`):163//! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so164//! `slot` now contains a valid bit pattern for the type `T`,165//! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so166//! you need to take care to clean up anything if your initialization fails mid-way,167//! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of168//! `slot` gets called.169//!170//! ```rust171//! # #![feature(extern_types)]172//! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure};173//! use core::{174//! ptr::addr_of_mut,175//! marker::PhantomPinned,176//! cell::UnsafeCell,177//! pin::Pin,178//! mem::MaybeUninit,179//! };180//! mod bindings {181//! #[repr(C)]182//! pub struct foo {183//! /* fields from C ... */184//! }185//! extern "C" {186//! pub fn init_foo(ptr: *mut foo);187//! pub fn destroy_foo(ptr: *mut foo);188//! #[must_use = "you must check the error return code"]189//! pub fn enable_foo(ptr: *mut foo, flags: u32) -> i32;190//! }191//! }192//!193//! /// # Invariants194//! ///195//! /// `foo` is always initialized196//! #[pin_data(PinnedDrop)]197//! pub struct RawFoo {198//! #[pin]199//! _p: PhantomPinned,200//! #[pin]201//! foo: UnsafeCell<MaybeUninit<bindings::foo>>,202//! }203//!204//! impl RawFoo {205//! pub fn new(flags: u32) -> impl PinInit<Self, i32> {206//! // SAFETY:207//! // - when the closure returns `Ok(())`, then it has successfully initialized and208//! // enabled `foo`,209//! // - when it returns `Err(e)`, then it has cleaned up before210//! unsafe {211//! pin_init_from_closure(move |slot: *mut Self| {212//! // `slot` contains uninit memory, avoid creating a reference.213//! let foo = addr_of_mut!((*slot).foo);214//! let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>();215//!216//! // Initialize the `foo`217//! bindings::init_foo(foo);218//!219//! // Try to enable it.220//! let err = bindings::enable_foo(foo, flags);221//! if err != 0 {222//! // Enabling has failed, first clean up the foo and then return the error.223//! bindings::destroy_foo(foo);224//! Err(err)225//! } else {226//! // All fields of `RawFoo` have been initialized, since `_p` is a ZST.227//! Ok(())228//! }229//! })230//! }231//! }232//! }233//!234//! #[pinned_drop]235//! impl PinnedDrop for RawFoo {236//! fn drop(self: Pin<&mut Self>) {237//! // SAFETY: Since `foo` is initialized, destroying is safe.238//! unsafe { bindings::destroy_foo(self.foo.get().cast::<bindings::foo>()) };239//! }240//! }241//! ```242//!243//! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside244//! the `kernel` crate. The [`sync`] module is a good starting point.245//!246//! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html247//! [pinning]: https://doc.rust-lang.org/std/pin/index.html248//! [structurally pinned fields]:249//! https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning250//! [stack]: crate::stack_pin_init251#![cfg_attr(252kernel,253doc = "[`Arc<T>`]: https://rust.docs.kernel.org/kernel/sync/struct.Arc.html"254)]255#![cfg_attr(256kernel,257doc = "[`Box<T>`]: https://rust.docs.kernel.org/kernel/alloc/kbox/struct.Box.html"258)]259#![cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")]260#![cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")]261//! [`impl PinInit<Foo>`]: crate::PinInit262//! [`impl PinInit<T, E>`]: crate::PinInit263//! [`impl Init<T, E>`]: crate::Init264//! [Rust-for-Linux]: https://rust-for-linux.com/265266#![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))]267#![cfg_attr(268all(269any(feature = "alloc", feature = "std"),270not(RUSTC_NEW_UNINIT_IS_STABLE)271),272feature(new_uninit)273)]274#![forbid(missing_docs, unsafe_op_in_unsafe_fn)]275#![cfg_attr(not(feature = "std"), no_std)]276#![cfg_attr(feature = "alloc", feature(allocator_api))]277#![cfg_attr(278all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED),279feature(unsafe_pinned)280)]281282use core::{283cell::UnsafeCell,284convert::Infallible,285marker::PhantomData,286mem::MaybeUninit,287num::*,288pin::Pin,289ptr::{self, NonNull},290};291292#[doc(hidden)]293pub mod __internal;294#[doc(hidden)]295pub mod macros;296297#[cfg(any(feature = "std", feature = "alloc"))]298mod alloc;299#[cfg(any(feature = "std", feature = "alloc"))]300pub use alloc::InPlaceInit;301302/// Used to specify the pinning information of the fields of a struct.303///304/// This is somewhat similar in purpose as305/// [pin-project-lite](https://crates.io/crates/pin-project-lite).306/// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each307/// field you want to structurally pin.308///309/// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,310/// then `#[pin]` directs the type of initializer that is required.311///312/// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this313/// macro, and change your `Drop` implementation to `PinnedDrop` annotated with314/// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care.315///316/// # Examples317///318/// ```319/// # #![feature(allocator_api)]320/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;321/// use pin_init::pin_data;322///323/// enum Command {324/// /* ... */325/// }326///327/// #[pin_data]328/// struct DriverData {329/// #[pin]330/// queue: CMutex<Vec<Command>>,331/// buf: Box<[u8; 1024 * 1024]>,332/// }333/// ```334///335/// ```336/// # #![feature(allocator_api)]337/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;338/// # mod bindings { pub struct info; pub unsafe fn destroy_info(_: *mut info) {} }339/// use core::pin::Pin;340/// use pin_init::{pin_data, pinned_drop, PinnedDrop};341///342/// enum Command {343/// /* ... */344/// }345///346/// #[pin_data(PinnedDrop)]347/// struct DriverData {348/// #[pin]349/// queue: CMutex<Vec<Command>>,350/// buf: Box<[u8; 1024 * 1024]>,351/// raw_info: *mut bindings::info,352/// }353///354/// #[pinned_drop]355/// impl PinnedDrop for DriverData {356/// fn drop(self: Pin<&mut Self>) {357/// unsafe { bindings::destroy_info(self.raw_info) };358/// }359/// }360/// ```361pub use ::pin_init_internal::pin_data;362363/// Used to implement `PinnedDrop` safely.364///365/// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`.366///367/// # Examples368///369/// ```370/// # #![feature(allocator_api)]371/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;372/// # mod bindings { pub struct info; pub unsafe fn destroy_info(_: *mut info) {} }373/// use core::pin::Pin;374/// use pin_init::{pin_data, pinned_drop, PinnedDrop};375///376/// enum Command {377/// /* ... */378/// }379///380/// #[pin_data(PinnedDrop)]381/// struct DriverData {382/// #[pin]383/// queue: CMutex<Vec<Command>>,384/// buf: Box<[u8; 1024 * 1024]>,385/// raw_info: *mut bindings::info,386/// }387///388/// #[pinned_drop]389/// impl PinnedDrop for DriverData {390/// fn drop(self: Pin<&mut Self>) {391/// unsafe { bindings::destroy_info(self.raw_info) };392/// }393/// }394/// ```395pub use ::pin_init_internal::pinned_drop;396397/// Derives the [`Zeroable`] trait for the given `struct` or `union`.398///399/// This can only be used for `struct`s/`union`s where every field implements the [`Zeroable`]400/// trait.401///402/// # Examples403///404/// ```405/// use pin_init::Zeroable;406///407/// #[derive(Zeroable)]408/// pub struct DriverData {409/// pub(crate) id: i64,410/// buf_ptr: *mut u8,411/// len: usize,412/// }413/// ```414///415/// ```416/// use pin_init::Zeroable;417///418/// #[derive(Zeroable)]419/// pub union SignCast {420/// signed: i64,421/// unsigned: u64,422/// }423/// ```424pub use ::pin_init_internal::Zeroable;425426/// Derives the [`Zeroable`] trait for the given `struct` or `union` if all fields implement427/// [`Zeroable`].428///429/// Contrary to the derive macro named [`macro@Zeroable`], this one silently fails when a field430/// doesn't implement [`Zeroable`].431///432/// # Examples433///434/// ```435/// use pin_init::MaybeZeroable;436///437/// // implmements `Zeroable`438/// #[derive(MaybeZeroable)]439/// pub struct DriverData {440/// pub(crate) id: i64,441/// buf_ptr: *mut u8,442/// len: usize,443/// }444///445/// // does not implmement `Zeroable`446/// #[derive(MaybeZeroable)]447/// pub struct DriverData2 {448/// pub(crate) id: i64,449/// buf_ptr: *mut u8,450/// len: usize,451/// // this field doesn't implement `Zeroable`452/// other_data: &'static i32,453/// }454/// ```455pub use ::pin_init_internal::MaybeZeroable;456457/// Initialize and pin a type directly on the stack.458///459/// # Examples460///461/// ```rust462/// # #![expect(clippy::disallowed_names)]463/// # #![feature(allocator_api)]464/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;465/// # use pin_init::*;466/// # use core::pin::Pin;467/// #[pin_data]468/// struct Foo {469/// #[pin]470/// a: CMutex<usize>,471/// b: Bar,472/// }473///474/// #[pin_data]475/// struct Bar {476/// x: u32,477/// }478///479/// stack_pin_init!(let foo = pin_init!(Foo {480/// a <- CMutex::new(42),481/// b: Bar {482/// x: 64,483/// },484/// }));485/// let foo: Pin<&mut Foo> = foo;486/// println!("a: {}", &*foo.a.lock());487/// ```488///489/// # Syntax490///491/// A normal `let` binding with optional type annotation. The expression is expected to implement492/// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error493/// type, then use [`stack_try_pin_init!`].494#[macro_export]495macro_rules! stack_pin_init {496(let $var:ident $(: $t:ty)? = $val:expr) => {497let val = $val;498let mut $var = ::core::pin::pin!($crate::__internal::StackInit$(::<$t>)?::uninit());499let mut $var = match $crate::__internal::StackInit::init($var, val) {500Ok(res) => res,501Err(x) => {502let x: ::core::convert::Infallible = x;503match x {}504}505};506};507}508509/// Initialize and pin a type directly on the stack.510///511/// # Examples512///513/// ```rust514/// # #![expect(clippy::disallowed_names)]515/// # #![feature(allocator_api)]516/// # #[path = "../examples/error.rs"] mod error; use error::Error;517/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;518/// # use pin_init::*;519/// #[pin_data]520/// struct Foo {521/// #[pin]522/// a: CMutex<usize>,523/// b: Box<Bar>,524/// }525///526/// struct Bar {527/// x: u32,528/// }529///530/// stack_try_pin_init!(let foo: Foo = try_pin_init!(Foo {531/// a <- CMutex::new(42),532/// b: Box::try_new(Bar {533/// x: 64,534/// })?,535/// }? Error));536/// let foo = foo.unwrap();537/// println!("a: {}", &*foo.a.lock());538/// ```539///540/// ```rust541/// # #![expect(clippy::disallowed_names)]542/// # #![feature(allocator_api)]543/// # #[path = "../examples/error.rs"] mod error; use error::Error;544/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;545/// # use pin_init::*;546/// #[pin_data]547/// struct Foo {548/// #[pin]549/// a: CMutex<usize>,550/// b: Box<Bar>,551/// }552///553/// struct Bar {554/// x: u32,555/// }556///557/// stack_try_pin_init!(let foo: Foo =? try_pin_init!(Foo {558/// a <- CMutex::new(42),559/// b: Box::try_new(Bar {560/// x: 64,561/// })?,562/// }? Error));563/// println!("a: {}", &*foo.a.lock());564/// # Ok::<_, Error>(())565/// ```566///567/// # Syntax568///569/// A normal `let` binding with optional type annotation. The expression is expected to implement570/// [`PinInit`]/[`Init`]. This macro assigns a result to the given variable, adding a `?` after the571/// `=` will propagate this error.572#[macro_export]573macro_rules! stack_try_pin_init {574(let $var:ident $(: $t:ty)? = $val:expr) => {575let val = $val;576let mut $var = ::core::pin::pin!($crate::__internal::StackInit$(::<$t>)?::uninit());577let mut $var = $crate::__internal::StackInit::init($var, val);578};579(let $var:ident $(: $t:ty)? =? $val:expr) => {580let val = $val;581let mut $var = ::core::pin::pin!($crate::__internal::StackInit$(::<$t>)?::uninit());582let mut $var = $crate::__internal::StackInit::init($var, val)?;583};584}585586/// Construct an in-place, pinned initializer for `struct`s.587///588/// This macro defaults the error to [`Infallible`]. If you need a different error, then use589/// [`try_pin_init!`].590///591/// The syntax is almost identical to that of a normal `struct` initializer:592///593/// ```rust594/// # use pin_init::*;595/// # use core::pin::Pin;596/// #[pin_data]597/// struct Foo {598/// a: usize,599/// b: Bar,600/// }601///602/// #[pin_data]603/// struct Bar {604/// x: u32,605/// }606///607/// # fn demo() -> impl PinInit<Foo> {608/// let a = 42;609///610/// let initializer = pin_init!(Foo {611/// a,612/// b: Bar {613/// x: 64,614/// },615/// });616/// # initializer }617/// # Box::pin_init(demo()).unwrap();618/// ```619///620/// Arbitrary Rust expressions can be used to set the value of a variable.621///622/// The fields are initialized in the order that they appear in the initializer. So it is possible623/// to read already initialized fields using raw pointers.624///625/// IMPORTANT: You are not allowed to create references to fields of the struct inside of the626/// initializer.627///628/// # Init-functions629///630/// When working with this library it is often desired to let others construct your types without631/// giving access to all fields. This is where you would normally write a plain function `new` that632/// would return a new instance of your type. With this library that is also possible. However,633/// there are a few extra things to keep in mind.634///635/// To create an initializer function, simply declare it like this:636///637/// ```rust638/// # use pin_init::*;639/// # use core::pin::Pin;640/// # #[pin_data]641/// # struct Foo {642/// # a: usize,643/// # b: Bar,644/// # }645/// # #[pin_data]646/// # struct Bar {647/// # x: u32,648/// # }649/// impl Foo {650/// fn new() -> impl PinInit<Self> {651/// pin_init!(Self {652/// a: 42,653/// b: Bar {654/// x: 64,655/// },656/// })657/// }658/// }659/// ```660///661/// Users of `Foo` can now create it like this:662///663/// ```rust664/// # #![expect(clippy::disallowed_names)]665/// # use pin_init::*;666/// # use core::pin::Pin;667/// # #[pin_data]668/// # struct Foo {669/// # a: usize,670/// # b: Bar,671/// # }672/// # #[pin_data]673/// # struct Bar {674/// # x: u32,675/// # }676/// # impl Foo {677/// # fn new() -> impl PinInit<Self> {678/// # pin_init!(Self {679/// # a: 42,680/// # b: Bar {681/// # x: 64,682/// # },683/// # })684/// # }685/// # }686/// let foo = Box::pin_init(Foo::new());687/// ```688///689/// They can also easily embed it into their own `struct`s:690///691/// ```rust692/// # use pin_init::*;693/// # use core::pin::Pin;694/// # #[pin_data]695/// # struct Foo {696/// # a: usize,697/// # b: Bar,698/// # }699/// # #[pin_data]700/// # struct Bar {701/// # x: u32,702/// # }703/// # impl Foo {704/// # fn new() -> impl PinInit<Self> {705/// # pin_init!(Self {706/// # a: 42,707/// # b: Bar {708/// # x: 64,709/// # },710/// # })711/// # }712/// # }713/// #[pin_data]714/// struct FooContainer {715/// #[pin]716/// foo1: Foo,717/// #[pin]718/// foo2: Foo,719/// other: u32,720/// }721///722/// impl FooContainer {723/// fn new(other: u32) -> impl PinInit<Self> {724/// pin_init!(Self {725/// foo1 <- Foo::new(),726/// foo2 <- Foo::new(),727/// other,728/// })729/// }730/// }731/// ```732///733/// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`.734/// This signifies that the given field is initialized in-place. As with `struct` initializers, just735/// writing the field (in this case `other`) without `:` or `<-` means `other: other,`.736///737/// # Syntax738///739/// As already mentioned in the examples above, inside of `pin_init!` a `struct` initializer with740/// the following modifications is expected:741/// - Fields that you want to initialize in-place have to use `<-` instead of `:`.742/// - You can use `_: { /* run any user-code here */ },` anywhere where you can place fields in743/// order to run arbitrary code.744/// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]745/// pointer named `this` inside of the initializer.746/// - Using struct update syntax one can place `..Zeroable::init_zeroed()` at the very end of the747/// struct, this initializes every field with 0 and then runs all initializers specified in the748/// body. This can only be done if [`Zeroable`] is implemented for the struct.749///750/// For instance:751///752/// ```rust753/// # use pin_init::*;754/// # use core::{ptr::addr_of_mut, marker::PhantomPinned};755/// #[pin_data]756/// #[derive(Zeroable)]757/// struct Buf {758/// // `ptr` points into `buf`.759/// ptr: *mut u8,760/// buf: [u8; 64],761/// #[pin]762/// pin: PhantomPinned,763/// }764///765/// let init = pin_init!(&this in Buf {766/// buf: [0; 64],767/// // SAFETY: TODO.768/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },769/// pin: PhantomPinned,770/// });771/// let init = pin_init!(Buf {772/// buf: [1; 64],773/// ..Zeroable::init_zeroed()774/// });775/// ```776///777/// [`NonNull<Self>`]: core::ptr::NonNull778// For a detailed example of how this macro works, see the module documentation of the hidden779// module `macros` inside of `macros.rs`.780#[macro_export]781macro_rules! pin_init {782($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {783$($fields:tt)*784}) => {785$crate::try_pin_init!($(&$this in)? $t $(::<$($generics),*>)? {786$($fields)*787}? ::core::convert::Infallible)788};789}790791/// Construct an in-place, fallible pinned initializer for `struct`s.792///793/// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].794///795/// You can use the `?` operator or use `return Err(err)` inside the initializer to stop796/// initialization and return the error.797///798/// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when799/// initialization fails, the memory can be safely deallocated without any further modifications.800///801/// The syntax is identical to [`pin_init!`] with the following exception: you must append `? $type`802/// after the `struct` initializer to specify the error type you want to use.803///804/// # Examples805///806/// ```rust807/// # #![feature(allocator_api)]808/// # #[path = "../examples/error.rs"] mod error; use error::Error;809/// use pin_init::{pin_data, try_pin_init, PinInit, InPlaceInit, init_zeroed};810///811/// #[pin_data]812/// struct BigBuf {813/// big: Box<[u8; 1024 * 1024 * 1024]>,814/// small: [u8; 1024 * 1024],815/// ptr: *mut u8,816/// }817///818/// impl BigBuf {819/// fn new() -> impl PinInit<Self, Error> {820/// try_pin_init!(Self {821/// big: Box::init(init_zeroed())?,822/// small: [0; 1024 * 1024],823/// ptr: core::ptr::null_mut(),824/// }? Error)825/// }826/// }827/// # let _ = Box::pin_init(BigBuf::new());828/// ```829// For a detailed example of how this macro works, see the module documentation of the hidden830// module `macros` inside of `macros.rs`.831#[macro_export]832macro_rules! try_pin_init {833($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {834$($fields:tt)*835}? $err:ty) => {836$crate::__init_internal!(837@this($($this)?),838@typ($t $(::<$($generics),*>)? ),839@fields($($fields)*),840@error($err),841@data(PinData, use_data),842@has_data(HasPinData, __pin_data),843@construct_closure(pin_init_from_closure),844@munch_fields($($fields)*),845)846}847}848849/// Construct an in-place initializer for `struct`s.850///851/// This macro defaults the error to [`Infallible`]. If you need a different error, then use852/// [`try_init!`].853///854/// The syntax is identical to [`pin_init!`] and its safety caveats also apply:855/// - `unsafe` code must guarantee either full initialization or return an error and allow856/// deallocation of the memory.857/// - the fields are initialized in the order given in the initializer.858/// - no references to fields are allowed to be created inside of the initializer.859///860/// This initializer is for initializing data in-place that might later be moved. If you want to861/// pin-initialize, use [`pin_init!`].862///863/// # Examples864///865/// ```rust866/// # #![feature(allocator_api)]867/// # #[path = "../examples/error.rs"] mod error; use error::Error;868/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;869/// # use pin_init::InPlaceInit;870/// use pin_init::{init, Init, init_zeroed};871///872/// struct BigBuf {873/// small: [u8; 1024 * 1024],874/// }875///876/// impl BigBuf {877/// fn new() -> impl Init<Self> {878/// init!(Self {879/// small <- init_zeroed(),880/// })881/// }882/// }883/// # let _ = Box::init(BigBuf::new());884/// ```885// For a detailed example of how this macro works, see the module documentation of the hidden886// module `macros` inside of `macros.rs`.887#[macro_export]888macro_rules! init {889($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {890$($fields:tt)*891}) => {892$crate::try_init!($(&$this in)? $t $(::<$($generics),*>)? {893$($fields)*894}? ::core::convert::Infallible)895}896}897898/// Construct an in-place fallible initializer for `struct`s.899///900/// If the initialization can complete without error (or [`Infallible`]), then use901/// [`init!`].902///903/// The syntax is identical to [`try_pin_init!`]. You need to specify a custom error904/// via `? $type` after the `struct` initializer.905/// The safety caveats from [`try_pin_init!`] also apply:906/// - `unsafe` code must guarantee either full initialization or return an error and allow907/// deallocation of the memory.908/// - the fields are initialized in the order given in the initializer.909/// - no references to fields are allowed to be created inside of the initializer.910///911/// # Examples912///913/// ```rust914/// # #![feature(allocator_api)]915/// # use core::alloc::AllocError;916/// # use pin_init::InPlaceInit;917/// use pin_init::{try_init, Init, init_zeroed};918///919/// struct BigBuf {920/// big: Box<[u8; 1024 * 1024 * 1024]>,921/// small: [u8; 1024 * 1024],922/// }923///924/// impl BigBuf {925/// fn new() -> impl Init<Self, AllocError> {926/// try_init!(Self {927/// big: Box::init(init_zeroed())?,928/// small: [0; 1024 * 1024],929/// }? AllocError)930/// }931/// }932/// # let _ = Box::init(BigBuf::new());933/// ```934// For a detailed example of how this macro works, see the module documentation of the hidden935// module `macros` inside of `macros.rs`.936#[macro_export]937macro_rules! try_init {938($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {939$($fields:tt)*940}? $err:ty) => {941$crate::__init_internal!(942@this($($this)?),943@typ($t $(::<$($generics),*>)?),944@fields($($fields)*),945@error($err),946@data(InitData, /*no use_data*/),947@has_data(HasInitData, __init_data),948@construct_closure(init_from_closure),949@munch_fields($($fields)*),950)951}952}953954/// Asserts that a field on a struct using `#[pin_data]` is marked with `#[pin]` ie. that it is955/// structurally pinned.956///957/// # Examples958///959/// This will succeed:960/// ```961/// use pin_init::{pin_data, assert_pinned};962///963/// #[pin_data]964/// struct MyStruct {965/// #[pin]966/// some_field: u64,967/// }968///969/// assert_pinned!(MyStruct, some_field, u64);970/// ```971///972/// This will fail:973/// ```compile_fail974/// use pin_init::{pin_data, assert_pinned};975///976/// #[pin_data]977/// struct MyStruct {978/// some_field: u64,979/// }980///981/// assert_pinned!(MyStruct, some_field, u64);982/// ```983///984/// Some uses of the macro may trigger the `can't use generic parameters from outer item` error. To985/// work around this, you may pass the `inline` parameter to the macro. The `inline` parameter can986/// only be used when the macro is invoked from a function body.987/// ```988/// # use core::pin::Pin;989/// use pin_init::{pin_data, assert_pinned};990///991/// #[pin_data]992/// struct Foo<T> {993/// #[pin]994/// elem: T,995/// }996///997/// impl<T> Foo<T> {998/// fn project_this(self: Pin<&mut Self>) -> Pin<&mut T> {999/// assert_pinned!(Foo<T>, elem, T, inline);1000///1001/// // SAFETY: The field is structurally pinned.1002/// unsafe { self.map_unchecked_mut(|me| &mut me.elem) }1003/// }1004/// }1005/// ```1006#[macro_export]1007macro_rules! assert_pinned {1008($ty:ty, $field:ident, $field_ty:ty, inline) => {1009let _ = move |ptr: *mut $field_ty| {1010// SAFETY: This code is unreachable.1011let data = unsafe { <$ty as $crate::__internal::HasPinData>::__pin_data() };1012let init = $crate::__internal::AlwaysFail::<$field_ty>::new();1013// SAFETY: This code is unreachable.1014unsafe { data.$field(ptr, init) }.ok();1015};1016};10171018($ty:ty, $field:ident, $field_ty:ty) => {1019const _: () = {1020$crate::assert_pinned!($ty, $field, $field_ty, inline);1021};1022};1023}10241025/// A pin-initializer for the type `T`.1026///1027/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can1028/// be [`Box<T>`], [`Arc<T>`] or even the stack (see [`stack_pin_init!`]).1029///1030/// Also see the [module description](self).1031///1032/// # Safety1033///1034/// When implementing this trait you will need to take great care. Also there are probably very few1035/// cases where a manual implementation is necessary. Use [`pin_init_from_closure`] where possible.1036///1037/// The [`PinInit::__pinned_init`] function:1038/// - returns `Ok(())` if it initialized every field of `slot`,1039/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:1040/// - `slot` can be deallocated without UB occurring,1041/// - `slot` does not need to be dropped,1042/// - `slot` is not partially initialized.1043/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.1044///1045#[cfg_attr(1046kernel,1047doc = "[`Arc<T>`]: https://rust.docs.kernel.org/kernel/sync/struct.Arc.html"1048)]1049#[cfg_attr(1050kernel,1051doc = "[`Box<T>`]: https://rust.docs.kernel.org/kernel/alloc/kbox/struct.Box.html"1052)]1053#[cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")]1054#[cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")]1055#[must_use = "An initializer must be used in order to create its value."]1056pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {1057/// Initializes `slot`.1058///1059/// # Safety1060///1061/// - `slot` is a valid pointer to uninitialized memory.1062/// - the caller does not touch `slot` when `Err` is returned, they are only permitted to1063/// deallocate.1064/// - `slot` will not move until it is dropped, i.e. it will be pinned.1065unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>;10661067/// First initializes the value using `self` then calls the function `f` with the initialized1068/// value.1069///1070/// If `f` returns an error the value is dropped and the initializer will forward the error.1071///1072/// # Examples1073///1074/// ```rust1075/// # #![feature(allocator_api)]1076/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;1077/// # use pin_init::*;1078/// let mtx_init = CMutex::new(42);1079/// // Make the initializer print the value.1080/// let mtx_init = mtx_init.pin_chain(|mtx| {1081/// println!("{:?}", mtx.get_data_mut());1082/// Ok(())1083/// });1084/// ```1085fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>1086where1087F: FnOnce(Pin<&mut T>) -> Result<(), E>,1088{1089ChainPinInit(self, f, PhantomData)1090}1091}10921093/// An initializer returned by [`PinInit::pin_chain`].1094pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);10951096// SAFETY: The `__pinned_init` function is implemented such that it1097// - returns `Ok(())` on successful initialization,1098// - returns `Err(err)` on error and in this case `slot` will be dropped.1099// - considers `slot` pinned.1100unsafe impl<T: ?Sized, E, I, F> PinInit<T, E> for ChainPinInit<I, F, T, E>1101where1102I: PinInit<T, E>,1103F: FnOnce(Pin<&mut T>) -> Result<(), E>,1104{1105unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {1106// SAFETY: All requirements fulfilled since this function is `__pinned_init`.1107unsafe { self.0.__pinned_init(slot)? };1108// SAFETY: The above call initialized `slot` and we still have unique access.1109let val = unsafe { &mut *slot };1110// SAFETY: `slot` is considered pinned.1111let val = unsafe { Pin::new_unchecked(val) };1112// SAFETY: `slot` was initialized above.1113(self.1)(val).inspect_err(|_| unsafe { core::ptr::drop_in_place(slot) })1114}1115}11161117/// An initializer for `T`.1118///1119/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can1120/// be [`Box<T>`], [`Arc<T>`] or even the stack (see [`stack_pin_init!`]). Because1121/// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well.1122///1123/// Also see the [module description](self).1124///1125/// # Safety1126///1127/// When implementing this trait you will need to take great care. Also there are probably very few1128/// cases where a manual implementation is necessary. Use [`init_from_closure`] where possible.1129///1130/// The [`Init::__init`] function:1131/// - returns `Ok(())` if it initialized every field of `slot`,1132/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:1133/// - `slot` can be deallocated without UB occurring,1134/// - `slot` does not need to be dropped,1135/// - `slot` is not partially initialized.1136/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.1137///1138/// The `__pinned_init` function from the supertrait [`PinInit`] needs to execute the exact same1139/// code as `__init`.1140///1141/// Contrary to its supertype [`PinInit<T, E>`] the caller is allowed to1142/// move the pointee after initialization.1143///1144#[cfg_attr(1145kernel,1146doc = "[`Arc<T>`]: https://rust.docs.kernel.org/kernel/sync/struct.Arc.html"1147)]1148#[cfg_attr(1149kernel,1150doc = "[`Box<T>`]: https://rust.docs.kernel.org/kernel/alloc/kbox/struct.Box.html"1151)]1152#[cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")]1153#[cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")]1154#[must_use = "An initializer must be used in order to create its value."]1155pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {1156/// Initializes `slot`.1157///1158/// # Safety1159///1160/// - `slot` is a valid pointer to uninitialized memory.1161/// - the caller does not touch `slot` when `Err` is returned, they are only permitted to1162/// deallocate.1163unsafe fn __init(self, slot: *mut T) -> Result<(), E>;11641165/// First initializes the value using `self` then calls the function `f` with the initialized1166/// value.1167///1168/// If `f` returns an error the value is dropped and the initializer will forward the error.1169///1170/// # Examples1171///1172/// ```rust1173/// # #![expect(clippy::disallowed_names)]1174/// use pin_init::{init, init_zeroed, Init};1175///1176/// struct Foo {1177/// buf: [u8; 1_000_000],1178/// }1179///1180/// impl Foo {1181/// fn setup(&mut self) {1182/// println!("Setting up foo");1183/// }1184/// }1185///1186/// let foo = init!(Foo {1187/// buf <- init_zeroed()1188/// }).chain(|foo| {1189/// foo.setup();1190/// Ok(())1191/// });1192/// ```1193fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>1194where1195F: FnOnce(&mut T) -> Result<(), E>,1196{1197ChainInit(self, f, PhantomData)1198}1199}12001201/// An initializer returned by [`Init::chain`].1202pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);12031204// SAFETY: The `__init` function is implemented such that it1205// - returns `Ok(())` on successful initialization,1206// - returns `Err(err)` on error and in this case `slot` will be dropped.1207unsafe impl<T: ?Sized, E, I, F> Init<T, E> for ChainInit<I, F, T, E>1208where1209I: Init<T, E>,1210F: FnOnce(&mut T) -> Result<(), E>,1211{1212unsafe fn __init(self, slot: *mut T) -> Result<(), E> {1213// SAFETY: All requirements fulfilled since this function is `__init`.1214unsafe { self.0.__pinned_init(slot)? };1215// SAFETY: The above call initialized `slot` and we still have unique access.1216(self.1)(unsafe { &mut *slot }).inspect_err(|_|1217// SAFETY: `slot` was initialized above.1218unsafe { core::ptr::drop_in_place(slot) })1219}1220}12211222// SAFETY: `__pinned_init` behaves exactly the same as `__init`.1223unsafe impl<T: ?Sized, E, I, F> PinInit<T, E> for ChainInit<I, F, T, E>1224where1225I: Init<T, E>,1226F: FnOnce(&mut T) -> Result<(), E>,1227{1228unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {1229// SAFETY: `__init` has less strict requirements compared to `__pinned_init`.1230unsafe { self.__init(slot) }1231}1232}12331234/// Creates a new [`PinInit<T, E>`] from the given closure.1235///1236/// # Safety1237///1238/// The closure:1239/// - returns `Ok(())` if it initialized every field of `slot`,1240/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:1241/// - `slot` can be deallocated without UB occurring,1242/// - `slot` does not need to be dropped,1243/// - `slot` is not partially initialized.1244/// - may assume that the `slot` does not move if `T: !Unpin`,1245/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.1246#[inline]1247pub const unsafe fn pin_init_from_closure<T: ?Sized, E>(1248f: impl FnOnce(*mut T) -> Result<(), E>,1249) -> impl PinInit<T, E> {1250__internal::InitClosure(f, PhantomData)1251}12521253/// Creates a new [`Init<T, E>`] from the given closure.1254///1255/// # Safety1256///1257/// The closure:1258/// - returns `Ok(())` if it initialized every field of `slot`,1259/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:1260/// - `slot` can be deallocated without UB occurring,1261/// - `slot` does not need to be dropped,1262/// - `slot` is not partially initialized.1263/// - the `slot` may move after initialization.1264/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.1265#[inline]1266pub const unsafe fn init_from_closure<T: ?Sized, E>(1267f: impl FnOnce(*mut T) -> Result<(), E>,1268) -> impl Init<T, E> {1269__internal::InitClosure(f, PhantomData)1270}12711272/// Changes the to be initialized type.1273///1274/// # Safety1275///1276/// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a1277/// pointer must result in a valid `U`.1278#[expect(clippy::let_and_return)]1279pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> {1280// SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety1281// requirements.1282let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::<T>())) };1283// FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a1284// cycle when computing the type returned by this function)1285res1286}12871288/// Changes the to be initialized type.1289///1290/// # Safety1291///1292/// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a1293/// pointer must result in a valid `U`.1294#[expect(clippy::let_and_return)]1295pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {1296// SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety1297// requirements.1298let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::<T>())) };1299// FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a1300// cycle when computing the type returned by this function)1301res1302}13031304/// An initializer that leaves the memory uninitialized.1305///1306/// The initializer is a no-op. The `slot` memory is not changed.1307#[inline]1308pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> {1309// SAFETY: The memory is allowed to be uninitialized.1310unsafe { init_from_closure(|_| Ok(())) }1311}13121313/// Initializes an array by initializing each element via the provided initializer.1314///1315/// # Examples1316///1317/// ```rust1318/// # use pin_init::*;1319/// use pin_init::init_array_from_fn;1320/// let array: Box<[usize; 1_000]> = Box::init(init_array_from_fn(|i| i)).unwrap();1321/// assert_eq!(array.len(), 1_000);1322/// ```1323pub fn init_array_from_fn<I, const N: usize, T, E>(1324mut make_init: impl FnMut(usize) -> I,1325) -> impl Init<[T; N], E>1326where1327I: Init<T, E>,1328{1329let init = move |slot: *mut [T; N]| {1330let slot = slot.cast::<T>();1331for i in 0..N {1332let init = make_init(i);1333// SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.1334let ptr = unsafe { slot.add(i) };1335// SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`1336// requirements.1337if let Err(e) = unsafe { init.__init(ptr) } {1338// SAFETY: The loop has initialized the elements `slot[0..i]` and since we return1339// `Err` below, `slot` will be considered uninitialized memory.1340unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };1341return Err(e);1342}1343}1344Ok(())1345};1346// SAFETY: The initializer above initializes every element of the array. On failure it drops1347// any initialized elements and returns `Err`.1348unsafe { init_from_closure(init) }1349}13501351/// Initializes an array by initializing each element via the provided initializer.1352///1353/// # Examples1354///1355/// ```rust1356/// # #![feature(allocator_api)]1357/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;1358/// # use pin_init::*;1359/// # use core::pin::Pin;1360/// use pin_init::pin_init_array_from_fn;1361/// use std::sync::Arc;1362/// let array: Pin<Arc<[CMutex<usize>; 1_000]>> =1363/// Arc::pin_init(pin_init_array_from_fn(|i| CMutex::new(i))).unwrap();1364/// assert_eq!(array.len(), 1_000);1365/// ```1366pub fn pin_init_array_from_fn<I, const N: usize, T, E>(1367mut make_init: impl FnMut(usize) -> I,1368) -> impl PinInit<[T; N], E>1369where1370I: PinInit<T, E>,1371{1372let init = move |slot: *mut [T; N]| {1373let slot = slot.cast::<T>();1374for i in 0..N {1375let init = make_init(i);1376// SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.1377let ptr = unsafe { slot.add(i) };1378// SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`1379// requirements.1380if let Err(e) = unsafe { init.__pinned_init(ptr) } {1381// SAFETY: The loop has initialized the elements `slot[0..i]` and since we return1382// `Err` below, `slot` will be considered uninitialized memory.1383unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };1384return Err(e);1385}1386}1387Ok(())1388};1389// SAFETY: The initializer above initializes every element of the array. On failure it drops1390// any initialized elements and returns `Err`.1391unsafe { pin_init_from_closure(init) }1392}13931394// SAFETY: the `__init` function always returns `Ok(())` and initializes every field of `slot`.1395unsafe impl<T> Init<T> for T {1396unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible> {1397// SAFETY: `slot` is valid for writes by the safety requirements of this function.1398unsafe { slot.write(self) };1399Ok(())1400}1401}14021403// SAFETY: the `__pinned_init` function always returns `Ok(())` and initializes every field of1404// `slot`. Additionally, all pinning invariants of `T` are upheld.1405unsafe impl<T> PinInit<T> for T {1406unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible> {1407// SAFETY: `slot` is valid for writes by the safety requirements of this function.1408unsafe { slot.write(self) };1409Ok(())1410}1411}14121413// SAFETY: when the `__init` function returns with1414// - `Ok(())`, `slot` was initialized and all pinned invariants of `T` are upheld.1415// - `Err(err)`, slot was not written to.1416unsafe impl<T, E> Init<T, E> for Result<T, E> {1417unsafe fn __init(self, slot: *mut T) -> Result<(), E> {1418// SAFETY: `slot` is valid for writes by the safety requirements of this function.1419unsafe { slot.write(self?) };1420Ok(())1421}1422}14231424// SAFETY: when the `__pinned_init` function returns with1425// - `Ok(())`, `slot` was initialized and all pinned invariants of `T` are upheld.1426// - `Err(err)`, slot was not written to.1427unsafe impl<T, E> PinInit<T, E> for Result<T, E> {1428unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {1429// SAFETY: `slot` is valid for writes by the safety requirements of this function.1430unsafe { slot.write(self?) };1431Ok(())1432}1433}14341435/// Smart pointer containing uninitialized memory and that can write a value.1436pub trait InPlaceWrite<T> {1437/// The type `Self` turns into when the contents are initialized.1438type Initialized;14391440/// Use the given initializer to write a value into `self`.1441///1442/// Does not drop the current value and considers it as uninitialized memory.1443fn write_init<E>(self, init: impl Init<T, E>) -> Result<Self::Initialized, E>;14441445/// Use the given pin-initializer to write a value into `self`.1446///1447/// Does not drop the current value and considers it as uninitialized memory.1448fn write_pin_init<E>(self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>;1449}14501451/// Trait facilitating pinned destruction.1452///1453/// Use [`pinned_drop`] to implement this trait safely:1454///1455/// ```rust1456/// # #![feature(allocator_api)]1457/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;1458/// # use pin_init::*;1459/// use core::pin::Pin;1460/// #[pin_data(PinnedDrop)]1461/// struct Foo {1462/// #[pin]1463/// mtx: CMutex<usize>,1464/// }1465///1466/// #[pinned_drop]1467/// impl PinnedDrop for Foo {1468/// fn drop(self: Pin<&mut Self>) {1469/// println!("Foo is being dropped!");1470/// }1471/// }1472/// ```1473///1474/// # Safety1475///1476/// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.1477pub unsafe trait PinnedDrop: __internal::HasPinData {1478/// Executes the pinned destructor of this type.1479///1480/// While this function is marked safe, it is actually unsafe to call it manually. For this1481/// reason it takes an additional parameter. This type can only be constructed by `unsafe` code1482/// and thus prevents this function from being called where it should not.1483///1484/// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute1485/// automatically.1486fn drop(self: Pin<&mut Self>, only_call_from_drop: __internal::OnlyCallFromDrop);1487}14881489/// Marker trait for types that can be initialized by writing just zeroes.1490///1491/// # Safety1492///1493/// The bit pattern consisting of only zeroes is a valid bit pattern for this type. In other words,1494/// this is not UB:1495///1496/// ```rust,ignore1497/// let val: Self = unsafe { core::mem::zeroed() };1498/// ```1499pub unsafe trait Zeroable {1500/// Create a new zeroed `Self`.1501///1502/// The returned initializer will write `0x00` to every byte of the given `slot`.1503#[inline]1504fn init_zeroed() -> impl Init<Self>1505where1506Self: Sized,1507{1508init_zeroed()1509}15101511/// Create a `Self` consisting of all zeroes.1512///1513/// Whenever a type implements [`Zeroable`], this function should be preferred over1514/// [`core::mem::zeroed()`] or using `MaybeUninit<T>::zeroed().assume_init()`.1515///1516/// # Examples1517///1518/// ```1519/// use pin_init::{Zeroable, zeroed};1520///1521/// #[derive(Zeroable)]1522/// struct Point {1523/// x: u32,1524/// y: u32,1525/// }1526///1527/// let point: Point = zeroed();1528/// assert_eq!(point.x, 0);1529/// assert_eq!(point.y, 0);1530/// ```1531fn zeroed() -> Self1532where1533Self: Sized,1534{1535zeroed()1536}1537}15381539/// Marker trait for types that allow `Option<Self>` to be set to all zeroes in order to write1540/// `None` to that location.1541///1542/// # Safety1543///1544/// The implementer needs to ensure that `unsafe impl Zeroable for Option<Self> {}` is sound.1545pub unsafe trait ZeroableOption {}15461547// SAFETY: by the safety requirement of `ZeroableOption`, this is valid.1548unsafe impl<T: ZeroableOption> Zeroable for Option<T> {}15491550// SAFETY: `Option<&T>` is part of the option layout optimization guarantee:1551// <https://doc.rust-lang.org/stable/std/option/index.html#representation>.1552unsafe impl<T> ZeroableOption for &T {}1553// SAFETY: `Option<&mut T>` is part of the option layout optimization guarantee:1554// <https://doc.rust-lang.org/stable/std/option/index.html#representation>.1555unsafe impl<T> ZeroableOption for &mut T {}1556// SAFETY: `Option<NonNull<T>>` is part of the option layout optimization guarantee:1557// <https://doc.rust-lang.org/stable/std/option/index.html#representation>.1558unsafe impl<T> ZeroableOption for NonNull<T> {}15591560/// Create an initializer for a zeroed `T`.1561///1562/// The returned initializer will write `0x00` to every byte of the given `slot`.1563#[inline]1564pub fn init_zeroed<T: Zeroable>() -> impl Init<T> {1565// SAFETY: Because `T: Zeroable`, all bytes zero is a valid bit pattern for `T`1566// and because we write all zeroes, the memory is initialized.1567unsafe {1568init_from_closure(|slot: *mut T| {1569slot.write_bytes(0, 1);1570Ok(())1571})1572}1573}15741575/// Create a `T` consisting of all zeroes.1576///1577/// Whenever a type implements [`Zeroable`], this function should be preferred over1578/// [`core::mem::zeroed()`] or using `MaybeUninit<T>::zeroed().assume_init()`.1579///1580/// # Examples1581///1582/// ```1583/// use pin_init::{Zeroable, zeroed};1584///1585/// #[derive(Zeroable)]1586/// struct Point {1587/// x: u32,1588/// y: u32,1589/// }1590///1591/// let point: Point = zeroed();1592/// assert_eq!(point.x, 0);1593/// assert_eq!(point.y, 0);1594/// ```1595pub const fn zeroed<T: Zeroable>() -> T {1596// SAFETY:By the type invariants of `Zeroable`, all zeroes is a valid bit pattern for `T`.1597unsafe { core::mem::zeroed() }1598}15991600macro_rules! impl_zeroable {1601($($({$($generics:tt)*})? $t:ty, )*) => {1602// SAFETY: Safety comments written in the macro invocation.1603$(unsafe impl$($($generics)*)? Zeroable for $t {})*1604};1605}16061607impl_zeroable! {1608// SAFETY: All primitives that are allowed to be zero.1609bool,1610char,1611u8, u16, u32, u64, u128, usize,1612i8, i16, i32, i64, i128, isize,1613f32, f64,16141615// Note: do not add uninhabited types (such as `!` or `core::convert::Infallible`) to this list;1616// creating an instance of an uninhabited type is immediate undefined behavior. For more on1617// uninhabited/empty types, consult The Rustonomicon:1618// <https://doc.rust-lang.org/stable/nomicon/exotic-sizes.html#empty-types>. The Rust Reference1619// also has information on undefined behavior:1620// <https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html>.1621//1622// SAFETY: These are inhabited ZSTs; there is nothing to zero and a valid value exists.1623{<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, (),16241625// SAFETY: Type is allowed to take any value, including all zeros.1626{<T>} MaybeUninit<T>,16271628// SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.1629{<T: ?Sized + Zeroable>} UnsafeCell<T>,16301631// SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:1632// <https://doc.rust-lang.org/stable/std/option/index.html#representation>).1633Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>,1634Option<NonZeroU128>, Option<NonZeroUsize>,1635Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>,1636Option<NonZeroI128>, Option<NonZeroIsize>,16371638// SAFETY: `null` pointer is valid.1639//1640// We cannot use `T: ?Sized`, since the VTABLE pointer part of fat pointers is not allowed to be1641// null.1642//1643// When `Pointee` gets stabilized, we could use1644// `T: ?Sized where <T as Pointee>::Metadata: Zeroable`1645{<T>} *mut T, {<T>} *const T,16461647// SAFETY: `null` pointer is valid and the metadata part of these fat pointers is allowed to be1648// zero.1649{<T>} *mut [T], {<T>} *const [T], *mut str, *const str,16501651// SAFETY: `T` is `Zeroable`.1652{<const N: usize, T: Zeroable>} [T; N], {<T: Zeroable>} Wrapping<T>,1653}16541655macro_rules! impl_tuple_zeroable {1656($(,)?) => {};1657($first:ident, $($t:ident),* $(,)?) => {1658// SAFETY: All elements are zeroable and padding can be zero.1659unsafe impl<$first: Zeroable, $($t: Zeroable),*> Zeroable for ($first, $($t),*) {}1660impl_tuple_zeroable!($($t),* ,);1661}1662}16631664impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J);16651666macro_rules! impl_fn_zeroable_option {1667([$($abi:literal),* $(,)?] $args:tt) => {1668$(impl_fn_zeroable_option!({extern $abi} $args);)*1669$(impl_fn_zeroable_option!({unsafe extern $abi} $args);)*1670};1671({$($prefix:tt)*} {$(,)?}) => {};1672({$($prefix:tt)*} {$ret:ident, $($rest:ident),* $(,)?}) => {1673// SAFETY: function pointers are part of the option layout optimization:1674// <https://doc.rust-lang.org/stable/std/option/index.html#representation>.1675unsafe impl<$ret, $($rest),*> ZeroableOption for $($prefix)* fn($($rest),*) -> $ret {}1676impl_fn_zeroable_option!({$($prefix)*} {$($rest),*,});1677};1678}16791680impl_fn_zeroable_option!(["Rust", "C"] { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U });16811682/// This trait allows creating an instance of `Self` which contains exactly one1683/// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).1684///1685/// This is useful when using wrapper `struct`s like [`UnsafeCell`] or with new-type `struct`s.1686///1687/// # Examples1688///1689/// ```1690/// # use core::cell::UnsafeCell;1691/// # use pin_init::{pin_data, pin_init, Wrapper};1692///1693/// #[pin_data]1694/// struct Foo {}1695///1696/// #[pin_data]1697/// struct Bar {1698/// #[pin]1699/// content: UnsafeCell<Foo>1700/// };1701///1702/// let foo_initializer = pin_init!(Foo{});1703/// let initializer = pin_init!(Bar {1704/// content <- UnsafeCell::pin_init(foo_initializer)1705/// });1706/// ```1707pub trait Wrapper<T> {1708/// Creates an pin-initializer for a [`Self`] containing `T` from the `value_init` initializer.1709fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E>;1710}17111712impl<T> Wrapper<T> for UnsafeCell<T> {1713fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {1714// SAFETY: `UnsafeCell<T>` has a compatible layout to `T`.1715unsafe { cast_pin_init(value_init) }1716}1717}17181719impl<T> Wrapper<T> for MaybeUninit<T> {1720fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {1721// SAFETY: `MaybeUninit<T>` has a compatible layout to `T`.1722unsafe { cast_pin_init(value_init) }1723}1724}17251726#[cfg(all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED))]1727impl<T> Wrapper<T> for core::pin::UnsafePinned<T> {1728fn pin_init<E>(init: impl PinInit<T, E>) -> impl PinInit<Self, E> {1729// SAFETY: `UnsafePinned<T>` has a compatible layout to `T`.1730unsafe { cast_pin_init(init) }1731}1732}173317341735