// SPDX-License-Identifier: Apache-2.0 OR MIT //! Library to safely and fallibly initialize pinned `struct`s using in-place constructors.//!//! [Pinning][pinning] is Rust's way of ensuring data does not move.//!//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack//! overflow.//!//! This library's main use-case is in [Rust-for-Linux]. Although this version can be used//! standalone.//!//! There are cases when you want to in-place initialize a struct. For example when it is very big//! and moving it from the stack is not an option, because it is bigger than the stack itself.//! Another reason would be that you need the address of the object to initialize it. This stands//! in direct conflict with Rust's normal process of first initializing an object and then moving//! it into it's final memory location. For more information, see//! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>.//!//! This library allows you to do in-place initialization safely.//!//! ## Nightly Needed for `alloc` feature//!//! This library requires the [`allocator_api` unstable feature] when the `alloc` feature is//! enabled and thus this feature can only be used with a nightly compiler. When enabling the//! `alloc` feature, the user will be required to activate `allocator_api` as well.//!//! [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html//!//! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler.//! However, using the crate on stable compilers is possible by disabling `alloc`. In practice this//! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std//! mode.//!//! ## Nightly needed for `unsafe-pinned` feature//!//! This feature enables the `Wrapper` implementation on the unstable `core::pin::UnsafePinned` type.//! This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735)//! and therefore a nightly compiler. Note that this feature is not enabled by default.//!//! # Overview//!//! To initialize a `struct` with an in-place constructor you will need two things://! - an in-place constructor,//! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],//! [`Box<T>`] or any other smart pointer that supports this library).//!//! To get an in-place constructor there are generally three options://! - directly creating an in-place constructor using the [`pin_init!`] macro,//! - a custom function/macro returning an in-place constructor provided by someone else,//! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.//!//! Aside from pinned initialization, this library also supports in-place construction without//! pinning, the macros/types/functions are generally named like the pinned variants without the//! `pin_` prefix.//!//! # Examples//!//! Throughout the examples we will often make use of the `CMutex` type which can be found in//! `../examples/mutex.rs`. It is essentially a userland rebuild of the `struct mutex` type from//! the Linux kernel. It also uses a wait list and a basic spinlock. Importantly the wait list//! requires it to be pinned to be locked and thus is a prime candidate for using this library.//!//! ## Using the [`pin_init!`] macro//!//! If you want to use [`PinInit`], then you will have to annotate your `struct` with//! `#[`[`pin_data`]`]`. It is a macro that uses `#[pin]` as a marker for//! [structurally pinned fields]. After doing this, you can then create an in-place constructor via//! [`pin_init!`]. The syntax is almost the same as normal `struct` initializers. The difference is//! that you need to write `<-` instead of `:` for fields that you want to initialize in-place.//!//! ```rust//! # #![expect(clippy::disallowed_names)]//! # #![feature(allocator_api)]//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;//! # use core::pin::Pin;//! use pin_init::{pin_data, pin_init, InPlaceInit};//!//! #[pin_data]//! struct Foo {//! #[pin]//! a: CMutex<usize>,//! b: u32,//! }//!//! let foo = pin_init!(Foo {//! a <- CMutex::new(42),//! b: 24,//! });//! # let _ = Box::pin_init(foo);//! ```//!//! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like//! (or just the stack) to actually initialize a `Foo`://!//! ```rust//! # #![expect(clippy::disallowed_names)]//! # #![feature(allocator_api)]//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;//! # use core::{alloc::AllocError, pin::Pin};//! # use pin_init::*;//! #//! # #[pin_data]//! # struct Foo {//! # #[pin]//! # a: CMutex<usize>,//! # b: u32,//! # }//! #//! # let foo = pin_init!(Foo {//! # a <- CMutex::new(42),//! # b: 24,//! # });//! let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo);//! ```//!//! For more information see the [`pin_init!`] macro.//!//! ## Using a custom function/macro that returns an initializer//!//! Many types that use this library supply a function/macro that returns an initializer, because//! the above method only works for types where you can access the fields.//!//! ```rust//! # #![feature(allocator_api)]//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;//! # use pin_init::*;//! # use std::sync::Arc;//! # use core::pin::Pin;//! let mtx: Result<Pin<Arc<CMutex<usize>>>, _> = Arc::pin_init(CMutex::new(42));//! ```//!//! To declare an init macro/function you just return an [`impl PinInit<T, E>`]://!//! ```rust//! # #![feature(allocator_api)]//! # use pin_init::*;//! # #[path = "../examples/error.rs"] mod error; use error::Error;//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;//! #[pin_data]//! struct DriverData {//! #[pin]//! status: CMutex<i32>,//! buffer: Box<[u8; 1_000_000]>,//! }//!//! impl DriverData {//! fn new() -> impl PinInit<Self, Error> {//! pin_init!(Self {//! status <- CMutex::new(0),//! buffer: Box::init(pin_init::init_zeroed())?,//! }? Error)//! }//! }//! ```//!//! ## Manual creation of an initializer//!//! Often when working with primitives the previous approaches are not sufficient. That is where//! [`pin_init_from_closure()`] comes in. This `unsafe` function allows you to create a//! [`impl PinInit<T, E>`] directly from a closure. Of course you have to ensure that the closure//! actually does the initialization in the correct way. Here are the things to look out for//! (we are calling the parameter to the closure `slot`)://! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so//! `slot` now contains a valid bit pattern for the type `T`,//! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so//! you need to take care to clean up anything if your initialization fails mid-way,//! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of//! `slot` gets called.//!//! ```rust//! # #![feature(extern_types)]//! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure};//! use core::{//! marker::PhantomPinned,//! cell::UnsafeCell,//! pin::Pin,//! mem::MaybeUninit,//! };//! mod bindings {//! #[repr(C)]//! pub struct foo {//! /* fields from C ... *///! }//! extern "C" {//! pub fn init_foo(ptr: *mut foo);//! pub fn destroy_foo(ptr: *mut foo);//! #[must_use = "you must check the error return code"]//! pub fn enable_foo(ptr: *mut foo, flags: u32) -> i32;//! }//! }//!//! /// # Invariants//! /////! /// `foo` is always initialized//! #[pin_data(PinnedDrop)]//! pub struct RawFoo {//! #[pin]//! _p: PhantomPinned,//! #[pin]//! foo: UnsafeCell<MaybeUninit<bindings::foo>>,//! }//!//! impl RawFoo {//! pub fn new(flags: u32) -> impl PinInit<Self, i32> {//! // SAFETY://! // - when the closure returns `Ok(())`, then it has successfully initialized and//! // enabled `foo`,//! // - when it returns `Err(e)`, then it has cleaned up before//! unsafe {//! pin_init_from_closure(move |slot: *mut Self| {//! // `slot` contains uninit memory, avoid creating a reference.//! let foo = &raw mut (*slot).foo;//! let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>();//!//! // Initialize the `foo`//! bindings::init_foo(foo);//!//! // Try to enable it.//! let err = bindings::enable_foo(foo, flags);//! if err != 0 {//! // Enabling has failed, first clean up the foo and then return the error.//! bindings::destroy_foo(foo);//! Err(err)//! } else {//! // All fields of `RawFoo` have been initialized, since `_p` is a ZST.//! Ok(())//! }//! })//! }//! }//! }//!//! #[pinned_drop]//! impl PinnedDrop for RawFoo {//! fn drop(self: Pin<&mut Self>) {//! // SAFETY: Since `foo` is initialized, destroying is safe.//! unsafe { bindings::destroy_foo(self.foo.get().cast::<bindings::foo>()) };//! }//! }//! ```//!//! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside//! the `kernel` crate. The [`sync`] module is a good starting point.//!//! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html//! [pinning]: https://doc.rust-lang.org/std/pin/index.html//! [structurally pinned fields]://! https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning//! [stack]: crate::stack_pin_init#![cfg_attr( kernel, doc = "[`Arc<T>`]: https://rust.docs.kernel.org/kernel/sync/struct.Arc.html")]#![cfg_attr( kernel, doc = "[`Box<T>`]: https://rust.docs.kernel.org/kernel/alloc/kbox/struct.Box.html")]#![cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")]#![cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")]//! [`impl PinInit<Foo>`]: crate::PinInit//! [`impl PinInit<T, E>`]: crate::PinInit//! [`impl Init<T, E>`]: crate::Init//! [Rust-for-Linux]: https://rust-for-linux.com/ #![forbid(missing_docs, unsafe_op_in_unsafe_fn)]#![cfg_attr(not(feature = "std"), no_std)]#![cfg_attr(feature = "alloc", feature(allocator_api))]#![cfg_attr( all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED), feature(unsafe_pinned))]#![cfg_attr(all(USE_RUSTC_FEATURES, doc), allow(internal_features))]#![cfg_attr(all(USE_RUSTC_FEATURES, doc), feature(rustdoc_internals))] use core::{ cell::UnsafeCell, convert::Infallible, marker::PhantomData, mem::MaybeUninit, num::*, pin::Pin, ptr::{self, NonNull},}; // This is used by doc-tests -- the proc-macros expand to `::pin_init::...` and without this the// doc-tests wouldn't have an extern crate named `pin_init`.#[allow(unused_extern_crates)]extern crate self as pin_init; #[doc(hidden)]pub mod __internal; #[cfg(any(feature = "std", feature = "alloc"))]mod alloc;#[cfg(any(feature = "std", feature = "alloc"))]pub use alloc::InPlaceInit; /// Used to specify the pinning information of the fields of a struct.////// This is somewhat similar in purpose as/// [pin-project-lite](https://crates.io/crates/pin-project-lite)./// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each/// field you want to structurally pin.////// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,/// then `#[pin]` directs the type of initializer that is required.////// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this/// macro, and change your `Drop` implementation to `PinnedDrop` annotated with/// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care.////// # Examples////// ```/// # #![feature(allocator_api)]/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;/// use pin_init::pin_data;////// enum Command {/// /* ... *//// }////// #[pin_data]/// struct DriverData {/// #[pin]/// queue: CMutex<Vec<Command>>,/// buf: Box<[u8; 1024 * 1024]>,/// }/// ```////// ```/// # #![feature(allocator_api)]/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;/// # mod bindings { pub struct info; pub unsafe fn destroy_info(_: *mut info) {} }/// use core::pin::Pin;/// use pin_init::{pin_data, pinned_drop, PinnedDrop};////// enum Command {/// /* ... *//// }////// #[pin_data(PinnedDrop)]/// struct DriverData {/// #[pin]/// queue: CMutex<Vec<Command>>,/// buf: Box<[u8; 1024 * 1024]>,/// raw_info: *mut bindings::info,/// }////// #[pinned_drop]/// impl PinnedDrop for DriverData {/// fn drop(self: Pin<&mut Self>) {/// unsafe { bindings::destroy_info(self.raw_info) };/// }/// }/// ```pub use ::pin_init_internal::pin_data; /// Used to implement `PinnedDrop` safely.////// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`.////// # Examples////// ```/// # #![feature(allocator_api)]/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;/// # mod bindings { pub struct info; pub unsafe fn destroy_info(_: *mut info) {} }/// use core::pin::Pin;/// use pin_init::{pin_data, pinned_drop, PinnedDrop};////// enum Command {/// /* ... *//// }////// #[pin_data(PinnedDrop)]/// struct DriverData {/// #[pin]/// queue: CMutex<Vec<Command>>,/// buf: Box<[u8; 1024 * 1024]>,/// raw_info: *mut bindings::info,/// }////// #[pinned_drop]/// impl PinnedDrop for DriverData {/// fn drop(self: Pin<&mut Self>) {/// unsafe { bindings::destroy_info(self.raw_info) };/// }/// }/// ```pub use ::pin_init_internal::pinned_drop; /// Derives the [`Zeroable`] trait for the given `struct` or `union`.////// This can only be used for `struct`s/`union`s where every field implements the [`Zeroable`]/// trait.////// # Examples////// ```/// use pin_init::Zeroable;////// #[derive(Zeroable)]/// pub struct DriverData {/// pub(crate) id: i64,/// buf_ptr: *mut u8,/// len: usize,/// }/// ```////// ```/// use pin_init::Zeroable;////// #[derive(Zeroable)]/// pub union SignCast {/// signed: i64,/// unsigned: u64,/// }/// ```pub use ::pin_init_internal::Zeroable; /// Derives the [`Zeroable`] trait for the given `struct` or `union` if all fields implement/// [`Zeroable`].////// Contrary to the derive macro named [`macro@Zeroable`], this one silently fails when a field/// doesn't implement [`Zeroable`].////// # Examples////// ```/// use pin_init::MaybeZeroable;////// // implements `Zeroable`/// #[derive(MaybeZeroable)]/// pub struct DriverData {/// pub(crate) id: i64,/// buf_ptr: *mut u8,/// len: usize,/// }////// // does not implement `Zeroable`/// #[derive(MaybeZeroable)]/// pub struct DriverData2 {/// pub(crate) id: i64,/// buf_ptr: *mut u8,/// len: usize,/// // this field doesn't implement `Zeroable`/// other_data: &'static i32,/// }/// ```pub use ::pin_init_internal::MaybeZeroable; /// Initialize and pin a type directly on the stack.////// # Examples////// ```rust/// # #![expect(clippy::disallowed_names)]/// # #![feature(allocator_api)]/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;/// # use pin_init::*;/// # use core::pin::Pin;/// #[pin_data]/// struct Foo {/// #[pin]/// a: CMutex<usize>,/// b: Bar,/// }////// #[pin_data]/// struct Bar {/// x: u32,/// }////// stack_pin_init!(let foo = pin_init!(Foo {/// a <- CMutex::new(42),/// b: Bar {/// x: 64,/// },/// }));/// let foo: Pin<&mut Foo> = foo;/// println!("a: {}", &*foo.a.lock());/// ```////// # Syntax////// A normal `let` binding with optional type annotation. The expression is expected to implement/// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error/// type, then use [`stack_try_pin_init!`].#[macro_export]macro_rules! stack_pin_init { (let $var:ident $(: $t:ty)? = $val:expr) => { let val = $val; let mut $var = ::core::pin::pin!($crate::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = match $crate::__internal::StackInit::init($var, val) { Ok(res) => res, Err(x) => { let x: ::core::convert::Infallible = x; match x {}Lines 1–500 of 1750. Load more
// SPDX-License-Identifier: Apache-2.0 OR MIT //! Library to safely and fallibly initialize pinned `struct`s using in-place constructors. //! //! [Pinning][pinning] is Rust's way of ensuring data does not move. //! //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack //! overflow. //! //! This library's main use-case is in [Rust-for-Linux]. Although this version can be used //! standalone. //! //! There are cases when you want to in-place initialize a struct. For example when it is very big //! and moving it from the stack is not an option, because it is bigger than the stack itself. //! Another reason would be that you need the address of the object to initialize it. This stands //! in direct conflict with Rust's normal process of first initializing an object and then moving //! it into it's final memory location. For more information, see //! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>. //! //! This library allows you to do in-place initialization safely. //! //! ## Nightly Needed for `alloc` feature //! //! This library requires the [`allocator_api` unstable feature] when the `alloc` feature is //! enabled and thus this feature can only be used with a nightly compiler. When enabling the //! `alloc` feature, the user will be required to activate `allocator_api` as well. //! //! [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html //! //! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler. //! However, using the crate on stable compilers is possible by disabling `alloc`. In practice this //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std //! mode. //! //! ## Nightly needed for `unsafe-pinned` feature //! //! This feature enables the `Wrapper` implementation on the unstable `core::pin::UnsafePinned` type. //! This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735) //! and therefore a nightly compiler. Note that this feature is not enabled by default. //! //! # Overview //! //! To initialize a `struct` with an in-place constructor you will need two things: //! - an in-place constructor, //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`], //! [`Box<T>`] or any other smart pointer that supports this library). //! //! To get an in-place constructor there are generally three options: //! - directly creating an in-place constructor using the [`pin_init!`] macro, //! - a custom function/macro returning an in-place constructor provided by someone else, //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer. //! //! Aside from pinned initialization, this library also supports in-place construction without //! pinning, the macros/types/functions are generally named like the pinned variants without the //! `pin_` prefix. //! //! # Examples //! //! Throughout the examples we will often make use of the `CMutex` type which can be found in //! `../examples/mutex.rs`. It is essentially a userland rebuild of the `struct mutex` type from //! the Linux kernel. It also uses a wait list and a basic spinlock. Importantly the wait list //! requires it to be pinned to be locked and thus is a prime candidate for using this library. //! //! ## Using the [`pin_init!`] macro //! //! If you want to use [`PinInit`], then you will have to annotate your `struct` with //! `#[`[`pin_data`]`]`. It is a macro that uses `#[pin]` as a marker for //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via //! [`pin_init!`]. The syntax is almost the same as normal `struct` initializers. The difference is //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place. //! //! ```rust //! # #![expect(clippy::disallowed_names)] //! # #![feature(allocator_api)] //! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; //! # use core::pin::Pin; //! use pin_init::{pin_data, pin_init, InPlaceInit}; //! //! #[pin_data] //! struct Foo { //! #[pin] //! a: CMutex<usize>, //! b: u32, //! } //! //! let foo = pin_init!(Foo { //! a <- CMutex::new(42), //! b: 24, //! }); //! # let _ = Box::pin_init(foo); //! ``` //! //! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like //! (or just the stack) to actually initialize a `Foo`: //! //! ```rust //! # #![expect(clippy::disallowed_names)] //! # #![feature(allocator_api)] //! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; //! # use core::{alloc::AllocError, pin::Pin}; //! # use pin_init::*; //! # //! # #[pin_data] //! # struct Foo { //! # #[pin] //! # a: CMutex<usize>, //! # b: u32, //! # } //! # //! # let foo = pin_init!(Foo { //! # a <- CMutex::new(42), //! # b: 24, //! # }); //! let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo); //! ``` //! //! For more information see the [`pin_init!`] macro. //! //! ## Using a custom function/macro that returns an initializer //! //! Many types that use this library supply a function/macro that returns an initializer, because //! the above method only works for types where you can access the fields. //! //! ```rust //! # #![feature(allocator_api)] //! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; //! # use pin_init::*; //! # use std::sync::Arc; //! # use core::pin::Pin; //! let mtx: Result<Pin<Arc<CMutex<usize>>>, _> = Arc::pin_init(CMutex::new(42)); //! ``` //! //! To declare an init macro/function you just return an [`impl PinInit<T, E>`]: //! //! ```rust //! # #![feature(allocator_api)] //! # use pin_init::*; //! # #[path = "../examples/error.rs"] mod error; use error::Error; //! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; //! #[pin_data] //! struct DriverData { //! #[pin] //! status: CMutex<i32>, //! buffer: Box<[u8; 1_000_000]>, //! } //! //! impl DriverData { //! fn new() -> impl PinInit<Self, Error> { //! pin_init!(Self { //! status <- CMutex::new(0), //! buffer: Box::init(pin_init::init_zeroed())?, //! }? Error) //! } //! } //! ``` //! //! ## Manual creation of an initializer //! //! Often when working with primitives the previous approaches are not sufficient. That is where //! [`pin_init_from_closure()`] comes in. This `unsafe` function allows you to create a //! [`impl PinInit<T, E>`] directly from a closure. Of course you have to ensure that the closure //! actually does the initialization in the correct way. Here are the things to look out for //! (we are calling the parameter to the closure `slot`): //! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so //! `slot` now contains a valid bit pattern for the type `T`, //! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so //! you need to take care to clean up anything if your initialization fails mid-way, //! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of //! `slot` gets called. //! //! ```rust //! # #![feature(extern_types)] //! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure}; //! use core::{ //! marker::PhantomPinned, //! cell::UnsafeCell, //! pin::Pin, //! mem::MaybeUninit, //! }; //! mod bindings { //! #[repr(C)] //! pub struct foo { //! /* fields from C ... */ //! } //! extern "C" { //! pub fn init_foo(ptr: *mut foo); //! pub fn destroy_foo(ptr: *mut foo); //! #[must_use = "you must check the error return code"] //! pub fn enable_foo(ptr: *mut foo, flags: u32) -> i32; //! } //! } //! //! /// # Invariants //! /// //! /// `foo` is always initialized //! #[pin_data(PinnedDrop)] //! pub struct RawFoo { //! #[pin] //! _p: PhantomPinned, //! #[pin] //! foo: UnsafeCell<MaybeUninit<bindings::foo>>, //! } //! //! impl RawFoo { //! pub fn new(flags: u32) -> impl PinInit<Self, i32> { //! // SAFETY: //! // - when the closure returns `Ok(())`, then it has successfully initialized and //! // enabled `foo`, //! // - when it returns `Err(e)`, then it has cleaned up before //! unsafe { //! pin_init_from_closure(move |slot: *mut Self| { //! // `slot` contains uninit memory, avoid creating a reference. //! let foo = &raw mut (*slot).foo; //! let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>(); //! //! // Initialize the `foo` //! bindings::init_foo(foo); //! //! // Try to enable it. //! let err = bindings::enable_foo(foo, flags); //! if err != 0 { //! // Enabling has failed, first clean up the foo and then return the error. //! bindings::destroy_foo(foo); //! Err(err) //! } else { //! // All fields of `RawFoo` have been initialized, since `_p` is a ZST. //! Ok(()) //! } //! }) //! } //! } //! } //! //! #[pinned_drop] //! impl PinnedDrop for RawFoo { //! fn drop(self: Pin<&mut Self>) { //! // SAFETY: Since `foo` is initialized, destroying is safe. //! unsafe { bindings::destroy_foo(self.foo.get().cast::<bindings::foo>()) }; //! } //! } //! ``` //! //! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside //! the `kernel` crate. The [`sync`] module is a good starting point. //! //! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html //! [pinning]: https://doc.rust-lang.org/std/pin/index.html //! [structurally pinned fields]: //! https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning //! [stack]: crate::stack_pin_init #![cfg_attr( kernel, doc = "[`Arc<T>`]: https://rust.docs.kernel.org/kernel/sync/struct.Arc.html" )] #![cfg_attr( kernel, doc = "[`Box<T>`]: https://rust.docs.kernel.org/kernel/alloc/kbox/struct.Box.html" )] #![cfg_attr(not(kernel), doc = "[`Arc<T>`]: alloc::alloc::sync::Arc")] #![cfg_attr(not(kernel), doc = "[`Box<T>`]: alloc::alloc::boxed::Box")] //! [`impl PinInit<Foo>`]: crate::PinInit //! [`impl PinInit<T, E>`]: crate::PinInit //! [`impl Init<T, E>`]: crate::Init //! [Rust-for-Linux]: https://rust-for-linux.com/ #![forbid(missing_docs, unsafe_op_in_unsafe_fn)] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "alloc", feature(allocator_api))] #![cfg_attr( all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED), feature(unsafe_pinned) )] #![cfg_attr(all(USE_RUSTC_FEATURES, doc), allow(internal_features))] #![cfg_attr(all(USE_RUSTC_FEATURES, doc), feature(rustdoc_internals))] use core::{ cell::UnsafeCell, convert::Infallible, marker::PhantomData, mem::MaybeUninit, num::*, pin::Pin, ptr::{self, NonNull}, }; // This is used by doc-tests -- the proc-macros expand to `::pin_init::...` and without this the // doc-tests wouldn't have an extern crate named `pin_init`. #[allow(unused_extern_crates)] extern crate self as pin_init; #[doc(hidden)] pub mod __internal; #[cfg(any(feature = "std", feature = "alloc"))] mod alloc; #[cfg(any(feature = "std", feature = "alloc"))] pub use alloc::InPlaceInit; /// Used to specify the pinning information of the fields of a struct. /// /// This is somewhat similar in purpose as /// [pin-project-lite](https://crates.io/crates/pin-project-lite). /// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each /// field you want to structurally pin. /// /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`, /// then `#[pin]` directs the type of initializer that is required. /// /// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this /// macro, and change your `Drop` implementation to `PinnedDrop` annotated with /// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care. /// /// # Examples /// /// ``` /// # #![feature(allocator_api)] /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; /// use pin_init::pin_data; /// /// enum Command { /// /* ... */ /// } /// /// #[pin_data] /// struct DriverData { /// #[pin] /// queue: CMutex<Vec<Command>>, /// buf: Box<[u8; 1024 * 1024]>, /// } /// ``` /// /// ``` /// # #![feature(allocator_api)] /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; /// # mod bindings { pub struct info; pub unsafe fn destroy_info(_: *mut info) {} } /// use core::pin::Pin; /// use pin_init::{pin_data, pinned_drop, PinnedDrop}; /// /// enum Command { /// /* ... */ /// } /// /// #[pin_data(PinnedDrop)] /// struct DriverData { /// #[pin] /// queue: CMutex<Vec<Command>>, /// buf: Box<[u8; 1024 * 1024]>, /// raw_info: *mut bindings::info, /// } /// /// #[pinned_drop] /// impl PinnedDrop for DriverData { /// fn drop(self: Pin<&mut Self>) { /// unsafe { bindings::destroy_info(self.raw_info) }; /// } /// } /// ``` pub use ::pin_init_internal::pin_data; /// Used to implement `PinnedDrop` safely. /// /// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`. /// /// # Examples /// /// ``` /// # #![feature(allocator_api)] /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; /// # mod bindings { pub struct info; pub unsafe fn destroy_info(_: *mut info) {} } /// use core::pin::Pin; /// use pin_init::{pin_data, pinned_drop, PinnedDrop}; /// /// enum Command { /// /* ... */ /// } /// /// #[pin_data(PinnedDrop)] /// struct DriverData { /// #[pin] /// queue: CMutex<Vec<Command>>, /// buf: Box<[u8; 1024 * 1024]>, /// raw_info: *mut bindings::info, /// } /// /// #[pinned_drop] /// impl PinnedDrop for DriverData { /// fn drop(self: Pin<&mut Self>) { /// unsafe { bindings::destroy_info(self.raw_info) }; /// } /// } /// ``` pub use ::pin_init_internal::pinned_drop; /// Derives the [`Zeroable`] trait for the given `struct` or `union`. /// /// This can only be used for `struct`s/`union`s where every field implements the [`Zeroable`] /// trait. /// /// # Examples /// /// ``` /// use pin_init::Zeroable; /// /// #[derive(Zeroable)] /// pub struct DriverData { /// pub(crate) id: i64, /// buf_ptr: *mut u8, /// len: usize, /// } /// ``` /// /// ``` /// use pin_init::Zeroable; /// /// #[derive(Zeroable)] /// pub union SignCast { /// signed: i64, /// unsigned: u64, /// } /// ``` pub use ::pin_init_internal::Zeroable; /// Derives the [`Zeroable`] trait for the given `struct` or `union` if all fields implement /// [`Zeroable`]. /// /// Contrary to the derive macro named [`macro@Zeroable`], this one silently fails when a field /// doesn't implement [`Zeroable`]. /// /// # Examples /// /// ``` /// use pin_init::MaybeZeroable; /// /// // implements `Zeroable` /// #[derive(MaybeZeroable)] /// pub struct DriverData { /// pub(crate) id: i64, /// buf_ptr: *mut u8, /// len: usize, /// } /// /// // does not implement `Zeroable` /// #[derive(MaybeZeroable)] /// pub struct DriverData2 { /// pub(crate) id: i64, /// buf_ptr: *mut u8, /// len: usize, /// // this field doesn't implement `Zeroable` /// other_data: &'static i32, /// } /// ``` pub use ::pin_init_internal::MaybeZeroable; /// Initialize and pin a type directly on the stack. /// /// # Examples /// /// ```rust /// # #![expect(clippy::disallowed_names)] /// # #![feature(allocator_api)] /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*; /// # use pin_init::*; /// # use core::pin::Pin; /// #[pin_data] /// struct Foo { /// #[pin] /// a: CMutex<usize>, /// b: Bar, /// } /// /// #[pin_data] /// struct Bar { /// x: u32, /// } /// /// stack_pin_init!(let foo = pin_init!(Foo { /// a <- CMutex::new(42), /// b: Bar { /// x: 64, /// }, /// })); /// let foo: Pin<&mut Foo> = foo; /// println!("a: {}", &*foo.a.lock()); /// ``` /// /// # Syntax /// /// A normal `let` binding with optional type annotation. The expression is expected to implement /// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error /// type, then use [`stack_try_pin_init!`]. #[macro_export] macro_rules! stack_pin_init { (let $var:ident $(: $t:ty)? = $val:expr) => { let val = $val; let mut $var = ::core::pin::pin!($crate::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = match $crate::__internal::StackInit::init($var, val) { Ok(res) => res, Err(x) => { let x: ::core::convert::Infallible = x; match x {}