// SPDX-License-Identifier: Apache-2.0 OR MIT //! API to safely and fallibly initialize pinned `struct`s using in-place constructors.//!//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack//! overflow.//!//! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential//! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move.//!//! # 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>`],//! [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]).//!//! 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 API also supports in-place construction without pinning,//! the macros/types/functions are generally named like the pinned variants without the `pin`//! prefix.//!//! # Examples//!//! ## 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//! # #![allow(clippy::disallowed_names)]//! use kernel::sync::{new_mutex, Mutex};//! # use core::pin::Pin;//! #[pin_data]//! struct Foo {//! #[pin]//! a: Mutex<usize>,//! b: u32,//! }//!//! let foo = pin_init!(Foo {//! a <- new_mutex!(42, "Foo::a"),//! b: 24,//! });//! ```//!//! `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//! # #![allow(clippy::disallowed_names)]//! # use kernel::sync::{new_mutex, Mutex};//! # use core::pin::Pin;//! # #[pin_data]//! # struct Foo {//! # #[pin]//! # a: Mutex<usize>,//! # b: u32,//! # }//! # let foo = pin_init!(Foo {//! # a <- new_mutex!(42, "Foo::a"),//! # b: 24,//! # });//! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo, GFP_KERNEL);//! ```//!//! For more information see the [`pin_init!`] macro.//!//! ## Using a custom function/macro that returns an initializer//!//! Many types from the kernel supply a function/macro that returns an initializer, because the//! above method only works for types where you can access the fields.//!//! ```rust//! # use kernel::sync::{new_mutex, Arc, Mutex};//! let mtx: Result<Arc<Mutex<usize>>> =//! Arc::pin_init(new_mutex!(42, "example::mtx"), GFP_KERNEL);//! ```//!//! To declare an init macro/function you just return an [`impl PinInit<T, E>`]://!//! ```rust//! # #![allow(clippy::disallowed_names)]//! # use kernel::{sync::Mutex, new_mutex, init::PinInit, try_pin_init};//! #[pin_data]//! struct DriverData {//! #[pin]//! status: Mutex<i32>,//! buffer: Box<[u8; 1_000_000]>,//! }//!//! impl DriverData {//! fn new() -> impl PinInit<Self, Error> {//! try_pin_init!(Self {//! status <- new_mutex!(0, "DriverData::status"),//! buffer: Box::init(kernel::init::zeroed(), GFP_KERNEL)?,//! })//! }//! }//! ```//!//! ## 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//! # #![allow(unreachable_pub, clippy::disallowed_names)]//! use kernel::{init, types::Opaque};//! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};//! # mod bindings {//! # #![allow(non_camel_case_types)]//! # pub struct foo;//! # pub unsafe fn init_foo(_ptr: *mut foo) {}//! # pub unsafe fn destroy_foo(_ptr: *mut foo) {}//! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }//! # }//! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.//! # trait FromErrno {//! # fn from_errno(errno: core::ffi::c_int) -> Error {//! # // Dummy error that can be constructed outside the `kernel` crate.//! # Error::from(core::fmt::Error)//! # }//! # }//! # impl FromErrno for Error {}//! /// # Invariants//! /////! /// `foo` is always initialized//! #[pin_data(PinnedDrop)]//! pub struct RawFoo {//! #[pin]//! foo: Opaque<bindings::foo>,//! #[pin]//! _p: PhantomPinned,//! }//!//! impl RawFoo {//! pub fn new(flags: u32) -> impl PinInit<Self, Error> {//! // 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 {//! init::pin_init_from_closure(move |slot: *mut Self| {//! // `slot` contains uninit memory, avoid creating a reference.//! let foo = addr_of_mut!((*slot).foo);//!//! // Initialize the `foo`//! bindings::init_foo(Opaque::raw_get(foo));//!//! // Try to enable it.//! let err = bindings::enable_foo(Opaque::raw_get(foo), flags);//! if err != 0 {//! // Enabling has failed, first clean up the foo and then return the error.//! bindings::destroy_foo(Opaque::raw_get(foo));//! return Err(Error::from_errno(err));//! }//!//! // 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()) };//! }//! }//! ```//!//! For the special case where initializing a field is a single FFI-function call that cannot fail,//! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single//! [`Opaque`] field by just delegating to the supplied closure. You can use these in combination//! with [`pin_init!`].//!//! 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`]: kernel::sync//! [pinning]: https://doc.rust-lang.org/std/pin/index.html//! [structurally pinned fields]://! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field//! [stack]: crate::stack_pin_init//! [`Arc<T>`]: crate::sync::Arc//! [`impl PinInit<Foo>`]: PinInit//! [`impl PinInit<T, E>`]: PinInit//! [`impl Init<T, E>`]: Init//! [`Opaque`]: kernel::types::Opaque//! [`Opaque::ffi_init`]: kernel::types::Opaque::ffi_init//! [`pin_data`]: ::macros::pin_data//! [`pin_init!`]: crate::pin_init! use crate::{ alloc::{box_ext::BoxExt, AllocError, Flags}, error::{self, Error}, sync::UniqueArc, types::{Opaque, ScopeGuard},};use alloc::boxed::Box;use core::{ cell::UnsafeCell, convert::Infallible, marker::PhantomData, mem::MaybeUninit, num::*, pin::Pin, ptr::{self, NonNull},}; #[doc(hidden)]pub mod __internal;#[doc(hidden)]pub mod macros; /// Initialize and pin a type directly on the stack.////// # Examples////// ```rust/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, macros::pin_data, pin_init, stack_pin_init, init::*, sync::Mutex, new_mutex};/// # use core::pin::Pin;/// #[pin_data]/// struct Foo {/// #[pin]/// a: Mutex<usize>,/// b: Bar,/// }////// #[pin_data]/// struct Bar {/// x: u32,/// }////// stack_pin_init!(let foo = pin_init!(Foo {/// a <- new_mutex!(42),/// b: Bar {/// x: 64,/// },/// }));/// let foo: Pin<&mut Foo> = foo;/// pr_info!("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!`].////// [`stack_try_pin_init!`]: crate::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::init::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = match $crate::init::__internal::StackInit::init($var, val) { Ok(res) => res, Err(x) => { let x: ::core::convert::Infallible = x; match x {} } }; };} /// Initialize and pin a type directly on the stack.////// # Examples////// ```rust,ignore/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex};/// # use macros::pin_data;/// # use core::{alloc::AllocError, pin::Pin};/// #[pin_data]/// struct Foo {/// #[pin]/// a: Mutex<usize>,/// b: Box<Bar>,/// }////// struct Bar {/// x: u32,/// }////// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo {/// a <- new_mutex!(42),/// b: Box::new(Bar {/// x: 64,/// }, GFP_KERNEL)?,/// }));/// let foo = foo.unwrap();/// pr_info!("a: {}", &*foo.a.lock());/// ```////// ```rust,ignore/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex};/// # use macros::pin_data;/// # use core::{alloc::AllocError, pin::Pin};/// #[pin_data]/// struct Foo {/// #[pin]/// a: Mutex<usize>,/// b: Box<Bar>,/// }////// struct Bar {/// x: u32,/// }////// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo {/// a <- new_mutex!(42),/// b: Box::new(Bar {/// x: 64,/// }, GFP_KERNEL)?,/// }));/// pr_info!("a: {}", &*foo.a.lock());/// # Ok::<_, AllocError>(())/// ```////// # Syntax////// A normal `let` binding with optional type annotation. The expression is expected to implement/// [`PinInit`]/[`Init`]. This macro assigns a result to the given variable, adding a `?` after the/// `=` will propagate this error.#[macro_export]macro_rules! stack_try_pin_init { (let $var:ident $(: $t:ty)? = $val:expr) => { let val = $val; let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = $crate::init::__internal::StackInit::init($var, val); }; (let $var:ident $(: $t:ty)? =? $val:expr) => { let val = $val; let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = $crate::init::__internal::StackInit::init($var, val)?; };} /// Construct an in-place, pinned initializer for `struct`s.////// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use/// [`try_pin_init!`].////// The syntax is almost identical to that of a normal `struct` initializer:////// ```rust/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, pin_init, macros::pin_data, init::*};/// # use core::pin::Pin;/// #[pin_data]/// struct Foo {/// a: usize,/// b: Bar,/// }////// #[pin_data]/// struct Bar {/// x: u32,/// }////// # fn demo() -> impl PinInit<Foo> {/// let a = 42;////// let initializer = pin_init!(Foo {/// a,/// b: Bar {/// x: 64,/// },/// });/// # initializer }/// # Box::pin_init(demo(), GFP_KERNEL).unwrap();/// ```////// Arbitrary Rust expressions can be used to set the value of a variable.////// The fields are initialized in the order that they appear in the initializer. So it is possible/// to read already initialized fields using raw pointers.////// IMPORTANT: You are not allowed to create references to fields of the struct inside of the/// initializer.////// # Init-functions////// When working with this API it is often desired to let others construct your types without/// giving access to all fields. This is where you would normally write a plain function `new`/// that would return a new instance of your type. With this API that is also possible./// However, there are a few extra things to keep in mind.////// To create an initializer function, simply declare it like this:////// ```rust/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, pin_init, init::*};/// # use core::pin::Pin;/// # #[pin_data]/// # struct Foo {/// # a: usize,/// # b: Bar,/// # }/// # #[pin_data]/// # struct Bar {/// # x: u32,/// # }/// impl Foo {/// fn new() -> impl PinInit<Self> {/// pin_init!(Self {/// a: 42,/// b: Bar {/// x: 64,/// },/// })/// }/// }/// ```////// Users of `Foo` can now create it like this:////// ```rust/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, pin_init, macros::pin_data, init::*};/// # use core::pin::Pin;/// # #[pin_data]/// # struct Foo {/// # a: usize,/// # b: Bar,/// # }/// # #[pin_data]/// # struct Bar {/// # x: u32,/// # }/// # impl Foo {/// # fn new() -> impl PinInit<Self> {/// # pin_init!(Self {/// # a: 42,/// # b: Bar {/// # x: 64,/// # },/// # })/// # }/// # }/// let foo = Box::pin_init(Foo::new(), GFP_KERNEL);/// ```////// They can also easily embed it into their own `struct`s:////// ```rust/// # #![allow(clippy::disallowed_names)]/// # use kernel::{init, pin_init, macros::pin_data, init::*};/// # use core::pin::Pin;/// # #[pin_data]/// # struct Foo {/// # a: usize,/// # b: Bar,/// # }/// # #[pin_data]/// # struct Bar {/// # x: u32,/// # }/// # impl Foo {/// # fn new() -> impl PinInit<Self> {/// # pin_init!(Self {/// # a: 42,/// # b: Bar {/// # x: 64,/// # },/// # })/// # }/// # }/// #[pin_data]/// struct FooContainer {/// #[pin]/// foo1: Foo,/// #[pin]/// foo2: Foo,/// other: u32,/// }///Lines 1–500 of 1347. Load more
// SPDX-License-Identifier: Apache-2.0 OR MIT //! API to safely and fallibly initialize pinned `struct`s using in-place constructors. //! //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack //! overflow. //! //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move. //! //! # 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>`], //! [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]). //! //! 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 API also supports in-place construction without pinning, //! the macros/types/functions are generally named like the pinned variants without the `pin` //! prefix. //! //! # Examples //! //! ## 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 //! # #![allow(clippy::disallowed_names)] //! use kernel::sync::{new_mutex, Mutex}; //! # use core::pin::Pin; //! #[pin_data] //! struct Foo { //! #[pin] //! a: Mutex<usize>, //! b: u32, //! } //! //! let foo = pin_init!(Foo { //! a <- new_mutex!(42, "Foo::a"), //! b: 24, //! }); //! ``` //! //! `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 //! # #![allow(clippy::disallowed_names)] //! # use kernel::sync::{new_mutex, Mutex}; //! # use core::pin::Pin; //! # #[pin_data] //! # struct Foo { //! # #[pin] //! # a: Mutex<usize>, //! # b: u32, //! # } //! # let foo = pin_init!(Foo { //! # a <- new_mutex!(42, "Foo::a"), //! # b: 24, //! # }); //! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo, GFP_KERNEL); //! ``` //! //! For more information see the [`pin_init!`] macro. //! //! ## Using a custom function/macro that returns an initializer //! //! Many types from the kernel supply a function/macro that returns an initializer, because the //! above method only works for types where you can access the fields. //! //! ```rust //! # use kernel::sync::{new_mutex, Arc, Mutex}; //! let mtx: Result<Arc<Mutex<usize>>> = //! Arc::pin_init(new_mutex!(42, "example::mtx"), GFP_KERNEL); //! ``` //! //! To declare an init macro/function you just return an [`impl PinInit<T, E>`]: //! //! ```rust //! # #![allow(clippy::disallowed_names)] //! # use kernel::{sync::Mutex, new_mutex, init::PinInit, try_pin_init}; //! #[pin_data] //! struct DriverData { //! #[pin] //! status: Mutex<i32>, //! buffer: Box<[u8; 1_000_000]>, //! } //! //! impl DriverData { //! fn new() -> impl PinInit<Self, Error> { //! try_pin_init!(Self { //! status <- new_mutex!(0, "DriverData::status"), //! buffer: Box::init(kernel::init::zeroed(), GFP_KERNEL)?, //! }) //! } //! } //! ``` //! //! ## 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 //! # #![allow(unreachable_pub, clippy::disallowed_names)] //! use kernel::{init, types::Opaque}; //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; //! # mod bindings { //! # #![allow(non_camel_case_types)] //! # pub struct foo; //! # pub unsafe fn init_foo(_ptr: *mut foo) {} //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {} //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 } //! # } //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround. //! # trait FromErrno { //! # fn from_errno(errno: core::ffi::c_int) -> Error { //! # // Dummy error that can be constructed outside the `kernel` crate. //! # Error::from(core::fmt::Error) //! # } //! # } //! # impl FromErrno for Error {} //! /// # Invariants //! /// //! /// `foo` is always initialized //! #[pin_data(PinnedDrop)] //! pub struct RawFoo { //! #[pin] //! foo: Opaque<bindings::foo>, //! #[pin] //! _p: PhantomPinned, //! } //! //! impl RawFoo { //! pub fn new(flags: u32) -> impl PinInit<Self, Error> { //! // 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 { //! init::pin_init_from_closure(move |slot: *mut Self| { //! // `slot` contains uninit memory, avoid creating a reference. //! let foo = addr_of_mut!((*slot).foo); //! //! // Initialize the `foo` //! bindings::init_foo(Opaque::raw_get(foo)); //! //! // Try to enable it. //! let err = bindings::enable_foo(Opaque::raw_get(foo), flags); //! if err != 0 { //! // Enabling has failed, first clean up the foo and then return the error. //! bindings::destroy_foo(Opaque::raw_get(foo)); //! return Err(Error::from_errno(err)); //! } //! //! // 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()) }; //! } //! } //! ``` //! //! For the special case where initializing a field is a single FFI-function call that cannot fail, //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single //! [`Opaque`] field by just delegating to the supplied closure. You can use these in combination //! with [`pin_init!`]. //! //! 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`]: kernel::sync //! [pinning]: https://doc.rust-lang.org/std/pin/index.html //! [structurally pinned fields]: //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field //! [stack]: crate::stack_pin_init //! [`Arc<T>`]: crate::sync::Arc //! [`impl PinInit<Foo>`]: PinInit //! [`impl PinInit<T, E>`]: PinInit //! [`impl Init<T, E>`]: Init //! [`Opaque`]: kernel::types::Opaque //! [`Opaque::ffi_init`]: kernel::types::Opaque::ffi_init //! [`pin_data`]: ::macros::pin_data //! [`pin_init!`]: crate::pin_init! use crate::{ alloc::{box_ext::BoxExt, AllocError, Flags}, error::{self, Error}, sync::UniqueArc, types::{Opaque, ScopeGuard}, }; use alloc::boxed::Box; use core::{ cell::UnsafeCell, convert::Infallible, marker::PhantomData, mem::MaybeUninit, num::*, pin::Pin, ptr::{self, NonNull}, }; #[doc(hidden)] pub mod __internal; #[doc(hidden)] pub mod macros; /// Initialize and pin a type directly on the stack. /// /// # Examples /// /// ```rust /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, macros::pin_data, pin_init, stack_pin_init, init::*, sync::Mutex, new_mutex}; /// # use core::pin::Pin; /// #[pin_data] /// struct Foo { /// #[pin] /// a: Mutex<usize>, /// b: Bar, /// } /// /// #[pin_data] /// struct Bar { /// x: u32, /// } /// /// stack_pin_init!(let foo = pin_init!(Foo { /// a <- new_mutex!(42), /// b: Bar { /// x: 64, /// }, /// })); /// let foo: Pin<&mut Foo> = foo; /// pr_info!("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!`]. /// /// [`stack_try_pin_init!`]: crate::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::init::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = match $crate::init::__internal::StackInit::init($var, val) { Ok(res) => res, Err(x) => { let x: ::core::convert::Infallible = x; match x {} } }; }; } /// Initialize and pin a type directly on the stack. /// /// # Examples /// /// ```rust,ignore /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; /// # use macros::pin_data; /// # use core::{alloc::AllocError, pin::Pin}; /// #[pin_data] /// struct Foo { /// #[pin] /// a: Mutex<usize>, /// b: Box<Bar>, /// } /// /// struct Bar { /// x: u32, /// } /// /// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo { /// a <- new_mutex!(42), /// b: Box::new(Bar { /// x: 64, /// }, GFP_KERNEL)?, /// })); /// let foo = foo.unwrap(); /// pr_info!("a: {}", &*foo.a.lock()); /// ``` /// /// ```rust,ignore /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; /// # use macros::pin_data; /// # use core::{alloc::AllocError, pin::Pin}; /// #[pin_data] /// struct Foo { /// #[pin] /// a: Mutex<usize>, /// b: Box<Bar>, /// } /// /// struct Bar { /// x: u32, /// } /// /// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo { /// a <- new_mutex!(42), /// b: Box::new(Bar { /// x: 64, /// }, GFP_KERNEL)?, /// })); /// pr_info!("a: {}", &*foo.a.lock()); /// # Ok::<_, AllocError>(()) /// ``` /// /// # Syntax /// /// A normal `let` binding with optional type annotation. The expression is expected to implement /// [`PinInit`]/[`Init`]. This macro assigns a result to the given variable, adding a `?` after the /// `=` will propagate this error. #[macro_export] macro_rules! stack_try_pin_init { (let $var:ident $(: $t:ty)? = $val:expr) => { let val = $val; let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = $crate::init::__internal::StackInit::init($var, val); }; (let $var:ident $(: $t:ty)? =? $val:expr) => { let val = $val; let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); let mut $var = $crate::init::__internal::StackInit::init($var, val)?; }; } /// Construct an in-place, pinned initializer for `struct`s. /// /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use /// [`try_pin_init!`]. /// /// The syntax is almost identical to that of a normal `struct` initializer: /// /// ```rust /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, macros::pin_data, init::*}; /// # use core::pin::Pin; /// #[pin_data] /// struct Foo { /// a: usize, /// b: Bar, /// } /// /// #[pin_data] /// struct Bar { /// x: u32, /// } /// /// # fn demo() -> impl PinInit<Foo> { /// let a = 42; /// /// let initializer = pin_init!(Foo { /// a, /// b: Bar { /// x: 64, /// }, /// }); /// # initializer } /// # Box::pin_init(demo(), GFP_KERNEL).unwrap(); /// ``` /// /// Arbitrary Rust expressions can be used to set the value of a variable. /// /// The fields are initialized in the order that they appear in the initializer. So it is possible /// to read already initialized fields using raw pointers. /// /// IMPORTANT: You are not allowed to create references to fields of the struct inside of the /// initializer. /// /// # Init-functions /// /// When working with this API it is often desired to let others construct your types without /// giving access to all fields. This is where you would normally write a plain function `new` /// that would return a new instance of your type. With this API that is also possible. /// However, there are a few extra things to keep in mind. /// /// To create an initializer function, simply declare it like this: /// /// ```rust /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, init::*}; /// # use core::pin::Pin; /// # #[pin_data] /// # struct Foo { /// # a: usize, /// # b: Bar, /// # } /// # #[pin_data] /// # struct Bar { /// # x: u32, /// # } /// impl Foo { /// fn new() -> impl PinInit<Self> { /// pin_init!(Self { /// a: 42, /// b: Bar { /// x: 64, /// }, /// }) /// } /// } /// ``` /// /// Users of `Foo` can now create it like this: /// /// ```rust /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, macros::pin_data, init::*}; /// # use core::pin::Pin; /// # #[pin_data] /// # struct Foo { /// # a: usize, /// # b: Bar, /// # } /// # #[pin_data] /// # struct Bar { /// # x: u32, /// # } /// # impl Foo { /// # fn new() -> impl PinInit<Self> { /// # pin_init!(Self { /// # a: 42, /// # b: Bar { /// # x: 64, /// # }, /// # }) /// # } /// # } /// let foo = Box::pin_init(Foo::new(), GFP_KERNEL); /// ``` /// /// They can also easily embed it into their own `struct`s: /// /// ```rust /// # #![allow(clippy::disallowed_names)] /// # use kernel::{init, pin_init, macros::pin_data, init::*}; /// # use core::pin::Pin; /// # #[pin_data] /// # struct Foo { /// # a: usize, /// # b: Bar, /// # } /// # #[pin_data] /// # struct Bar { /// # x: u32, /// # } /// # impl Foo { /// # fn new() -> impl PinInit<Self> { /// # pin_init!(Self { /// # a: 42, /// # b: Bar { /// # x: 64, /// # }, /// # }) /// # } /// # } /// #[pin_data] /// struct FooContainer { /// #[pin] /// foo1: Foo, /// #[pin] /// foo2: Foo, /// other: u32, /// } ///