11// SPDX-License-Identifier: Apache-2.0 OR MIT
22
3- //! API to safely and fallibly initialize pinned `struct`s using in-place constructors.
3+ //! Library to safely and fallibly initialize pinned `struct`s using in-place constructors.
4+ //!
5+ //! [Pinning][pinning] is Rust's way of ensuring data does not move.
46//!
57//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
68//! overflow.
79//!
10+ //! This library's main use-case is in [Rust-for-Linux]. Although this version can be used
11+ //! standalone.
12+ //!
13+ //! There are cases when you want to in-place initialize a struct. For example when it is very big
14+ //! and moving it from the stack is not an option, because it is bigger than the stack itself.
15+ //! Another reason would be that you need the address of the object to initialize it. This stands
16+ //! in direct conflict with Rust's normal process of first initializing an object and then moving
17+ //! it into it's final memory location. For more information, see
18+ //! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>.
19+ //!
20+ //! This library allows you to do in-place initialization safely.
21+ //!
22+ //! ## Nightly Needed for `alloc` feature
23+ //!
24+ //! This library requires the [`allocator_api` unstable feature] when the `alloc` feature is
25+ //! enabled and thus this feature can only be used with a nightly compiler. When enabling the
26+ //! `alloc` feature, the user will be required to activate `allocator_api` as well.
27+ //!
28+ //! [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html
29+ //!
30+ //! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler.
31+ //! However, using the crate on stable compilers is possible by disabling `alloc`. In practice this
32+ //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std
33+ //! mode.
34+ //!
835//! # Overview
936//!
1037//! To initialize a `struct` with an in-place constructor you will need two things:
1744//! - a custom function/macro returning an in-place constructor provided by someone else,
1845//! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
1946//!
20- //! Aside from pinned initialization, this API also supports in-place construction without pinning,
21- //! the macros/types/functions are generally named like the pinned variants without the `pin`
22- //! prefix.
47+ //! Aside from pinned initialization, this library also supports in-place construction without
48+ //! pinning, the macros/types/functions are generally named like the pinned variants without the
49+ //! `pin_` prefix.
2350//!
2451//! # Examples
2552//!
53+ //! Throughout the examples we will often make use of the `CMutex` type which can be found in
54+ //! `../examples/mutex.rs`. It is essentially a userland rebuild of the `struct mutex` type from
55+ //! the Linux kernel. It also uses a wait list and a basic spinlock. Importantly the wait list
56+ //! requires it to be pinned to be locked and thus is a prime candidate for using this library.
57+ //!
2658//! ## Using the [`pin_init!`] macro
2759//!
2860//! If you want to use [`PinInit`], then you will have to annotate your `struct` with
3668//! # #![feature(allocator_api)]
3769//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;
3870//! # use core::pin::Pin;
39- //! use pin_init::* ;
71+ //! use pin_init::{pin_data, pin_init, InPlaceInit} ;
4072//!
4173//! #[pin_data]
4274//! struct Foo {
80112//!
81113//! ## Using a custom function/macro that returns an initializer
82114//!
83- //! Many types from the kernel supply a function/macro that returns an initializer, because the
84- //! above method only works for types where you can access the fields.
115+ //! Many types that use this library supply a function/macro that returns an initializer, because
116+ //! the above method only works for types where you can access the fields.
85117//!
86118//! ```rust,ignore
87119//! # #![feature(allocator_api)]
132164//!
133165//! ```rust,ignore
134166//! # #![feature(extern_types)]
135- //! use pin_init::* ;
167+ //! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure} ;
136168//! use core::{
137169//! ptr::addr_of_mut,
138170//! marker::PhantomPinned,
141173//! mem::MaybeUninit,
142174//! };
143175//! mod bindings {
176+ //! #[repr(C)]
177+ //! pub struct foo {
178+ //! /* fields from C ... */
179+ //! }
144180//! extern "C" {
145- //! pub type foo;
146181//! pub fn init_foo(ptr: *mut foo);
147182//! pub fn destroy_foo(ptr: *mut foo);
148183//! #[must_use = "you must check the error return code"]
200235//! }
201236//! ```
202237//!
238+ //! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside
239+ //! the `kernel` crate. The [`sync`] module is a good starting point.
240+ //!
241+ //! [`sync`]: https://rust.docs.kernel.org/kernel/sync/index.html
203242//! [pinning]: https://doc.rust-lang.org/std/pin/index.html
204243//! [structurally pinned fields]:
205244//! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
214253) ]
215254#![ cfg_attr( not( kernel) , doc = "[`Arc<T>`]: alloc::alloc::sync::Arc" ) ]
216255#![ cfg_attr( not( kernel) , doc = "[`Box<T>`]: alloc::alloc::boxed::Box" ) ]
217- //! [`impl PinInit<Foo>`]: PinInit
218- //! [`impl PinInit<T, E>`]: PinInit
219- //! [`impl Init<T, E>`]: Init
220- //! [`pin_data`]: crate::pin_data
221- //! [`pin_init!`]: crate::pin_init!
256+ //! [`impl PinInit<Foo>`]: crate::PinInit
257+ //! [`impl PinInit<T, E>`]: crate::PinInit
258+ //! [`impl Init<T, E>`]: crate::Init
259+ //! [Rust-for-Linux]: https://rust-for-linux.com/
222260
223261#![ cfg_attr( not( RUSTC_LINT_REASONS_IS_STABLE ) , feature( lint_reasons) ) ]
224262#![ cfg_attr(
@@ -404,8 +442,6 @@ pub use ::pin_init_internal::Zeroable;
404442/// A normal `let` binding with optional type annotation. The expression is expected to implement
405443/// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error
406444/// type, then use [`stack_try_pin_init!`].
407- ///
408- /// [`stack_try_pin_init!`]: crate::stack_try_pin_init!
409445#[ macro_export]
410446macro_rules! stack_pin_init {
411447 ( let $var: ident $( : $t: ty) ? = $val: expr) => {
@@ -542,10 +578,10 @@ macro_rules! stack_try_pin_init {
542578///
543579/// # Init-functions
544580///
545- /// When working with this API it is often desired to let others construct your types without
546- /// giving access to all fields. This is where you would normally write a plain function `new`
547- /// that would return a new instance of your type. With this API that is also possible.
548- /// However, there are a few extra things to keep in mind.
581+ /// When working with this library it is often desired to let others construct your types without
582+ /// giving access to all fields. This is where you would normally write a plain function `new` that
583+ /// would return a new instance of your type. With this library that is also possible. However,
584+ /// there are a few extra things to keep in mind.
549585///
550586/// To create an initializer function, simply declare it like this:
551587///
@@ -674,22 +710,22 @@ macro_rules! stack_try_pin_init {
674710/// #[pin]
675711/// pin: PhantomPinned,
676712/// }
677- /// pin_init!(&this in Buf {
713+ ///
714+ /// let init = pin_init!(&this in Buf {
678715/// buf: [0; 64],
679716/// // SAFETY: TODO.
680717/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },
681718/// pin: PhantomPinned,
682719/// });
683- /// pin_init!(Buf {
720+ /// let init = pin_init!(Buf {
684721/// buf: [1; 64],
685722/// ..Zeroable::zeroed()
686723/// });
687724/// ```
688725///
689- /// [`try_pin_init!`]: crate::try_pin_init
690726/// [`NonNull<Self>`]: core::ptr::NonNull
691727// For a detailed example of how this macro works, see the module documentation of the hidden
692- // module `__internal ` inside of `init/__internal .rs`.
728+ // module `macros ` inside of `macros .rs`.
693729#[ macro_export]
694730macro_rules! pin_init {
695731 ( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -719,7 +755,8 @@ macro_rules! pin_init {
719755/// ```rust,ignore
720756/// # #![feature(allocator_api)]
721757/// # #[path = "../examples/error.rs"] mod error; use error::Error;
722- /// use pin_init::*;
758+ /// use pin_init::{pin_data, try_pin_init, PinInit, InPlaceInit, zeroed};
759+ ///
723760/// #[pin_data]
724761/// struct BigBuf {
725762/// big: Box<[u8; 1024 * 1024 * 1024]>,
@@ -730,7 +767,7 @@ macro_rules! pin_init {
730767/// impl BigBuf {
731768/// fn new() -> impl PinInit<Self, Error> {
732769/// try_pin_init!(Self {
733- /// big: Box::init(init:: zeroed())?,
770+ /// big: Box::init(zeroed())?,
734771/// small: [0; 1024 * 1024],
735772/// ptr: core::ptr::null_mut(),
736773/// }? Error)
@@ -739,7 +776,7 @@ macro_rules! pin_init {
739776/// # let _ = Box::pin_init(BigBuf::new());
740777/// ```
741778// For a detailed example of how this macro works, see the module documentation of the hidden
742- // module `__internal ` inside of `init/__internal .rs`.
779+ // module `macros ` inside of `macros .rs`.
743780#[ macro_export]
744781macro_rules! try_pin_init {
745782 ( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -772,9 +809,30 @@ macro_rules! try_pin_init {
772809/// This initializer is for initializing data in-place that might later be moved. If you want to
773810/// pin-initialize, use [`pin_init!`].
774811///
775- /// [`try_init!`]: crate::try_init!
812+ /// # Examples
813+ ///
814+ /// ```rust
815+ /// # #![feature(allocator_api)]
816+ /// # #[path = "../examples/error.rs"] mod error; use error::Error;
817+ /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;
818+ /// # use pin_init::InPlaceInit;
819+ /// use pin_init::{init, Init, zeroed};
820+ ///
821+ /// struct BigBuf {
822+ /// small: [u8; 1024 * 1024],
823+ /// }
824+ ///
825+ /// impl BigBuf {
826+ /// fn new() -> impl Init<Self> {
827+ /// init!(Self {
828+ /// small <- zeroed(),
829+ /// })
830+ /// }
831+ /// }
832+ /// # let _ = Box::init(BigBuf::new());
833+ /// ```
776834// For a detailed example of how this macro works, see the module documentation of the hidden
777- // module `__internal ` inside of `init/__internal .rs`.
835+ // module `macros ` inside of `macros .rs`.
778836#[ macro_export]
779837macro_rules! init {
780838 ( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -804,7 +862,9 @@ macro_rules! init {
804862/// ```rust,ignore
805863/// # #![feature(allocator_api)]
806864/// # use core::alloc::AllocError;
807- /// use pin_init::*;
865+ /// # use pin_init::InPlaceInit;
866+ /// use pin_init::{try_init, Init, zeroed};
867+ ///
808868/// struct BigBuf {
809869/// big: Box<[u8; 1024 * 1024 * 1024]>,
810870/// small: [u8; 1024 * 1024],
@@ -818,10 +878,10 @@ macro_rules! init {
818878/// }? AllocError)
819879/// }
820880/// }
881+ /// # let _ = Box::init(BigBuf::new());
821882/// ```
822- /// [`try_pin_init!`]: crate::try_pin_init
823883// For a detailed example of how this macro works, see the module documentation of the hidden
824- // module `__internal ` inside of `init/__internal .rs`.
884+ // module `macros ` inside of `macros .rs`.
825885#[ macro_export]
826886macro_rules! try_init {
827887 ( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -847,7 +907,8 @@ macro_rules! try_init {
847907///
848908/// This will succeed:
849909/// ```ignore
850- /// use pin_init::assert_pinned;
910+ /// use pin_init::{pin_data, assert_pinned};
911+ ///
851912/// #[pin_data]
852913/// struct MyStruct {
853914/// #[pin]
@@ -859,7 +920,8 @@ macro_rules! try_init {
859920///
860921/// This will fail:
861922/// ```compile_fail,ignore
862- /// use pin_init::assert_pinned;
923+ /// use pin_init::{pin_data, assert_pinned};
924+ ///
863925/// #[pin_data]
864926/// struct MyStruct {
865927/// some_field: u64,
@@ -872,7 +934,9 @@ macro_rules! try_init {
872934/// work around this, you may pass the `inline` parameter to the macro. The `inline` parameter can
873935/// only be used when the macro is invoked from a function body.
874936/// ```ignore
875- /// use pin_init::assert_pinned;
937+ /// # use core::pin::Pin;
938+ /// use pin_init::{pin_data, assert_pinned};
939+ ///
876940/// #[pin_data]
877941/// struct Foo<T> {
878942/// #[pin]
@@ -1056,14 +1120,15 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
10561120 ///
10571121 /// ```rust,ignore
10581122 /// # #![expect(clippy::disallowed_names)]
1059- /// use pin_init::{init_from_closure, zeroed};
1123+ /// use pin_init::{init, zeroed, Init};
1124+ ///
10601125 /// struct Foo {
10611126 /// buf: [u8; 1_000_000],
10621127 /// }
10631128 ///
10641129 /// impl Foo {
10651130 /// fn setup(&mut self) {
1066- /// pr_info !("Setting up foo");
1131+ /// println !("Setting up foo");
10671132 /// }
10681133 /// }
10691134 ///
@@ -1302,8 +1367,6 @@ pub trait InPlaceWrite<T> {
13021367/// # Safety
13031368///
13041369/// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
1305- ///
1306- /// [`pinned_drop`]: crate::pinned_drop
13071370pub unsafe trait PinnedDrop : __internal:: HasPinData {
13081371 /// Executes the pinned destructor of this type.
13091372 ///
0 commit comments