|
269 | 269 | #![forbid(missing_docs, unsafe_op_in_unsafe_fn)] |
270 | 270 | #![cfg_attr(not(feature = "std"), no_std)] |
271 | 271 | #![cfg_attr(feature = "alloc", feature(allocator_api))] |
| 272 | +#![cfg_attr(feature = "unsafe-pinned", feature(unsafe_pinned))] |
272 | 273 |
|
273 | 274 | use core::{ |
274 | 275 | cell::UnsafeCell, |
@@ -1481,3 +1482,30 @@ macro_rules! impl_tuple_zeroable { |
1481 | 1482 | } |
1482 | 1483 |
|
1483 | 1484 | impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J); |
| 1485 | + |
| 1486 | +/// Trait for creating a [PinInitialized](PinInit) wrapper containing `T`. |
| 1487 | +pub trait TryPinInitWrapper<T: ?Sized> { |
| 1488 | + /// Create an pin-initializer for a [`Self`] containing `T` form the `value` initializer. |
| 1489 | + fn try_pin_init<E>(value: impl PinInit<T, E>) -> impl PinInit<Self, E>; |
| 1490 | +} |
| 1491 | + |
| 1492 | +impl<T: ?Sized> TryPinInitWrapper<T> for UnsafeCell<T> { |
| 1493 | + fn try_pin_init<E>(value: impl PinInit<T, E>) -> impl PinInit<Self, E> { |
| 1494 | + // SAFETY: |
| 1495 | + // - In case of an error in `value` the error is returned, otherwise `slot` is fully |
| 1496 | + // initialized, since `self.value` is initialized and `_pin` is a zero sized type. |
| 1497 | + // - The `Pin` invariants of `self.value` are upheld, since no moving occurs. |
| 1498 | + unsafe { pin_init_from_closure(move |slot| value.__pinned_init(Self::raw_get(slot))) } |
| 1499 | + } |
| 1500 | +} |
| 1501 | + |
| 1502 | +#[cfg(feature = "unsafe-pinned")] |
| 1503 | +impl<T: ?Sized> TryPinInitWrapper<T> for core::pin::UnsafePinned<T> { |
| 1504 | + fn try_pin_init<E>(value: impl PinInit<T, E>) -> impl PinInit<Self, E> { |
| 1505 | + // SAFETY: |
| 1506 | + // - In case of an error in `value` the error is returned, otherwise `slot` is fully |
| 1507 | + // initialized, since `self.value` is initialized and `_pin` is a zero sized type. |
| 1508 | + // - The `Pin` invariants of `self.value` are upheld, since no moving occurs. |
| 1509 | + unsafe { pin_init_from_closure(move |slot| value.__pinned_init(Self::raw_get_mut(slot))) } |
| 1510 | + } |
| 1511 | +} |
0 commit comments