Skip to content

Commit f0349ab

Browse files
committed
Add the PinInitable trait, implement it for UnsafeCell.
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. Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
1 parent a4ec26b commit f0349ab

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@
269269
#![forbid(missing_docs, unsafe_op_in_unsafe_fn)]
270270
#![cfg_attr(not(feature = "std"), no_std)]
271271
#![cfg_attr(feature = "alloc", feature(allocator_api))]
272+
#![cfg_attr(feature = "unsafe-pinned", feature(unsafe_pinned))]
272273

273274
use core::{
274275
cell::UnsafeCell,
@@ -1513,3 +1514,38 @@ macro_rules! impl_tuple_zeroable {
15131514
}
15141515

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

0 commit comments

Comments
 (0)