Lines Matching +full:foo +full:- +full:supply

1 // SPDX-License-Identifier: Apache-2.0 OR MIT
3 //! Library to safely and fallibly initialize pinned `struct`s using in-place constructors.
7 //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
10 //! This library's main use-case is in [Rust-for-Linux]. Although this version can be used
13 //! There are cases when you want to in-place initialize a struct. For example when it is very big
18 //! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>.
20 //! This library allows you to do in-place initialization safely.
28 //! [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html
30 //! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler.
32 //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std
35 //! ## Nightly needed for `unsafe-pinned` feature
38 //! This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735)
43 //! To initialize a `struct` with an in-place constructor you will need two things:
44 //! - an in-place constructor,
45 //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
48 //! To get an in-place constructor there are generally three options:
49 //! - directly creating an in-place constructor using the [`pin_init!`] macro,
50 //! - a custom function/macro returning an in-place constructor provided by someone else,
51 //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
53 //! Aside from pinned initialization, this library also supports in-place construction without
68 //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via
70 //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place.
80 //! struct Foo {
86 //! let foo = pin_init!(Foo {
87 //! a <- CMutex::new(42),
90 //! # let _ = Box::pin_init(foo);
93 //! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like
94 //! (or just the stack) to actually initialize a `Foo`:
104 //! # struct Foo {
110 //! # let foo = pin_init!(Foo {
111 //! # a <- CMutex::new(42),
114 //! let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo);
121 //! Many types that use this library supply a function/macro that returns an initializer, because
148 //! fn new() -> impl PinInit<Self, Error> {
150 //! status <- CMutex::new(0),
164 //! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so
166 //! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so
167 //! you need to take care to clean up anything if your initialization fails mid-way,
168 //! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of
183 //! pub struct foo {
187 //! pub fn init_foo(ptr: *mut foo);
188 //! pub fn destroy_foo(ptr: *mut foo);
190 //! pub fn enable_foo(ptr: *mut foo, flags: u32) -> i32;
196 //! /// `foo` is always initialized
202 //! foo: UnsafeCell<MaybeUninit<bindings::foo>>,
206 //! pub fn new(flags: u32) -> impl PinInit<Self, i32> {
208 //! // - when the closure returns `Ok(())`, then it has successfully initialized and
209 //! // enabled `foo`,
210 //! // - when it returns `Err(e)`, then it has cleaned up before
214 //! let foo = addr_of_mut!((*slot).foo);
215 //! let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>();
217 //! // Initialize the `foo`
218 //! bindings::init_foo(foo);
221 //! let err = bindings::enable_foo(foo, flags);
223 //! // Enabling has failed, first clean up the foo and then return the error.
224 //! bindings::destroy_foo(foo);
238 //! // SAFETY: Since `foo` is initialized, destroying is safe.
239 //! unsafe { bindings::destroy_foo(self.foo.get().cast::<bindings::foo>()) };
248 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html
250 //! https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning
262 //! [`impl PinInit<Foo>`]: crate::PinInit
265 //! [Rust-for-Linux]: https://rust-for-linux.com/
279 all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED),
306 /// [pin-project-lite](https://crates.io/crates/pin-project-lite).
310 /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,
469 /// struct Foo {
480 /// stack_pin_init!(let foo = pin_init!(Foo {
481 /// a <- CMutex::new(42),
486 /// let foo: Pin<&mut Foo> = foo;
487 /// println!("a: {}", &*foo.a.lock());
521 /// struct Foo {
531 /// stack_try_pin_init!(let foo: Foo = try_pin_init!(Foo {
532 /// a <- CMutex::new(42),
537 /// let foo = foo.unwrap();
538 /// println!("a: {}", &*foo.a.lock());
548 /// struct Foo {
558 /// stack_try_pin_init!(let foo: Foo =? try_pin_init!(Foo {
559 /// a <- CMutex::new(42),
564 /// println!("a: {}", &*foo.a.lock());
587 /// Construct an in-place, pinned initializer for `struct`s.
598 /// struct Foo {
608 /// # fn demo() -> impl PinInit<Foo> {
611 /// let initializer = pin_init!(Foo {
629 /// # Init-functions
642 /// # struct Foo {
650 /// impl Foo {
651 /// fn new() -> impl PinInit<Self> {
662 /// Users of `Foo` can now create it like this:
669 /// # struct Foo {
677 /// # impl Foo {
678 /// # fn new() -> impl PinInit<Self> {
687 /// let foo = Box::pin_init(Foo::new());
696 /// # struct Foo {
704 /// # impl Foo {
705 /// # fn new() -> impl PinInit<Self> {
717 /// foo1: Foo,
719 /// foo2: Foo,
724 /// fn new(other: u32) -> impl PinInit<Self> {
726 /// foo1 <- Foo::new(),
727 /// foo2 <- Foo::new(),
734 /// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`.
735 /// This signifies that the given field is initialized in-place. As with `struct` initializers, just
736 /// writing the field (in this case `other`) without `:` or `<-` means `other: other,`.
742 /// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
743 /// - You can use `_: { /* run any user-code here */ },` anywhere where you can place fields in
745 /// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
747 /// - Using struct update syntax one can place `..Zeroable::init_zeroed()` at the very end of the
792 /// Construct an in-place, fallible pinned initializer for `struct`s.
820 /// fn new() -> impl PinInit<Self, Error> {
850 /// Construct an in-place initializer for `struct`s.
856 /// - `unsafe` code must guarantee either full initialization or return an error and allow
858 /// - the fields are initialized in the order given in the initializer.
859 /// - no references to fields are allowed to be created inside of the initializer.
861 /// This initializer is for initializing data in-place that might later be moved. If you want to
862 /// pin-initialize, use [`pin_init!`].
878 /// fn new() -> impl Init<Self> {
880 /// small <- init_zeroed(),
899 /// Construct an in-place fallible initializer for `struct`s.
907 /// - `unsafe` code must guarantee either full initialization or return an error and allow
909 /// - the fields are initialized in the order given in the initializer.
910 /// - no references to fields are allowed to be created inside of the initializer.
926 /// fn new() -> impl Init<Self, AllocError> {
993 /// struct Foo<T> {
998 /// impl<T> Foo<T> {
999 /// fn project_this(self: Pin<&mut Self>) -> Pin<&mut T> {
1000 /// assert_pinned!(Foo<T>, elem, T, inline);
1026 /// A pin-initializer for the type `T`.
1039 /// - returns `Ok(())` if it initialized every field of `slot`,
1040 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1041 /// - `slot` can be deallocated without UB occurring,
1042 /// - `slot` does not need to be dropped,
1043 /// - `slot` is not partially initialized.
1044 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1062 /// - `slot` is a valid pointer to uninitialized memory.
1063 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
1065 /// - `slot` will not move until it is dropped, i.e. it will be pinned.
1066 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>;
1086 fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
1088 F: FnOnce(Pin<&mut T>) -> Result<(), E>,
1098 // - returns `Ok(())` on successful initialization,
1099 // - returns `Err(err)` on error and in this case `slot` will be dropped.
1100 // - considers `slot` pinned.
1104 F: FnOnce(Pin<&mut T>) -> Result<(), E>,
1106 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
1132 /// - returns `Ok(())` if it initialized every field of `slot`,
1133 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1134 /// - `slot` can be deallocated without UB occurring,
1135 /// - `slot` does not need to be dropped,
1136 /// - `slot` is not partially initialized.
1137 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1161 /// - `slot` is a valid pointer to uninitialized memory.
1162 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
1164 unsafe fn __init(self, slot: *mut T) -> Result<(), E>;
1177 /// struct Foo {
1181 /// impl Foo {
1183 /// println!("Setting up foo");
1187 /// let foo = init!(Foo {
1188 /// buf <- init_zeroed()
1189 /// }).chain(|foo| {
1190 /// foo.setup();
1194 fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
1196 F: FnOnce(&mut T) -> Result<(), E>,
1206 // - returns `Ok(())` on successful initialization,
1207 // - returns `Err(err)` on error and in this case `slot` will be dropped.
1211 F: FnOnce(&mut T) -> Result<(), E>,
1213 unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
1227 F: FnOnce(&mut T) -> Result<(), E>,
1229 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
1240 /// - returns `Ok(())` if it initialized every field of `slot`,
1241 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1242 /// - `slot` can be deallocated without UB occurring,
1243 /// - `slot` does not need to be dropped,
1244 /// - `slot` is not partially initialized.
1245 /// - may assume that the `slot` does not move if `T: !Unpin`,
1246 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1249 f: impl FnOnce(*mut T) -> Result<(), E>,
1250 ) -> impl PinInit<T, E> {
1259 /// - returns `Ok(())` if it initialized every field of `slot`,
1260 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1261 /// - `slot` can be deallocated without UB occurring,
1262 /// - `slot` does not need to be dropped,
1263 /// - `slot` is not partially initialized.
1264 /// - the `slot` may move after initialization.
1265 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1268 f: impl FnOnce(*mut T) -> Result<(), E>,
1269 ) -> impl Init<T, E> {
1277 /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a
1280 pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> {
1284 // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
1293 /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a
1296 pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
1300 // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
1307 /// The initializer is a no-op. The `slot` memory is not changed.
1309 pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> {
1325 mut make_init: impl FnMut(usize) -> I,
1326 ) -> impl Init<[T; N], E>
1368 mut make_init: impl FnMut(usize) -> I,
1369 ) -> impl PinInit<[T; N], E>
1397 unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible> {
1407 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible> {
1415 // - `Ok(())`, `slot` was initialized and all pinned invariants of `T` are upheld.
1416 // - `Err(err)`, slot was not written to.
1418 unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
1426 // - `Ok(())`, `slot` was initialized and all pinned invariants of `T` are upheld.
1427 // - `Err(err)`, slot was not written to.
1429 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
1444 fn write_init<E>(self, init: impl Init<T, E>) -> Result<Self::Initialized, E>;
1446 /// Use the given pin-initializer to write a value into `self`.
1449 fn write_pin_init<E>(self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>;
1462 /// struct Foo {
1468 /// impl PinnedDrop for Foo {
1470 /// println!("Foo is being dropped!");
1477 /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
1485 /// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute
1505 fn init_zeroed() -> impl Init<Self>
1532 fn zeroed() -> Self
1552 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1555 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1558 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1565 pub fn init_zeroed<T: Zeroable>() -> impl Init<T> {
1596 pub const fn zeroed<T: Zeroable>() -> T {
1619 // <https://doc.rust-lang.org/stable/nomicon/exotic-sizes.html#empty-types>. The Rust Reference
1621 // <https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html>.
1633 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>).
1675 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1676 unsafe impl<$ret, $($rest),*> ZeroableOption for $($prefix)* fn($($rest),*) -> $ret {}
1684 /// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).
1686 /// This is useful when using wrapper `struct`s like [`UnsafeCell`] or with new-type `struct`s.
1695 /// struct Foo {}
1700 /// content: UnsafeCell<Foo>
1703 /// let foo_initializer = pin_init!(Foo{});
1705 /// content <- UnsafeCell::pin_init(foo_initializer)
1709 /// Creates an pin-initializer for a [`Self`] containing `T` from the `value_init` initializer.
1710 fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E>;
1714 fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
1721 fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
1727 #[cfg(all(feature = "unsafe-pinned", CONFIG_RUSTC_HAS_UNSAFE_PINNED))]
1729 fn pin_init<E>(init: impl PinInit<T, E>) -> impl PinInit<Self, E> {