Skip to content

Commit 9034898

Browse files
committed
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: Rust-for-Linux/pin-init@80c03dd Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com> Signed-off-by: Benno Lossin <benno.lossin@proton.me>
1 parent 39051ad commit 9034898

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

rust/pin-init/src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,38 @@ pub const unsafe fn init_from_closure<T: ?Sized, E>(
12161216
__internal::InitClosure(f, PhantomData)
12171217
}
12181218

1219+
/// Changes the to be initialized type.
1220+
///
1221+
/// # Safety
1222+
///
1223+
/// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a
1224+
/// pointer must result in a valid `U`.
1225+
#[expect(clippy::let_and_return)]
1226+
pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl PinInit<U, E> {
1227+
// SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety
1228+
// requirements.
1229+
let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::<T>())) };
1230+
// FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
1231+
// cycle when computing the type returned by this function)
1232+
res
1233+
}
1234+
1235+
/// Changes the to be initialized type.
1236+
///
1237+
/// # Safety
1238+
///
1239+
/// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a
1240+
/// pointer must result in a valid `U`.
1241+
#[expect(clippy::let_and_return)]
1242+
pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
1243+
// SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety
1244+
// requirements.
1245+
let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::<T>())) };
1246+
// FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
1247+
// cycle when computing the type returned by this function)
1248+
res
1249+
}
1250+
12191251
/// An initializer that leaves the memory uninitialized.
12201252
///
12211253
/// The initializer is a no-op. The `slot` memory is not changed.

0 commit comments

Comments
 (0)