// SPDX-License-Identifier: Apache-2.0 OR MIT //! This module contains library internal items. //! //! These items must not be used outside of this crate and the pin-init-internal crate located at //! `../internal`. #![expect(clippy::new_without_default, reason = "private API")] use core::marker::PhantomPinned; use core::ops::Deref; use super::*; /// Zero-sized type used to mark a type as invariant. /// /// This is a polyfill for the [unstable type] in the standard library of the same name. /// /// See the [nomicon] for what subtyping is. See also [this table]. /// /// [unstable type]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomInvariant.html /// [nomicon]: https://doc.rust-lang.org/nomicon/subtyping.html /// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns #[repr(transparent)] pub struct PhantomInvariant(PhantomData T>); impl Clone for PhantomInvariant { #[inline(always)] fn clone(&self) -> Self { *self } } impl Copy for PhantomInvariant {} impl Default for PhantomInvariant { #[inline(always)] fn default() -> Self { Self::new() } } impl PhantomInvariant { #[inline(always)] pub const fn new() -> Self { Self(PhantomData) } } /// Token type to signify successful initialization. /// /// Can only be constructed via the unsafe [`Self::new`] function. The initializer macros use this /// token type to prevent returning `Ok` from an initializer without initializing all fields. pub struct InitOk(()); impl InitOk { /// Creates a new token. /// /// # Safety /// /// This function may only be called from the `init!` macro in `../internal/src/init.rs`. #[inline(always)] pub unsafe fn new() -> Self { Self(()) } } /// This trait is only implemented via the `#[pin_data]` proc-macro. It is used to facilitate /// the pin projections within the initializers. /// /// # Safety /// /// `pin-init` relies on the correctness of the helper functions defined on `PinData`. /// Thus, only the `#[pin_data]` can implement this trait. #[diagnostic::on_unimplemented( message = "`{Self}` cannot be used with `pin_init!` macro", note = "did you forget to add `#[pin_data]` attribute to the struct?" )] pub unsafe trait HasPinData { type PinData; fn __pin_data(_: InitData) -> Self::PinData; } /// This trait is automatically implemented for every type. /// /// It aims to provide type inference help; `PATH::__init_data()` would be able to retrieve an /// instance of `InitData>` without having to mention the generics explicitly. pub trait HasInitData { #[inline] fn __init_data() -> InitData { InitData(PhantomInvariant::new()) } } impl HasInitData for T {} pub struct InitData(PhantomInvariant); impl Clone for InitData { #[inline] fn clone(&self) -> Self { *self } } impl Copy for InitData {} impl InitData { /// Type inference helper function. #[inline(always)] pub fn __make_closure(self, f: F) -> F where F: FnOnce(*mut T, Self) -> Result, { f } #[inline(always)] pub fn __with_lt(self) -> Self { self } } /// Stack initializer helper type. Use [`stack_pin_init`] instead of this primitive. /// /// # Invariants /// /// If `self.is_init` is true, then `self.value` is initialized. /// /// [`stack_pin_init`]: crate::stack_pin_init pub struct StackInit { value: MaybeUninit, is_init: bool, } impl Drop for StackInit { #[inline] fn drop(&mut self) { if self.is_init { // SAFETY: As we are being dropped, we only call this once. And since `self.is_init` is // true, `self.value` is initialized. unsafe { self.value.assume_init_drop() }; } } } impl StackInit { /// Creates a new [`StackInit`] that is uninitialized. Use [`stack_pin_init`] instead of this /// primitive. /// /// [`stack_pin_init`]: crate::stack_pin_init #[inline] pub fn uninit() -> Self { Self { value: MaybeUninit::uninit(), is_init: false, } } /// Initializes the contents and returns the result. #[inline] pub fn init(self: Pin<&mut Self>, init: impl PinInit) -> Result, E> { // SAFETY: We never move out of `this`. let this = unsafe { Pin::into_inner_unchecked(self) }; // The value is currently initialized, so it needs to be dropped before we can reuse // the memory (this is a safety guarantee of `Pin`). if this.is_init { this.is_init = false; // SAFETY: `this.is_init` was true and therefore `this.value` is initialized. unsafe { this.value.assume_init_drop() }; } // SAFETY: The memory slot is valid and this type ensures that it will stay pinned. unsafe { init.__init(this.value.as_mut_ptr())? }; // INVARIANT: `this.value` is initialized above. this.is_init = true; // SAFETY: The slot is now pinned, since we will never give access to `&mut T`. Ok(unsafe { Pin::new_unchecked(this.value.assume_init_mut()) }) } } #[test] #[cfg(feature = "std")] fn stack_init_reuse() { use ::std::{borrow::ToOwned, println, string::String}; use core::pin::pin; #[derive(Debug)] struct Foo { a: usize, b: String, } let mut slot: Pin<&mut StackInit> = pin!(StackInit::uninit()); let value: Result, core::convert::Infallible> = slot.as_mut().init(crate::init!(Foo { a: 42, b: "Hello".to_owned(), })); let value = value.unwrap(); println!("{value:?}"); let value: Result, core::convert::Infallible> = slot.as_mut().init(crate::init!(Foo { a: 24, b: "world!".to_owned(), })); let value = value.unwrap(); println!("{value:?}"); } // Marker types that determines type of `DropGuard`'s let bindings. pub struct Pinned; pub struct Unpinned; /// Represent an uninitialized field. /// /// # Invariants /// /// - `ptr` is valid, properly aligned and points to uninitialized and exclusively accessed memory. /// - If `P` is `Pinned`, then `ptr` is structurally pinned. pub struct Slot { ptr: *mut T, _phantom: PhantomData

, } impl Slot { /// # Safety /// /// - `ptr` is valid, properly aligned and points to uninitialized and exclusively accessed /// memory. /// - If `P` is `Pinned`, then `ptr` is structurally pinned. #[inline(always)] pub unsafe fn new(ptr: *mut T) -> Self { // INVARIANT: Per safety requirement. Self { ptr, _phantom: PhantomData, } } /// Initialize the field by value. #[inline(always)] pub fn write(self, value: T) -> DropGuard where T: Sized, { // SAFETY: `self.ptr` is a valid and aligned pointer for write. unsafe { self.ptr.write(value) } // SAFETY: // - `self.ptr` is valid and properly aligned per type invariant. // - `*self.ptr` is initialized above and the ownership is transferred to the guard. // - If `P` is `Pinned`, `self.ptr` is pinned. unsafe { DropGuard::new(self.ptr) } } } impl Slot { /// Initialize the field. #[inline(always)] pub fn init(self, init: impl Init) -> Result, E> { // SAFETY: // - `self.ptr` is valid and properly aligned. // - when `Err` is returned, we also propagate the error without touching `slot`; // also `self` is consumed so it cannot be touched further. unsafe { init.__init(self.ptr)? }; // SAFETY: // - `self.ptr` is valid and properly aligned per type invariant. // - `*self.ptr` is initialized above and the ownership is transferred to the guard. Ok(unsafe { DropGuard::new(self.ptr) }) } } impl Slot { /// Initialize the field. #[inline(always)] pub fn init(self, init: impl PinInit) -> Result, E> { // SAFETY: // - `self.ptr` is valid and properly aligned. // - when `Err` is returned, we also propagate the error without touching `ptr`; // also `self` is consumed so it cannot be touched further. // - the drop guard will not hand out `&mut` (only `Pin<&mut T>`). unsafe { init.__init(self.ptr)? }; // SAFETY: // - `self.ptr` is valid, properly aligned and pinned per type invariant. // - `*self.ptr` is initialized above and the ownership is transferred to the guard. Ok(unsafe { DropGuard::new(self.ptr) }) } } /// When a value of this type is dropped, it drops a `T`. /// /// Can be forgotten to prevent the drop. /// /// # Invariants /// /// - `ptr` is valid and properly aligned. /// - `*ptr` is initialized and owned by this guard. /// - if `P` is `Pinned`, `ptr` is pinned. pub struct DropGuard { ptr: *mut T, phantom: PhantomData

, } impl DropGuard { /// Creates a drop guard and transfer the ownership of the pointer content. /// /// The ownership is only relinguished if the guard is forgotten via [`core::mem::forget`]. /// /// # Safety /// /// - `ptr` is valid and properly aligned. /// - `*ptr` is initialized, and the ownership is transferred to this guard. /// - if `P` is `Pinned`, `ptr` is pinned. #[inline] pub unsafe fn new(ptr: *mut T) -> Self { // INVARIANT: By safety requirement. Self { ptr, phantom: PhantomData, } } } impl DropGuard { /// Create a let binding for accessor use. #[inline] pub fn let_binding(&mut self) -> &mut T { // SAFETY: Per type invariant. unsafe { &mut *self.ptr } } /// Create a let binding for accessor use in dropck. #[inline] pub fn let_binding_in_dropck(&mut self) -> &mut T { self.let_binding() } } impl DropGuard { /// Create a let binding for accessor use. #[inline] pub fn let_binding(&mut self) -> Pin<&mut T> { // SAFETY: `self.ptr` is valid, properly aligned, initialized, exclusively accessible and // pinned per type invariant. unsafe { Pin::new_unchecked(&mut *self.ptr) } } /// Create a let binding for accessor use in dropck. #[inline] pub fn let_binding_in_dropck(&mut self) -> Pin<&mut T> { self.let_binding() } } impl Drop for DropGuard { #[inline] fn drop(&mut self) { // SAFETY: `self.ptr` is valid, properly aligned and `*self.ptr` is owned by this guard. unsafe { ptr::drop_in_place(self.ptr) } } } pub struct Shared; pub struct Mutable; /// Represent an uninitialized field in a pinned struct that will be referenced by other fields. /// /// # Invariants /// /// - `ptr` is valid, properly aligned and points to uninitialized and exclusively accessed memory /// and will live longer than `'a`. /// - If `P` is `Pinned`, then `ptr` is structurally pinned. pub struct SelfRefSlot<'a, M, P, T: ?Sized> { ptr: *mut T, _phantom: PhantomData<(M, P, &'a mut T)>, } impl<'a, M, P, T: ?Sized> SelfRefSlot<'a, M, P, T> { /// # Safety /// /// - `ptr` is valid, properly aligned and points to uninitialized and exclusively accessed /// memory and will live longer than `'a`. /// - If `P` is `Pinned`, then `ptr` is structurally pinned. #[inline] pub unsafe fn new(ptr: *mut T) -> Self { // INVARIANT: Per safety requirement. Self { ptr, _phantom: PhantomData, } } /// Initialize the field by value. #[inline] pub fn write(self, value: T) -> SelfRefDropGuard<'a, M, P, T> where T: Sized, { // SAFETY: `self.ptr` is a valid and aligned pointer for write. unsafe { self.ptr.write(value) } // SAFETY: // - `self.ptr` is valid, properly aligned and live longer than `'a` per type invariant. // - `*self.ptr` is initialized above and the ownership is transferred to the guard. // - If `P` is `Pinned`, `self.ptr` is pinned. unsafe { SelfRefDropGuard::new(self.ptr) } } } impl<'a, M, T: ?Sized> SelfRefSlot<'a, M, Unpinned, T> { /// Initialize the field. #[inline] pub fn init(self, init: impl Init) -> Result, E> { // SAFETY: // - `self.ptr` is valid and properly aligned. // - when `Err` is returned, we also propagate the error without touching `ptr`; // also `self` is consumed so it cannot be touched further. unsafe { init.__init(self.ptr)? }; // SAFETY: // - `self.ptr` is valid, properly aligned and live longer than `'a` per type invariant. // - `*self.ptr` is initialized above and the ownership is transferred to the guard. Ok(unsafe { SelfRefDropGuard::new(self.ptr) }) } } impl<'a, M, T: ?Sized> SelfRefSlot<'a, M, Pinned, T> { /// Initialize the field. #[inline] pub fn init( self, init: impl PinInit, ) -> Result, E> { // SAFETY: // - `ptr` is valid // - when `Err` is returned, we also propagate the error without touching `ptr`; // also `self` is consumed so it cannot be touched further. // - the drop guard will not hand out `&mut` (only `Pin<&mut T>`). unsafe { init.__init(self.ptr)? }; // SAFETY: // - `self.ptr` is valid, properly aligned and live longer than `'a` per type invariant. // - `*self.ptr` is initialized above and the ownership is transferred to the guard. Ok(unsafe { SelfRefDropGuard::new(self.ptr) }) } } /// When a value of this type is dropped, it drops a `T`. /// /// Can be forgotten to prevent the drop. /// /// # Invariants /// /// - `ptr` is valid, properly aligned and live longer than `'a`. /// - `*ptr` is initialized and owned by this guard. /// - if `P` is `Pinned`, `ptr` is pinned. pub struct SelfRefDropGuard<'a, M, P, T: ?Sized> { ptr: *mut T, phantom: PhantomData<(M, P, &'a mut T)>, } impl<'a, M, P, T: ?Sized> SelfRefDropGuard<'a, M, P, T> { /// Creates a drop guard and transfer the ownership of the pointer content. /// /// The ownership is only relinquished if the guard is forgotten via [`core::mem::forget`]. /// /// # Safety /// /// - `ptr` is valid, properly aligned and live longer than `'a`. /// - `*ptr` is initialized, and the ownership is transferred to this guard. /// - if `P` is `Pinned`, `ptr` is pinned. #[inline] pub unsafe fn new(ptr: *mut T) -> Self { // INVARIANT: By safety requirement. Self { ptr, phantom: PhantomData, } } } impl<'a, T: ?Sized> SelfRefDropGuard<'a, Shared, Unpinned, T> { /// Create a let binding for accessor use. #[inline] pub fn let_binding(&mut self) -> &'a T { // SAFETY: Per type invariant. unsafe { &*self.ptr } } /// Create a let binding for accessor use in dropck. #[inline] pub fn let_binding_in_dropck(&mut self) -> &T { self.let_binding() } } impl<'a, T: ?Sized> SelfRefDropGuard<'a, Shared, Pinned, T> { /// Create a let binding for accessor use. #[inline] pub fn let_binding(&mut self) -> Pin<&'a T> { // SAFETY: `self.ptr` is valid, properly aligned, live longer than `'a`, initialized, // exclusively accessible and pinned per type invariant. unsafe { Pin::new_unchecked(&*self.ptr) } } /// Create a let binding for accessor use in dropck. #[inline] pub fn let_binding_in_dropck(&mut self) -> Pin<&T> { self.let_binding() } } impl<'a, T: ?Sized> SelfRefDropGuard<'a, Mutable, Unpinned, T> { /// Create a let binding for accessor use. #[inline] pub fn let_binding(&mut self) -> &'a mut T { // SAFETY: Per type invariant. unsafe { &mut *self.ptr } } /// Create a let binding for accessor use in dropck. #[inline] pub fn let_binding_in_dropck(&mut self) -> &mut T { self.let_binding() } } impl<'a, T: ?Sized> SelfRefDropGuard<'a, Mutable, Pinned, T> { /// Create a let binding for accessor use. #[inline] pub fn let_binding(&mut self) -> Pin<&'a mut T> { // SAFETY: `self.ptr` is valid, properly aligned, live longer than `'a`, initialized, // exclusively accessible and pinned per type invariant. unsafe { Pin::new_unchecked(&mut *self.ptr) } } #[inline] pub fn let_binding_in_dropck(&mut self) -> Pin<&mut T> { self.let_binding() } } impl Drop for SelfRefDropGuard<'_, M, P, T> { #[inline] fn drop(&mut self) { // SAFETY: `self.ptr` is valid, properly aligned and `*self.ptr` is owned by this guard. unsafe { ptr::drop_in_place(self.ptr) } } } /// Token used by `PinnedDrop` to prevent calling the function without creating this unsafely /// created struct. This is needed, because the `drop` function is safe, but should not be called /// manually. pub struct OnlyCallFromDrop(()); impl OnlyCallFromDrop { /// # Safety /// /// This function should only be called from the [`Drop::drop`] function and only be used to /// delegate the destruction to the pinned destructor [`PinnedDrop::drop`] of the same type. pub unsafe fn new() -> Self { Self(()) } } /// Initializer that always fails. /// /// Used by [`assert_pinned!`]. /// /// [`assert_pinned!`]: crate::assert_pinned pub struct AlwaysFail { _t: PhantomData, } impl AlwaysFail { /// Creates a new initializer that always fails. #[inline] pub fn new() -> Self { Self { _t: PhantomData } } } impl Default for AlwaysFail { #[inline] fn default() -> Self { Self::new() } } // SAFETY: `__init` always fails, which is always okay. unsafe impl PinInit for AlwaysFail { #[inline] unsafe fn __init(self, _slot: *mut T) -> Result<(), ()> { Err(()) } } /// Polyfill of `FnOnce` trait to be able to reference output via associated type. pub trait FnOutput { type Output; } macro_rules! impl_fn_output { () => {}; ($ret:ident, $($arg:ident,)*) => { impl FnOutput<($($arg,)*)> for This where This: FnOnce($($arg,)*) -> $ret, { type Output = $ret; } impl_fn_output!($($arg,)*); }; } impl_fn_output!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U,); /// Lifetime erasure facility. /// /// Say we have `exists<'a, 'b> Foo<'a, 'b>` and we want to store it. There's no concrete /// lifetimes we can use, so we want to erase the lifetime. /// /// Such erasure can be encoded as /// `Erased fn(&'a ()) -> for<'b> fn(&'b()) -> (Foo<'a, 'b>,)`. /// /// This can be considered the stable version of Rust's `unsafe_binder` feature, without the /// no-drop-glue requirement. #[repr(transparent)] #[allow(private_bounds)] pub struct Erase(F::Erased); /// Helper trait to resolve the erased lifetime. trait EraseLt { type Erased; } impl EraseLt for (T,) { type Erased = T; } impl EraseLt for T where T: for<'a> FnOutput<(&'a (),), Output: EraseLt>, { type Erased = <>::Output as EraseLt>::Erased; } // The default `Send` and `Sync` are not sufficient, because one can use lifetime specialization to // implement `Send` or `Sync` for a concrete instance of lifetime. Use HRTB to ensure that the type // will only implement `Send` or `Sync` if it's implemented for *all* erased lifetimes. // SAFETY: Trivial, no lifetime to erase. unsafe impl Send for Erase<(T,)> {} // SAFETY: If we erased a lifetime, then the type needs to be `Send` for across *all* that // lifetimes. unsafe impl Send for Erase where F: for<'a> FnOutput<(&'a (),), Output: EraseLt>, for<'a> Erase<>::Output>: Send, { } // SAFETY: Trivial, no lifetime to erase. unsafe impl Sync for Erase<(T,)> {} // SAFETY: If we erased a lifetime, then the type needs to be `Sync` for across *all* that // lifetimes. unsafe impl Sync for Erase where F: for<'a> FnOutput<(&'a (),), Output: EraseLt>, for<'a> Erase<>::Output>: Sync, { } /// Wrapper for borrowed fields. /// /// This should be switched to `UnsafePinned` when it is stable. /// NOTE: This type needs to be covariant; Rust's 1.89+'s `UnsafePinned` is invariant. #[repr(transparent)] pub struct Borrowed(PhantomInvariant

, PhantomPinned, T); // Lifetimes not needed by drop glue are considered by Rust's drop check to be considered // `#[may_dangle]`. In case for a self-referential struct, we may have fields which need lifetime of // borrowed fields in their drop glue, so compiler's automatic check is insufficient. // // Code like this: // ``` // #[pin_data] // struct SelfRef<'a> { // borrow: PrintOnDrop<&'owner str>, // owner: &'a str, // } // ``` // may access `owner` during the drop, however Rust will determine that since `'a` only is used in // `owner`, the `'a` lifetime may dangle during drop. // // This is undesirable for pin-init self references, because `&'a str` could be coerecd to // `&'owner str` and this could further coerce if there're implied outlives, e.g. // `&'earlier_field &'owner ()` would allow `&'owner str` to further coerce to `&'earlier_field`. // // Thus, if any self-referential field require field lifetime access in `Drop` impl, we would need // to ensure that the all generic parameters visible by self-referential fields would strictly // outlive the struct. And this can be done by a simple `Drop` impl that does nothing. Without a // dropck eye patch, presence of `Drop` impl, albeit empty, tells the drop check that the strict // outlive relation is needed. impl Drop for Borrowed { #[inline(always)] fn drop(&mut self) {} } impl Deref for Borrowed { type Target = T; #[inline(always)] fn deref(&self) -> &T { &self.2 } } /// An alias of `PhantomData` but with a name to aid user in case of misuse. pub struct NotVisible(PhantomData); impl NotVisible { #[inline(always)] pub fn new() -> Self { Self(PhantomData) } } /// Marker type to capture outlive bounds coming from existential lifetimes. pub struct ExistLt<'a>(PhantomData<&'a ()>); // Dummy `Drop`, same reason as `Borrowed`. impl Drop for ExistLt<'_> { #[inline(always)] fn drop(&mut self) {} } /// Type that allows additional `PhantomData` to be attached. /// /// This allows changing variance of types without introducing additional fields. #[repr(transparent)] pub struct WithPhantom(PhantomData

, T);