Skip to content

Commit 2f7c738

Browse files
onestackedBennoLossin
authored andcommitted
rust: pin-init: Add the Wrapper trait.
This trait allows creating `PinInitializers` for wrapper or new-type structs with the inner value structurally pinned, when given the initializer for the inner value. Implement this trait for `UnsafeCell` and `MaybeUninit`. Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com> Link: Rust-for-Linux/pin-init@3ab4db0 [ Reworded commit message into imperative mode, fixed typo and fixed commit authorship. - Benno ] Signed-off-by: Benno Lossin <benno.lossin@proton.me>
1 parent 9034898 commit 2f7c738

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

rust/pin-init/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,3 +1513,47 @@ macro_rules! impl_tuple_zeroable {
15131513
}
15141514

15151515
impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J);
1516+
1517+
/// This trait allows creating an instance of `Self` which contains exactly one
1518+
/// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).
1519+
///
1520+
/// This is useful when using wrapper `struct`s like [`UnsafeCell`] or with new-type `struct`s.
1521+
///
1522+
/// # Examples
1523+
///
1524+
/// ```
1525+
/// # use core::cell::UnsafeCell;
1526+
/// # use pin_init::{pin_data, pin_init, Wrapper};
1527+
///
1528+
/// #[pin_data]
1529+
/// struct Foo {}
1530+
///
1531+
/// #[pin_data]
1532+
/// struct Bar {
1533+
/// #[pin]
1534+
/// content: UnsafeCell<Foo>
1535+
/// };
1536+
///
1537+
/// let foo_initializer = pin_init!(Foo{});
1538+
/// let initializer = pin_init!(Bar {
1539+
/// content <- UnsafeCell::pin_init(foo_initializer)
1540+
/// });
1541+
/// ```
1542+
pub trait Wrapper<T> {
1543+
/// Create an pin-initializer for a [`Self`] containing `T` form the `value_init` initializer.
1544+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E>;
1545+
}
1546+
1547+
impl<T> Wrapper<T> for UnsafeCell<T> {
1548+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
1549+
// SAFETY: `UnsafeCell<T>` has a compatible layout to `T`.
1550+
unsafe { cast_pin_init(value_init) }
1551+
}
1552+
}
1553+
1554+
impl<T> Wrapper<T> for MaybeUninit<T> {
1555+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
1556+
// SAFETY: `MaybeUninit<T>` has a compatible layout to `T`.
1557+
unsafe { cast_pin_init(value_init) }
1558+
}
1559+
}

0 commit comments

Comments
 (0)