Skip to content

Commit 3680171

Browse files
committed
Add the PinInitable trait.
This trait allows crating `PinInitializers` for wrapper or new-type structs with the inner value structurally pinned, when given the initializer for the inner value. This commit implements this trait for `UnsafeCell` and `MaybeUninit`. Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
1 parent a4ec26b commit 3680171

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,3 +1513,46 @@ 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 structurally [`Pinned`](Pin) value.
1518+
///
1519+
/// This is useful when using wrapper `struct`s like [`UnsafeCell`] or with new-type `struct`s.
1520+
///
1521+
/// ```
1522+
/// # use core::cell::UnsafeCell;
1523+
/// # use pin_init::{pin_data, pin_init, PinInitable};
1524+
///
1525+
/// #[pin_data]
1526+
/// struct Foo {}
1527+
///
1528+
/// #[pin_data]
1529+
/// struct Bar {
1530+
/// #[pin]
1531+
/// content: UnsafeCell<Foo>
1532+
/// };
1533+
///
1534+
/// let foo_initializer = pin_init!(Foo{});
1535+
/// let initializer = pin_init!(Bar {
1536+
/// content <- UnsafeCell::pin_init(foo_initializer)
1537+
/// });
1538+
/// ```
1539+
pub trait PinInitable<T> {
1540+
/// Create an pin-initializer for a [`Self`] containing `T` form the `value_init` initializer.
1541+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E>;
1542+
}
1543+
1544+
impl<T> PinInitable<T> for UnsafeCell<T> {
1545+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
1546+
// SAFETY:
1547+
// `UnsafeCell<T>` has a compatible layout to `T`.
1548+
unsafe { cast_pin_init(value_init) }
1549+
}
1550+
}
1551+
1552+
impl<T> PinInitable<T> for MaybeUninit<T> {
1553+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
1554+
// SAFETY:
1555+
// `MaybeUninit<T>` has a compatible layout to `T`.
1556+
unsafe { cast_pin_init(value_init) }
1557+
}
1558+
}

0 commit comments

Comments
 (0)