Skip to content

Commit 196dd27

Browse files
committed
Add TryPinInitWrapper trait.
Implement it for `UnsafeCell` and `UnsafePinned` (unsafe-pinned feature is enabled. Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
1 parent fc6169f commit 196dd27

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pin-init-internal = { path = "./internal", version = "=0.0.5" }
2121
default = ["std", "alloc"]
2222
std = []
2323
alloc = []
24+
unsafe-pinned = []
2425

2526
[build-dependencies]
2627
rustc_version = "0.4"
@@ -34,7 +35,11 @@ prettyplease = { version = "0.2", features = ["verbatim"] }
3435

3536
[lints.rust]
3637
non_ascii_idents = "deny"
37-
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(NO_UI_TESTS)', 'cfg(NO_ALLOC_FAIL_TESTS)', 'cfg(kernel)'] }
38+
unexpected_cfgs = { level = "warn", check-cfg = [
39+
'cfg(NO_UI_TESTS)',
40+
'cfg(NO_ALLOC_FAIL_TESTS)',
41+
'cfg(kernel)',
42+
] }
3843
unsafe_op_in_unsafe_fn = "deny"
3944
unused_attributes = "deny"
4045
warnings = "deny"

src/lib.rs

Lines changed: 28 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,
@@ -1481,3 +1482,30 @@ macro_rules! impl_tuple_zeroable {
14811482
}
14821483

14831484
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

Comments
 (0)