summaryrefslogtreecommitdiffstats
path: root/rust/pin-init/src
diff options
context:
space:
mode:
authorBenno Lossin <benno.lossin@proton.me>2025-03-08 11:04:34 +0000
committerMiguel Ojeda <ojeda@kernel.org>2025-03-16 21:59:18 +0100
commit114ca41fe7922ce85fcac30fa2b06b42b4956520 (patch)
treee044016281c0165d1d417bae499d663328cdd746 /rust/pin-init/src
parent578eb8b6db13cd923f1ffa80b9e8d32dcc06d35d (diff)
downloadlinux-114ca41fe7922ce85fcac30fa2b06b42b4956520.tar.gz
linux-114ca41fe7922ce85fcac30fa2b06b42b4956520.tar.bz2
linux-114ca41fe7922ce85fcac30fa2b06b42b4956520.zip
rust: pin-init: move `InPlaceInit` and impls of `InPlaceWrite` into the kernel crate
In order to make pin-init a standalone crate, move kernel-specific code directly into the kernel crate. This includes the `InPlaceInit<T>` trait, its implementations and the implementations of `InPlaceWrite` for `Arc` and `UniqueArc`. All of these use the kernel's error type which will become unavailable in pin-init. Signed-off-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Fiona Behrens <me@kloenk.dev> Tested-by: Andreas Hindborg <a.hindborg@kernel.org> Link: https://lore.kernel.org/r/20250308110339.2997091-9-benno.lossin@proton.me Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/pin-init/src')
-rw-r--r--rust/pin-init/src/lib.rs125
1 files changed, 4 insertions, 121 deletions
diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
index d2176c65b109..f88465e0bb76 100644
--- a/rust/pin-init/src/lib.rs
+++ b/rust/pin-init/src/lib.rs
@@ -10,7 +10,7 @@
//! 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>`], [`KBox<T>`] or any other smart pointer that implements [`InPlaceInit`]).
+//! [`KBox<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,
@@ -212,10 +212,7 @@
//! [`pin_init!`]: crate::pin_init!
use crate::{
- alloc::{AllocError, Flags, KBox},
- error::{self, Error},
- sync::Arc,
- sync::UniqueArc,
+ alloc::KBox,
types::{Opaque, ScopeGuard},
};
use core::{
@@ -891,8 +888,7 @@ macro_rules! assert_pinned {
/// A pin-initializer for the type `T`.
///
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
-/// be [`KBox<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use
-/// the [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
+/// be [`KBox<T>`], [`Arc<T>`] or even the stack (see [`stack_pin_init!`]).
///
/// Also see the [module description](self).
///
@@ -910,7 +906,6 @@ macro_rules! assert_pinned {
/// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
///
/// [`Arc<T>`]: crate::sync::Arc
-/// [`Arc::pin_init`]: crate::sync::Arc::pin_init
#[must_use = "An initializer must be used in order to create its value."]
pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
/// Initializes `slot`.
@@ -976,8 +971,7 @@ where
/// An initializer for `T`.
///
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
-/// be [`KBox<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use
-/// the [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
+/// be [`KBox<T>`], [`Arc<T>`] or even the stack (see [`stack_pin_init!`]). Because
/// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well.
///
/// Also see the [module description](self).
@@ -1238,95 +1232,6 @@ unsafe impl<T, E> PinInit<T, E> for T {
}
}
-/// Smart pointer that can initialize memory in-place.
-pub trait InPlaceInit<T>: Sized {
- /// Pinned version of `Self`.
- ///
- /// If a type already implicitly pins its pointee, `Pin<Self>` is unnecessary. In this case use
- /// `Self`, otherwise just use `Pin<Self>`.
- type PinnedSelf;
-
- /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
- /// type.
- ///
- /// If `T: !Unpin` it will not be able to move afterwards.
- fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
- where
- E: From<AllocError>;
-
- /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
- /// type.
- ///
- /// If `T: !Unpin` it will not be able to move afterwards.
- fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf>
- where
- Error: From<E>,
- {
- // SAFETY: We delegate to `init` and only change the error type.
- let init = unsafe {
- pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
- };
- Self::try_pin_init(init, flags)
- }
-
- /// Use the given initializer to in-place initialize a `T`.
- fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
- where
- E: From<AllocError>;
-
- /// Use the given initializer to in-place initialize a `T`.
- fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
- where
- Error: From<E>,
- {
- // SAFETY: We delegate to `init` and only change the error type.
- let init = unsafe {
- init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
- };
- Self::try_init(init, flags)
- }
-}
-
-impl<T> InPlaceInit<T> for Arc<T> {
- type PinnedSelf = Self;
-
- #[inline]
- fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
- where
- E: From<AllocError>,
- {
- UniqueArc::try_pin_init(init, flags).map(|u| u.into())
- }
-
- #[inline]
- fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
- where
- E: From<AllocError>,
- {
- UniqueArc::try_init(init, flags).map(|u| u.into())
- }
-}
-
-impl<T> InPlaceInit<T> for UniqueArc<T> {
- type PinnedSelf = Pin<Self>;
-
- #[inline]
- fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E>
- where
- E: From<AllocError>,
- {
- UniqueArc::new_uninit(flags)?.write_pin_init(init)
- }
-
- #[inline]
- fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
- where
- E: From<AllocError>,
- {
- UniqueArc::new_uninit(flags)?.write_init(init)
- }
-}
-
/// Smart pointer containing uninitialized memory and that can write a value.
pub trait InPlaceWrite<T> {
/// The type `Self` turns into when the contents are initialized.
@@ -1343,28 +1248,6 @@ pub trait InPlaceWrite<T> {
fn write_pin_init<E>(self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>;
}
-impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
- type Initialized = UniqueArc<T>;
-
- fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
- let slot = self.as_mut_ptr();
- // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
- // slot is valid.
- unsafe { init.__init(slot)? };
- // SAFETY: All fields have been initialized.
- Ok(unsafe { self.assume_init() })
- }
-
- fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
- let slot = self.as_mut_ptr();
- // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
- // slot is valid and will not be moved, because we pin it later.
- unsafe { init.__pinned_init(slot)? };
- // SAFETY: All fields have been initialized.
- Ok(unsafe { self.assume_init() }.into())
- }
-}
-
/// Trait facilitating pinned destruction.
///
/// Use [`pinned_drop`] to implement this trait safely: