summaryrefslogtreecommitdiff
path: root/rust/pin-init/src
diff options
context:
space:
mode:
authorBenno Lossin <benno.lossin@proton.me>2025-04-21 22:17:50 +0000
committerBenno Lossin <benno.lossin@proton.me>2025-05-01 18:08:52 +0200
commit90348980a305cc24a067cc6e606e1c318e277930 (patch)
tree4bcea488916abdf4bc972799b33cb43b743b682d /rust/pin-init/src
parent39051adb070432b283e6c11b2b24937281b9f97f (diff)
rust: pin-init: add `cast_[pin_]init` functions to change the initialized type
These functions cast the given pointer from one type to another. They are particularly useful when initializing transparent wrapper types. Link: https://github.com/Rust-for-Linux/pin-init/pull/39/commits/80c03ddee41b154f1099fd8cc7c2bbd8c80af0ad Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com> Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Diffstat (limited to 'rust/pin-init/src')
-rw-r--r--rust/pin-init/src/lib.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
index 0806c689f693..a880c21d3f09 100644
--- a/rust/pin-init/src/lib.rs
+++ b/rust/pin-init/src/lib.rs
@@ -1216,6 +1216,38 @@ pub const unsafe fn init_from_closure<T: ?Sized, E>(
__internal::InitClosure(f, PhantomData)
}
+/// Changes the to be initialized type.
+///
+/// # Safety
+///
+/// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a
+/// pointer must result in a valid `U`.
+#[expect(clippy::let_and_return)]
+pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> {
+ // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety
+ // requirements.
+ let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::<T>())) };
+ // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
+ // cycle when computing the type returned by this function)
+ res
+}
+
+/// Changes the to be initialized type.
+///
+/// # Safety
+///
+/// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a
+/// pointer must result in a valid `U`.
+#[expect(clippy::let_and_return)]
+pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
+ // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety
+ // requirements.
+ let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::<T>())) };
+ // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
+ // cycle when computing the type returned by this function)
+ res
+}
+
/// An initializer that leaves the memory uninitialized.
///
/// The initializer is a no-op. The `slot` memory is not changed.