1
1
// SPDX-License-Identifier: Apache-2.0 OR MIT
2
2
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.
4
6
//!
5
7
//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
6
8
//! overflow.
7
9
//!
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
+ //!
8
35
//! # Overview
9
36
//!
10
37
//! To initialize a `struct` with an in-place constructor you will need two things:
17
44
//! - a custom function/macro returning an in-place constructor provided by someone else,
18
45
//! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
19
46
//!
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.
23
50
//!
24
51
//! # Examples
25
52
//!
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
+ //!
26
58
//! ## Using the [`pin_init!`] macro
27
59
//!
28
60
//! If you want to use [`PinInit`], then you will have to annotate your `struct` with
36
68
//! # #![feature(allocator_api)]
37
69
//! # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;
38
70
//! # use core::pin::Pin;
39
- //! use pin_init::* ;
71
+ //! use pin_init::{pin_data, pin_init, InPlaceInit} ;
40
72
//!
41
73
//! #[pin_data]
42
74
//! struct Foo {
80
112
//!
81
113
//! ## Using a custom function/macro that returns an initializer
82
114
//!
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.
85
117
//!
86
118
//! ```rust,ignore
87
119
//! # #![feature(allocator_api)]
132
164
//!
133
165
//! ```rust,ignore
134
166
//! # #![feature(extern_types)]
135
- //! use pin_init::* ;
167
+ //! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure} ;
136
168
//! use core::{
137
169
//! ptr::addr_of_mut,
138
170
//! marker::PhantomPinned,
141
173
//! mem::MaybeUninit,
142
174
//! };
143
175
//! mod bindings {
176
+ //! #[repr(C)]
177
+ //! pub struct foo {
178
+ //! /* fields from C ... */
179
+ //! }
144
180
//! extern "C" {
145
- //! pub type foo;
146
181
//! pub fn init_foo(ptr: *mut foo);
147
182
//! pub fn destroy_foo(ptr: *mut foo);
148
183
//! #[must_use = "you must check the error return code"]
200
235
//! }
201
236
//! ```
202
237
//!
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
203
242
//! [pinning]: https://doc.rust-lang.org/std/pin/index.html
204
243
//! [structurally pinned fields]:
205
244
//! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
214
253
) ]
215
254
#![ cfg_attr( not( kernel) , doc = "[`Arc<T>`]: alloc::alloc::sync::Arc" ) ]
216
255
#![ 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/
222
260
223
261
#![ cfg_attr( not( RUSTC_LINT_REASONS_IS_STABLE ) , feature( lint_reasons) ) ]
224
262
#![ cfg_attr(
@@ -404,8 +442,6 @@ pub use ::pin_init_internal::Zeroable;
404
442
/// A normal `let` binding with optional type annotation. The expression is expected to implement
405
443
/// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error
406
444
/// type, then use [`stack_try_pin_init!`].
407
- ///
408
- /// [`stack_try_pin_init!`]: crate::stack_try_pin_init!
409
445
#[ macro_export]
410
446
macro_rules! stack_pin_init {
411
447
( let $var: ident $( : $t: ty) ? = $val: expr) => {
@@ -542,10 +578,10 @@ macro_rules! stack_try_pin_init {
542
578
///
543
579
/// # Init-functions
544
580
///
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.
549
585
///
550
586
/// To create an initializer function, simply declare it like this:
551
587
///
@@ -674,22 +710,22 @@ macro_rules! stack_try_pin_init {
674
710
/// #[pin]
675
711
/// pin: PhantomPinned,
676
712
/// }
677
- /// pin_init!(&this in Buf {
713
+ ///
714
+ /// let init = pin_init!(&this in Buf {
678
715
/// buf: [0; 64],
679
716
/// // SAFETY: TODO.
680
717
/// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },
681
718
/// pin: PhantomPinned,
682
719
/// });
683
- /// pin_init!(Buf {
720
+ /// let init = pin_init!(Buf {
684
721
/// buf: [1; 64],
685
722
/// ..Zeroable::zeroed()
686
723
/// });
687
724
/// ```
688
725
///
689
- /// [`try_pin_init!`]: crate::try_pin_init
690
726
/// [`NonNull<Self>`]: core::ptr::NonNull
691
727
// 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`.
693
729
#[ macro_export]
694
730
macro_rules! pin_init {
695
731
( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -719,7 +755,8 @@ macro_rules! pin_init {
719
755
/// ```rust,ignore
720
756
/// # #![feature(allocator_api)]
721
757
/// # #[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
+ ///
723
760
/// #[pin_data]
724
761
/// struct BigBuf {
725
762
/// big: Box<[u8; 1024 * 1024 * 1024]>,
@@ -730,7 +767,7 @@ macro_rules! pin_init {
730
767
/// impl BigBuf {
731
768
/// fn new() -> impl PinInit<Self, Error> {
732
769
/// try_pin_init!(Self {
733
- /// big: Box::init(init:: zeroed())?,
770
+ /// big: Box::init(zeroed())?,
734
771
/// small: [0; 1024 * 1024],
735
772
/// ptr: core::ptr::null_mut(),
736
773
/// }? Error)
@@ -739,7 +776,7 @@ macro_rules! pin_init {
739
776
/// # let _ = Box::pin_init(BigBuf::new());
740
777
/// ```
741
778
// 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`.
743
780
#[ macro_export]
744
781
macro_rules! try_pin_init {
745
782
( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -772,9 +809,30 @@ macro_rules! try_pin_init {
772
809
/// This initializer is for initializing data in-place that might later be moved. If you want to
773
810
/// pin-initialize, use [`pin_init!`].
774
811
///
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
+ /// ```
776
834
// 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`.
778
836
#[ macro_export]
779
837
macro_rules! init {
780
838
( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -804,7 +862,9 @@ macro_rules! init {
804
862
/// ```rust,ignore
805
863
/// # #![feature(allocator_api)]
806
864
/// # use core::alloc::AllocError;
807
- /// use pin_init::*;
865
+ /// # use pin_init::InPlaceInit;
866
+ /// use pin_init::{try_init, Init, zeroed};
867
+ ///
808
868
/// struct BigBuf {
809
869
/// big: Box<[u8; 1024 * 1024 * 1024]>,
810
870
/// small: [u8; 1024 * 1024],
@@ -818,10 +878,10 @@ macro_rules! init {
818
878
/// }? AllocError)
819
879
/// }
820
880
/// }
881
+ /// # let _ = Box::init(BigBuf::new());
821
882
/// ```
822
- /// [`try_pin_init!`]: crate::try_pin_init
823
883
// 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`.
825
885
#[ macro_export]
826
886
macro_rules! try_init {
827
887
( $( & $this: ident in) ? $t: ident $( :: <$( $generics: ty) ,* $( , ) ?>) ? {
@@ -847,7 +907,8 @@ macro_rules! try_init {
847
907
///
848
908
/// This will succeed:
849
909
/// ```ignore
850
- /// use pin_init::assert_pinned;
910
+ /// use pin_init::{pin_data, assert_pinned};
911
+ ///
851
912
/// #[pin_data]
852
913
/// struct MyStruct {
853
914
/// #[pin]
@@ -859,7 +920,8 @@ macro_rules! try_init {
859
920
///
860
921
/// This will fail:
861
922
/// ```compile_fail,ignore
862
- /// use pin_init::assert_pinned;
923
+ /// use pin_init::{pin_data, assert_pinned};
924
+ ///
863
925
/// #[pin_data]
864
926
/// struct MyStruct {
865
927
/// some_field: u64,
@@ -872,7 +934,9 @@ macro_rules! try_init {
872
934
/// work around this, you may pass the `inline` parameter to the macro. The `inline` parameter can
873
935
/// only be used when the macro is invoked from a function body.
874
936
/// ```ignore
875
- /// use pin_init::assert_pinned;
937
+ /// # use core::pin::Pin;
938
+ /// use pin_init::{pin_data, assert_pinned};
939
+ ///
876
940
/// #[pin_data]
877
941
/// struct Foo<T> {
878
942
/// #[pin]
@@ -1056,14 +1120,15 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
1056
1120
///
1057
1121
/// ```rust,ignore
1058
1122
/// # #![expect(clippy::disallowed_names)]
1059
- /// use pin_init::{init_from_closure, zeroed};
1123
+ /// use pin_init::{init, zeroed, Init};
1124
+ ///
1060
1125
/// struct Foo {
1061
1126
/// buf: [u8; 1_000_000],
1062
1127
/// }
1063
1128
///
1064
1129
/// impl Foo {
1065
1130
/// fn setup(&mut self) {
1066
- /// pr_info !("Setting up foo");
1131
+ /// println !("Setting up foo");
1067
1132
/// }
1068
1133
/// }
1069
1134
///
@@ -1302,8 +1367,6 @@ pub trait InPlaceWrite<T> {
1302
1367
/// # Safety
1303
1368
///
1304
1369
/// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
1305
- ///
1306
- /// [`pinned_drop`]: crate::pinned_drop
1307
1370
pub unsafe trait PinnedDrop : __internal:: HasPinData {
1308
1371
/// Executes the pinned destructor of this type.
1309
1372
///
0 commit comments