pin_init/
lib.rs

1#![no_std]
2#![cfg_attr(doc_cfg, feature(doc_cfg))]
3#![cfg_attr(feature = "alloc_try_pin_with", feature(allocator_api))]
4#![warn(unsafe_op_in_unsafe_fn)]
5#![allow(clippy::new_without_default)]
6#![allow(clippy::should_implement_trait)]
7#![allow(clippy::needless_lifetimes)]
8
9//! Safe pinned-initialization in Rust.
10//!
11//! # The problem
12//! Rust's `Pin` provides sufficient guarantee for C interop and self-referential
13//! structs -- their address are stable once they're pinned and the destructor is
14//! guaranteed to be called before the memory region can be deallocated.
15//!
16//! The problem here is "once pinned". `Pin` expects the type can be created without
17//! pinning, and can be pinned later before any operations. This is okay for
18//! `Generator`s, which are created without any self references, and self references
19//! can only be created when polling the generator. For other types, e.g.
20//! `pthread_mutex_t`, it is expected to be pinned from the start.
21//!
22//! For demonstration purpose, we will use this type `NeedPin`:
23//! ```no_run
24//! # use std::marker::PhantomPinned;
25//! # use std::ptr;
26//! struct NeedPin {
27//!     // Must points to itself
28//!     address: *const NeedPin,
29//!     _pinned: PhantomPinned,
30//! }
31//!
32//! impl NeedPin {
33//!     fn verify(&self) {
34//!         assert!(ptr::eq(self, self.address), "invariant not held");
35//!     }
36//! }
37//!
38//! impl Drop for NeedPin {
39//!     fn drop(&mut self) {
40//!         /* Must be called */
41//!     }
42//! }
43//! ```
44//!
45//! One could separate creating and initialization (Infallible is used as a
46//! placeholder here but in reality it can fail):
47//! ```no_run
48//! # include!("doctest.rs");
49//! # fn main() {}
50//! impl NeedPin {
51//!     unsafe fn uninit() -> Self {
52//!         Self {
53//!             address: ptr::null(),
54//!             _pinned: PhantomPinned,
55//!         }
56//!     }
57//!
58//!     unsafe fn init(self: Pin<&mut Self>) -> Result<(), Infallible> {
59//!         let this = unsafe { self.get_unchecked_mut() };
60//!         this.address = this;
61//!         Ok(())
62//!     }
63//! }
64//! ```
65//! but this requires unsafe and is very difficult to use.
66//!
67//! The ultimate goal is:
68//! 1. Safety. We should be able to create and use such pinned type without unsafe.
69//!    (Obviously the pinned type themselves are still unsafe to implement).
70//! 2. Ergonomics. The syntax shouldn't be too different from anormal Rust.
71//! 3. Aggregatable. A struct containing multiple pinned types can be safely
72//!    created and initialized together.
73//! 4. No Implicit Allocation. Allocation should not be required during initialization.
74//!    User should be able to dictate whether it's initialized in a box or on the stack.
75//! 5. Fallible. No assumption is made about success of initialization.
76//!
77//! # The solution: `pin_init`
78//!
79//! This crate provides type [`PinUninit`] and [`InitResult`] as the primitives
80//! for safe pinned-initialization. Details about these types can be found in
81//! their respective documentation, but in a nutshell, instead of having a (fallible)
82//! constructor that returns `Result<T, Err>`, `pin_init` expect you to present a constructor
83//! that returns `impl Init<T, Err>`, where [`Init`] can be created from
84//! a closure of type `for<'a> FnOnce(PinUninit<'a, T>) -> InitResult<'a, T, Err>`
85//! using [`init_from_closure`].
86//!
87//! `NeedPin::new` could be define like this:
88//! ```no_run
89//! # use pin_init::*;
90//! # use std::convert::Infallible;
91//! # use std::ptr;
92//! # struct NeedPin {
93//! #     address: *const NeedPin,
94//! #     _pinned: std::marker::PhantomPinned,
95//! # }
96//! impl NeedPin {
97//!     pub fn new() -> impl Init<Self, Infallible> {
98//!         init_from_closure(|mut this: PinUninit<'_, Self>| -> InitResult<'_, Self, Infallible> {
99//!             let v = this.get_mut().as_mut_ptr();
100//!             unsafe { *ptr::addr_of_mut!((*v).address) = v };
101//!             Ok(unsafe { this.init_ok() })
102//!         })
103//!     }
104//! }
105//! ```
106//!
107//! With Rust's affine type system and borrow checker, the `InitResult` is
108//! essentially a certificate about whether the type is initialized or not.
109//! `NeedPin` can now be easily initialized:
110//! ```
111//! # include!("doctest.rs");
112//! # fn main() {
113//! // In a box
114//! let p: Pin<Box<NeedPin>> = Box::pin_with(NeedPin::new()).unwrap();
115//! // On the stack
116//! init_stack!(p = NeedPin::new());
117//! let p: Pin<&mut NeedPin> = p.unwrap();
118//! # }
119//! ```
120//!
121//! For structs, if [`#[pin_init]`](pin_init) when defining the struct, then
122//! [`init_pin!`] can create it very similar to the struct expression. Nested
123//! structures are also supported.
124//!
125//! ```
126//! # include!("doctest.rs");
127//! # fn main() {
128//! #[pin_init]
129//! struct ManyPin {
130//!     #[pin]
131//!     a: NeedPin,
132//!     b: usize,
133//! }
134//!
135//! #[pin_init]
136//! struct TooManyPin {
137//!     #[pin]
138//!     a: NeedPin,
139//!     #[pin]
140//!     b: ManyPin,
141//! }
142//! let p = Box::pin_with(init_pin!(TooManyPin {
143//!     a: NeedPin::new(),
144//!     b: ManyPin {
145//!         a: NeedPin::new(),
146//!         b: 0,
147//!     },
148//! }));
149//! # }
150//! ```
151//!
152//! This crate also provides a [`UniqueRc`] and [`UniqueArc`], inspired from servo_arc.
153//! They can be used to mutably initialize `Rc` and `Arc` before they are being shared.
154//! [`Rc::pin_with`] and [`Arc::pin_with`] are provided which create [`UniqueRc`] and [`UniqueArc`]
155//! internally, pin-initialize it with given constructor, and convert them to the shareable form.
156//!
157//! This crate allows safe initialization of pinned data structure.
158//! [`pin-project`](https://docs.rs/pin-project) can be used to safely access these structs. You can
159//! use both `#[pin_init]` and `#[pin_project]` together with your struct, they even share the same
160//! `#[pin]` field attribute!
161//!
162//! See [examples](https://github.com/nbdd0121/pin-init/tree/trunk/examples) for some non-artifical examples.
163//!
164//! [`UniqueRc`]: struct.UniqueRc.html
165//! [`UniqueArc`]: struct.UniqueArc.html
166//! [`Rc::pin_with`]: trait.PtrPinWith.html#tymethod.pin_with
167//! [`Arc::pin_with`]: trait.PtrPinWith.html#tymethod.pin_with
168
169#[cfg(feature = "alloc")]
170extern crate alloc;
171
172#[cfg(feature = "alloc")]
173mod unique;
174
175/// Mark a type as being [`init_pin!`]-able.
176///
177/// Can only be applied to structs. Each field can be tagged with `#[pin]`
178/// or not. Tagged fields are pin-initialized, and untaged fields are initialized
179/// by value like they do in normal struct expression.
180///
181/// ```no_run
182/// # include!("doctest.rs");
183/// #[pin_init]
184/// struct ManyPin {
185///     #[pin]
186///     a: NeedPin,
187///     b: usize,
188/// }
189/// # fn main() {}
190/// ```
191///
192/// Also works for tuple-structs:
193/// ```no_run
194/// # include!("doctest.rs");
195/// #[pin_init]
196/// struct ManyPin(#[pin] NeedPin, usize);
197/// # fn main() {}
198/// ```
199///
200/// You could apply it to unit-structs (but probably not very useful):
201/// ```no_run
202/// # include!("doctest.rs");
203/// #[pin_init]
204/// struct NoPin;
205/// # fn main() {}
206/// ```
207pub use pin_init_internal::pin_init;
208
209/// Create and pin-initialize a struct.
210///
211/// The type to create need to be marked with [`#[pin_init]`](pin_init).
212///
213/// ```
214/// # include!("doctest.rs");
215/// # fn main() {
216/// #[pin_init]
217/// struct ManyPin {
218///     #[pin]
219///     a: NeedPin,
220///     b: usize,
221/// }
222/// let p = Box::pin_with(init_pin!(ManyPin {
223///     a: NeedPin::new(),
224///     b: 0,
225/// }));
226/// # }
227/// ```
228///
229/// Also works for tuple-structs:
230/// ```
231/// # include!("doctest.rs");
232/// # fn main() {
233/// #[pin_init]
234/// struct ManyPin(#[pin] NeedPin, usize);
235/// let p = Box::pin_with(init_pin!(ManyPin(
236///     NeedPin::new(),
237///     0,
238/// )));
239/// # }
240/// ```
241///
242/// You could apply it to unit-structs (but probably not very useful):
243/// ```
244/// # include!("doctest.rs");
245/// # fn main() {
246/// #[pin_init]
247/// struct NoPin;
248/// let p: Result<_, Infallible> = Box::pin_with(init_pin!(NoPin));
249/// # }
250/// ```
251///
252/// By default, no conversions are made for errors, as otherwise type inference
253/// may fail (like using the ? operator in a closure). If you need error conversion,
254/// you can use [`Init::map_err`].
255/// You may need type annotation or [`specify_err`] to avoid type inference failure.
256/// ```
257/// # include!("doctest.rs");
258/// # fn main() {
259/// #[pin_init]
260/// # struct ManyPin {
261/// #     #[pin]
262/// #     a: NeedPin,
263/// #     b: usize,
264/// # }
265/// let p: Result<Pin<Box<_>>, Infallible> = Box::pin_with(init_pin!(ManyPin {
266///     a: NeedPin::new().map_err(Into::into),
267///     b: 0,
268/// }));
269/// # }
270/// ```
271///
272/// `init_pin!` can be used for nested initialization as well:
273/// ```
274/// # include!("doctest.rs");
275/// # fn main() {
276/// # #[pin_init]
277/// # struct ManyPin {
278/// #     #[pin]
279/// #     a: NeedPin,
280/// #     b: usize,
281/// # }
282/// #[pin_init]
283/// struct TooManyPin {
284///     #[pin]
285///     a: NeedPin,
286///     #[pin]
287///     b: ManyPin,
288/// }
289/// let p = Box::pin_with(init_pin!(TooManyPin {
290///     a: NeedPin::new(),
291///     // Nested by default. To opt out write `b: #[unpin] NeedPin {`.
292///     b: ManyPin {
293///         a: NeedPin::new(),
294///         b: 0,
295///     },
296/// }));
297/// # }
298/// ```
299///
300/// If you want to define a constructor, you can write like this:
301/// ```
302/// # include!("doctest.rs");
303/// # fn main() {
304/// # #[pin_init]
305/// # struct ManyPin {
306/// #     #[pin]
307/// #     a: NeedPin,
308/// #     b: usize,
309/// # }
310/// impl ManyPin {
311///     pub fn new() -> impl Init<Self, Infallible> {
312///         init_pin!(ManyPin {
313///             a: NeedPin::new(),
314///             b: 1,
315///         })
316///     }
317/// }
318/// # }
319/// ```
320///
321/// `init_pin!` can also initialize some std types:
322/// ```
323/// # include!("doctest.rs");
324/// # fn main() {
325/// use core::cell::UnsafeCell;
326/// use core::cell::Cell;
327/// specify_err::<_, Infallible, _>(init_pin!(PhantomPinned));
328/// init_pin!(UnsafeCell(NeedPin::new()));
329/// init_pin!(Cell(NeedPin::new()));
330/// # }
331/// ```
332pub use pin_init_internal::init_pin;
333
334#[cfg(feature = "alloc")]
335pub use unique::{UniqueArc, UniqueRc};
336
337use core::marker::PhantomData;
338use core::mem;
339use core::mem::MaybeUninit;
340use core::pin::Pin;
341
342#[cfg(feature = "alloc")]
343use alloc::{boxed::Box, rc::Rc, sync::Arc};
344#[cfg(feature = "alloc_try_pin_with")]
345use core::alloc::AllocError;
346#[cfg(feature = "alloc")]
347use core::{mem::ManuallyDrop, ops::Deref};
348
349/// A pinned, uninitialized pointer.
350///
351/// This can be considered as [`Pin<&mut MaybeUninit<T>>`]:
352/// * The pointee has a stable location in memory. It cannot be moved elsewhere.
353/// * The pointee is not yet initialized, therefore the drop guarantee is not
354///   existent.
355///
356/// However, `PinUninit` provides the additional guarantee that once a method
357/// that successfully initialze the data is called (e.g. [`init_ok`](#method.init_ok)), the
358/// pointee will be considered as [`Pin<&mut T>`], therefore the drop guarantee
359/// kicks in, and `T`'s destructor is guaranteed to be called before the storage
360/// is deallocated.
361pub struct PinUninit<'a, T> {
362    ptr: *mut MaybeUninit<T>,
363    // Make sure the lifetime `'a` isn't tied to `MaybeUninit<T>`, to avoid
364    // implying `T: 'a`. Note that `PinUninit::new` still takes `&'a mut MaybeUninit<T>`,
365    // so only well-formed `PinUninit` can be constructed.
366    _marker: PhantomData<&'a mut ()>,
367}
368
369impl<'a, T> PinUninit<'a, T> {
370    /// Creates a new [`PinUninit`] with a given [`MaybeUninit<T>`].
371    ///
372    /// # Safety
373    /// The caller must ensure `ptr` has a stable location in memory.
374    ///
375    /// The caller must obtain a [`InitResult`] that is tied to the lifetime of the returned
376    /// `PinUninit`, and need to respect its value:
377    /// * If [`InitOk`] is obtained, the caller must treat the `ptr` as [`Pin<&mut T>`].
378    ///   This means that the drop guarantee kick in; the memory cannot be deallocated until `T`
379    ///   is dropped.
380    /// * If [`InitErr`] is obtained, `ptr` is uninitialized and the caller must not
381    ///   try to drop `T`.
382    /// * If panic happens while trying to get the result, then we are not certain about
383    ///   initialization state. This means that the caller must respect the drop guarantee,
384    ///   but also not drop the value. The only solution is to leak memory. If that's not possible,
385    ///   then the caller must abort the process.
386    ///
387    /// The lifetime associated with this function should be "closed". It should be a local,
388    /// temporary lifetime, shorter than any of the lifetime the caller have access to (including
389    /// `'static`, and should not escape the calling function.
390    /// This is to guarantee that the only way to get a [`InitResult<'a, T, E>`]
391    /// is to use of the methods of this particular `PinUninit` returned.
392    /// In order to satisfy the requirement, the caller typically takes a constructor with type
393    /// `Init<T, E>`, which can be seen as `for<'a> FnOnce(PinUninit<'a, T>) -> InitResult<'a, T, E>`.
394    ///
395    /// [`PinUninit<'a, T>`]: PinUninit
396    /// [`InitResult<'a, T, E>`]: InitResult
397    #[inline]
398    pub unsafe fn new(ptr: &'a mut MaybeUninit<T>) -> Self {
399        PinUninit {
400            ptr,
401            _marker: PhantomData,
402        }
403    }
404
405    /// Gets a mutable reference to `MaybeUninit` inside of this `PinUninit`.
406    ///
407    /// This is safe because the `MaybeUninit` we point to is not yet initialized,
408    /// and `MaybeUninit` does not have `Drop` implementation.
409    #[inline]
410    pub fn get_mut(&mut self) -> &mut MaybeUninit<T> {
411        unsafe { &mut *self.ptr }
412    }
413
414    /// Asserts that the initialize is indeed completed. Doing so initiates the
415    /// drop guarantee of `T`.
416    ///
417    /// # Safety
418    /// This function is unsafe as this is equivalent to [`MaybeUninit::assume_init`].
419    #[inline]
420    pub unsafe fn init_ok(self) -> InitOk<'a, T> {
421        InitOk {
422            ptr: self.ptr as *mut T,
423            marker: PhantomData,
424        }
425    }
426
427    /// Generates a `InitResult` signaling that the initialization is failed.
428    ///
429    /// Note that the caller should make sure nothing is partially pinned-initialized.
430    /// This isn't the contract of this function, but is the contract for
431    /// creating `PinUninit` for pinned-initializing sub-fields.
432    #[inline]
433    pub fn init_err<E>(self, err: E) -> InitErr<'a, E> {
434        InitErr {
435            inner: err,
436            marker: PhantomData,
437        }
438    }
439
440    /// Completes the initialization with a callback.
441    ///
442    /// Useful e.g. if the callback is produced by `init_pin!`.
443    #[inline]
444    pub fn init<E, F>(self, value: F) -> InitResult<'a, T, E>
445    where
446        F: Init<T, E>,
447    {
448        value.__init(self)
449    }
450
451    /// Completes the initialization by moving the given value.
452    ///
453    /// Useful if the the type `T` can be initialized unpinned.
454    #[inline]
455    pub fn init_with_value(mut self, value: T) -> InitOk<'a, T> {
456        // SAFFTY: writing to `MaybeUninit` is safe.
457        unsafe { self.get_mut().as_mut_ptr().write(value) };
458        // SAFETY: we have just performed initialization.
459        unsafe { self.init_ok() }
460    }
461}
462
463/// Proof that the value is pin-initialized.
464///
465/// See documentation of [`PinUninit`] for details.
466pub struct InitOk<'a, T> {
467    // We don't want a T: 'a bound, so don't we cannot put `Pin<&'a mut T>` here.
468    // This is safe as, `InitOk` can only come from `PinUninit::new` which
469    // guarantees the well-formedness.
470    ptr: *mut T,
471    marker: PhantomData<&'a mut ()>,
472}
473
474impl<'a, T> InitOk<'a, T> {
475    /// Get the `Pin<&T>` view of the pinned and initialized `T`.
476    #[inline]
477    pub fn as_ref(&self) -> Pin<&T> {
478        unsafe { Pin::new_unchecked(&*self.ptr) }
479    }
480
481    /// Get the `Pin<&mut T>` view of the pinned and initialized `T`.
482    #[inline]
483    pub fn as_mut(&mut self) -> Pin<&mut T> {
484        unsafe { Pin::new_unchecked(&mut *self.ptr) }
485    }
486
487    /// Get the pinned and initialized `T`.
488    #[inline]
489    pub fn into_inner(self) -> Pin<&'a mut T> {
490        unsafe { Pin::new_unchecked(&mut *self.ptr) }
491    }
492}
493
494/// Proof that the value is not pin-initialized.
495///
496/// See documentation of [`PinUninit`] for details.
497pub struct InitErr<'a, E> {
498    inner: E,
499    marker: PhantomData<&'a mut ()>,
500}
501
502impl<'a, E> InitErr<'a, E> {
503    /// Get a reference to the inner error.
504    #[inline]
505    pub fn as_ref(&self) -> &E {
506        &self.inner
507    }
508
509    /// Get a mutable reference to the inner error.
510    #[inline]
511    pub fn as_mut(&mut self) -> &mut E {
512        &mut self.inner
513    }
514
515    /// Get the inner error.
516    #[inline]
517    pub fn into_inner(self) -> E {
518        self.inner
519    }
520
521    /// Map the inner error with the given function.
522    #[inline]
523    pub fn map<T, F>(self, f: F) -> InitErr<'a, T>
524    where
525        F: FnOnce(E) -> T,
526    {
527        InitErr {
528            inner: f(self.inner),
529            marker: PhantomData,
530        }
531    }
532}
533
534/// Result of pin-initialization.
535///
536/// See documentation of [`PinUninit`] for details.
537pub type InitResult<'a, T, E> = Result<InitOk<'a, T>, InitErr<'a, E>>;
538
539/// Initializer that can be used to safely pin-initialize `T`.
540///
541/// A blanket implementation `impl<T, E> Init<T, E> for T` is provided for all types, so
542/// a non-pinned value can be used directly for pin-initialization.
543pub trait Init<T, E>: Sized {
544    /// Pin-initialize `this`.
545    fn __init<'a>(self, this: PinUninit<'a, T>) -> InitResult<'a, T, E>;
546
547    /// Maps the error from `E` to `E2`.
548    fn map_err<E2, F>(self, f: F) -> MapErr<T, E, E2, Self, F>
549    where
550        F: FnOnce(E) -> E2,
551    {
552        MapErr {
553            init: self,
554            map: f,
555            marker: PhantomData,
556        }
557    }
558}
559
560impl<T, E> Init<T, E> for T {
561    fn __init<'a>(self, this: PinUninit<'a, T>) -> InitResult<'a, T, E> {
562        Ok(this.init_with_value(self))
563    }
564}
565
566#[doc(hidden)]
567pub struct MapErr<T, E, E2, I, F> {
568    init: I,
569    map: F,
570    #[allow(clippy::type_complexity)]
571    marker: PhantomData<(fn(T) -> E, fn(E) -> E2)>,
572}
573
574impl<T, E, E2, I, F> Init<T, E2> for MapErr<T, E, E2, I, F>
575where
576    I: Init<T, E>,
577    F: FnOnce(E) -> E2,
578{
579    fn __init<'a>(self, this: PinUninit<'a, T>) -> InitResult<'a, T, E2> {
580        match self.init.__init(this) {
581            Ok(v) => Ok(v),
582            Err(v) => Err(v.map(self.map)),
583        }
584    }
585}
586
587/// Specify an Error type if type inference cannot infer it.
588pub fn specify_err<T, E, I>(init: I) -> impl Init<T, E>
589where
590    I: Init<T, E>,
591{
592    init
593}
594
595/// Construct a [`Init<T, E>`] with a closure.
596pub fn init_from_closure<T, E, F>(f: F) -> impl Init<T, E>
597where
598    F: for<'a> FnOnce(PinUninit<'a, T>) -> InitResult<'a, T, E>,
599{
600    struct ClosureInit<T, E, F>(F, PhantomData<fn(T) -> E>)
601    where
602        F: for<'a> FnOnce(PinUninit<'a, T>) -> InitResult<'a, T, E>;
603
604    impl<T, E, F> Init<T, E> for ClosureInit<T, E, F>
605    where
606        F: for<'a> FnOnce(PinUninit<'a, T>) -> InitResult<'a, T, E>,
607    {
608        fn __init<'a>(self, this: PinUninit<'a, T>) -> InitResult<'a, T, E> {
609            (self.0)(this)
610        }
611    }
612
613    ClosureInit(f, PhantomData)
614}
615
616/// Pointer types that can be pin-initialized.
617pub trait PtrInit<T>: Deref<Target = T> + Sized {
618    type Uninit: Deref<Target = MaybeUninit<T>>;
619
620    fn init<E, I>(uninit: Pin<Self::Uninit>, init: I) -> Result<Pin<Self>, E>
621    where
622        I: Init<T, E>;
623}
624
625#[cfg(feature = "alloc")]
626#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
627impl<T> PtrInit<T> for Box<T> {
628    type Uninit = Box<MaybeUninit<T>>;
629
630    #[inline]
631    fn init<E, I>(uninit: Pin<Box<MaybeUninit<T>>>, init: I) -> Result<Pin<Box<T>>, E>
632    where
633        I: Init<T, E>,
634    {
635        // SAFETY: We don't move value out.
636        // If `f` below panics, we might be in a partially initialized state. We
637        // cannot drop nor assume_init, so we can only leak.
638        let mut ptr = ManuallyDrop::new(unsafe { Pin::into_inner_unchecked(uninit) });
639        // SAFETY: pinning is guaranteed by `storage`'s pin guarantee.
640        //         We will check the return value, and act accordingly.
641        match init.__init(unsafe { PinUninit::new(&mut ptr) }) {
642            Ok(_) => {
643                // SAFETY: We know it's initialized, and both `ManuallyDrop` and `Pin`
644                //         are `#[repr(transparent)]` so this is safe.
645                Ok(unsafe { mem::transmute(ptr) })
646            }
647            Err(err) => {
648                let err = err.into_inner();
649                // SAFETY: We know it's not initialized.
650                drop(ManuallyDrop::into_inner(ptr));
651                Err(err)
652            }
653        }
654    }
655}
656
657#[cfg(feature = "alloc")]
658#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
659impl<T> PtrInit<T> for UniqueRc<T> {
660    type Uninit = UniqueRc<MaybeUninit<T>>;
661
662    #[inline]
663    fn init<E, I>(uninit: Pin<UniqueRc<MaybeUninit<T>>>, init: I) -> Result<Pin<UniqueRc<T>>, E>
664    where
665        I: Init<T, E>,
666    {
667        // SAFETY: See `init_box`.
668        let mut ptr = ManuallyDrop::new(unsafe { Pin::into_inner_unchecked(uninit) });
669        match init.__init(unsafe { PinUninit::new(&mut ptr) }) {
670            Ok(_) => Ok(unsafe { mem::transmute(ptr) }),
671            Err(err) => {
672                let err = err.into_inner();
673                drop(ManuallyDrop::into_inner(ptr));
674                Err(err)
675            }
676        }
677    }
678}
679
680/// Pin-initialize a `UniqueArc`.
681#[cfg(feature = "alloc")]
682#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
683impl<T> PtrInit<T> for UniqueArc<T> {
684    type Uninit = UniqueArc<MaybeUninit<T>>;
685
686    #[inline]
687    fn init<E, I>(uninit: Pin<UniqueArc<MaybeUninit<T>>>, init: I) -> Result<Pin<UniqueArc<T>>, E>
688    where
689        I: Init<T, E>,
690    {
691        // SAFETY: See `init_box`.
692        let mut ptr = ManuallyDrop::new(unsafe { Pin::into_inner_unchecked(uninit) });
693        match init.__init(unsafe { PinUninit::new(&mut ptr) }) {
694            Ok(_) => Ok(unsafe { mem::transmute(ptr) }),
695            Err(err) => {
696                let err = err.into_inner();
697                drop(ManuallyDrop::into_inner(ptr));
698                Err(err)
699            }
700        }
701    }
702}
703
704/// Pointer types that can be pin-newed.
705#[cfg(feature = "alloc_pin_with")]
706#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
707pub trait PtrPinWith<T>: Deref<Target = T> + Sized {
708    fn pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
709    where
710        I: Init<T, E>;
711}
712
713#[cfg(feature = "alloc_pin_with")]
714#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
715impl<T> PtrPinWith<T> for Box<T> {
716    #[inline]
717    fn pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
718    where
719        I: Init<T, E>,
720    {
721        PtrInit::init(Box::new(MaybeUninit::uninit()).into(), init)
722    }
723}
724
725#[cfg(feature = "alloc_pin_with")]
726#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
727impl<T> PtrPinWith<T> for UniqueRc<T> {
728    #[inline]
729    fn pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
730    where
731        I: Init<T, E>,
732    {
733        PtrInit::init(UniqueRc::new(MaybeUninit::uninit()).into(), init)
734    }
735}
736
737#[cfg(feature = "alloc_pin_with")]
738#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
739impl<T> PtrPinWith<T> for UniqueArc<T> {
740    #[inline]
741    fn pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
742    where
743        I: Init<T, E>,
744    {
745        PtrInit::init(UniqueArc::new(MaybeUninit::uninit()).into(), init)
746    }
747}
748
749#[cfg(feature = "alloc_pin_with")]
750#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
751impl<T> PtrPinWith<T> for Rc<T> {
752    #[inline]
753    fn pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
754    where
755        I: Init<T, E>,
756    {
757        Ok(UniqueRc::shareable_pin(UniqueRc::pin_with(init)?))
758    }
759}
760
761#[cfg(feature = "alloc_pin_with")]
762#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
763impl<T> PtrPinWith<T> for Arc<T> {
764    #[inline]
765    fn pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
766    where
767        I: Init<T, E>,
768    {
769        Ok(UniqueArc::shareable_pin(UniqueArc::pin_with(init)?))
770    }
771}
772
773/// Pointer types that can be pin-newed.
774#[cfg(feature = "alloc_try_pin_with")]
775#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
776pub trait PtrTryPinWith<T>: Deref<Target = T> + Sized {
777    fn try_pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
778    where
779        I: Init<T, E>,
780        E: From<AllocError>;
781}
782
783#[cfg(feature = "alloc_try_pin_with")]
784#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
785impl<T> PtrTryPinWith<T> for Box<T> {
786    #[inline]
787    fn try_pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
788    where
789        I: Init<T, E>,
790        E: From<AllocError>,
791    {
792        PtrInit::init(Box::try_new(MaybeUninit::uninit())?.into(), init)
793    }
794}
795
796#[cfg(feature = "alloc_try_pin_with")]
797#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
798impl<T> PtrTryPinWith<T> for UniqueRc<T> {
799    #[inline]
800    fn try_pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
801    where
802        I: Init<T, E>,
803        E: From<AllocError>,
804    {
805        PtrInit::init(UniqueRc::try_new(MaybeUninit::uninit())?.into(), init)
806    }
807}
808
809#[cfg(feature = "alloc_try_pin_with")]
810#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
811impl<T> PtrTryPinWith<T> for UniqueArc<T> {
812    #[inline]
813    fn try_pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
814    where
815        I: Init<T, E>,
816        E: From<AllocError>,
817    {
818        PtrInit::init(UniqueArc::try_new(MaybeUninit::uninit())?.into(), init)
819    }
820}
821
822#[cfg(feature = "alloc_try_pin_with")]
823#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
824impl<T> PtrTryPinWith<T> for Rc<T> {
825    #[inline]
826    fn try_pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
827    where
828        I: Init<T, E>,
829        E: From<AllocError>,
830    {
831        Ok(UniqueRc::shareable_pin(UniqueRc::try_pin_with(init)?))
832    }
833}
834
835#[cfg(feature = "alloc_try_pin_with")]
836#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
837impl<T> PtrTryPinWith<T> for Arc<T> {
838    #[inline]
839    fn try_pin_with<E, I>(init: I) -> Result<Pin<Self>, E>
840    where
841        I: Init<T, E>,
842        E: From<AllocError>,
843    {
844        Ok(UniqueArc::shareable_pin(UniqueArc::try_pin_with(init)?))
845    }
846}
847
848/// Types that can be constructed using `init_pin`.
849///
850/// This trait is not meant for manual implementation and consumption.
851/// You should use [`#[pin_init]`](pin_init) attribute to implement this trait, and
852/// [`init_pin!`] macro to use.
853///
854/// This trait is implemented on some std types so they can also be constructed
855/// using `init_pin!`.
856pub trait Initable<'this>: Sized {
857    #[doc(hidden)]
858    type __PinInitBuilder;
859
860    #[doc(hidden)]
861    fn __pin_init_builder(init: PinUninit<'this, Self>) -> Self::__PinInitBuilder;
862}
863
864#[doc(hidden)]
865pub mod __private {
866    use super::*;
867    pub use pin_init_internal::PinInit;
868
869    pub struct StackWrapper<T>(MaybeUninit<T>, bool);
870
871    impl<T> StackWrapper<T> {
872        #[inline]
873        pub fn new() -> Self {
874            StackWrapper(MaybeUninit::uninit(), false)
875        }
876
877        #[inline]
878        pub fn init<F, E>(self: Pin<&mut Self>, f: F) -> Result<Pin<&mut T>, E>
879        where
880            F: Init<T, E>,
881        {
882            struct PanicGuard;
883            impl Drop for PanicGuard {
884                #[inline]
885                fn drop(&mut self) {
886                    panic!("panicked while pin-initing variable on stack");
887                }
888            }
889
890            assert!(!self.1);
891
892            let this = unsafe { self.get_unchecked_mut() };
893
894            // If `f` below panics, we might be in a partially initialized state. We
895            // cannot drop nor assume_init, and we cannot leak memory on stack. So
896            // the only sensible action would be to abort (with double-panic).
897            let g = PanicGuard;
898            let res = f.__init(unsafe { PinUninit::new(&mut this.0) });
899            mem::forget(g);
900
901            match res {
902                Ok(ok) => {
903                    this.1 = true;
904                    Ok(ok.into_inner())
905                }
906                Err(err) => Err(err.into_inner()),
907            }
908        }
909    }
910
911    impl<T> Drop for StackWrapper<T> {
912        #[inline]
913        fn drop(&mut self) {
914            if self.1 {
915                unsafe {
916                    self.0.as_mut_ptr().drop_in_place();
917                }
918            }
919        }
920    }
921
922    pub struct ValueBuilder<'this, T>(InitOk<'this, T>);
923
924    impl<'this, T> ValueBuilder<'this, T> {
925        #[inline]
926        pub fn __init_ok(self) -> InitOk<'this, T> {
927            self.0
928        }
929    }
930
931    // pin-project users may want a #[pin] PhantomPinned
932    impl<'this> Initable<'this> for core::marker::PhantomPinned {
933        #[doc(hidden)]
934        type __PinInitBuilder = ValueBuilder<'this, Self>;
935
936        #[doc(hidden)]
937        #[inline]
938        fn __pin_init_builder(init: PinUninit<'this, Self>) -> Self::__PinInitBuilder {
939            ValueBuilder(init.init_with_value(Self))
940        }
941    }
942
943    pub struct TransparentBuilder<'this, T, W>(
944        PinUninit<'this, W>,
945        PhantomData<PinUninit<'this, T>>,
946    );
947
948    impl<'this, T> Initable<'this> for core::cell::UnsafeCell<T> {
949        #[doc(hidden)]
950        type __PinInitBuilder = TransparentBuilder<'this, T, core::cell::UnsafeCell<T>>;
951
952        #[doc(hidden)]
953        #[inline]
954        fn __pin_init_builder(init: PinUninit<'this, Self>) -> Self::__PinInitBuilder {
955            TransparentBuilder(init, PhantomData)
956        }
957    }
958
959    impl<'this, T> Initable<'this> for core::cell::Cell<T> {
960        #[doc(hidden)]
961        type __PinInitBuilder = TransparentBuilder<'this, T, core::cell::Cell<T>>;
962
963        #[doc(hidden)]
964        #[inline]
965        fn __pin_init_builder(init: PinUninit<'this, Self>) -> Self::__PinInitBuilder {
966            TransparentBuilder(init, PhantomData)
967        }
968    }
969
970    impl<'this, T, W> TransparentBuilder<'this, T, W> {
971        #[inline]
972        pub fn __next<E, F>(mut self, f: F) -> Result<ValueBuilder<'this, W>, InitErr<'this, E>>
973        where
974            F: Init<T, E>,
975        {
976            // This is okay because we only deal with #[repr(transparent)] structs here.
977            let ptr = self.0.get_mut().as_mut_ptr() as *mut MaybeUninit<T>;
978            match f.__init(unsafe { PinUninit::new(&mut *ptr) }) {
979                Ok(_) => Ok(ValueBuilder(unsafe { self.0.init_ok() })),
980                Err(err) => Err(self.0.init_err(err.into_inner())),
981            }
982        }
983    }
984}
985
986/// Create and pin-initialize a new variable on the stack.
987///
988/// ```
989/// # include!("doctest.rs");
990/// # fn main() {
991/// init_stack!(p = NeedPin::new());
992/// // Now `p` is a `Result<Pin<&mut NeedPin>, Infallible>`.
993/// # }
994/// ```
995///
996/// Can be used together with [`init_pin!`]:
997/// ```
998/// # include!("doctest.rs");
999/// # fn main() {
1000/// #[pin_init]
1001/// struct ManyPin {
1002///     #[pin]
1003///     a: NeedPin,
1004///     b: usize,
1005/// }
1006/// init_stack!(p = init_pin!(ManyPin {
1007///     a: NeedPin::new(),
1008///     b: 0,
1009/// }));
1010/// # }
1011/// ```
1012///
1013/// The initializers should not panic, and should use `Err` to report failures.
1014/// If the initializer fails, because we cannot tell whether the value is
1015/// initialized or not (or even just partially initialized), drop guarantee cannot
1016/// be kept, this macro will abort the process.
1017#[macro_export]
1018macro_rules! init_stack {
1019    ($var:ident = $init:expr) => {
1020        let mut storage = $crate::__private::StackWrapper::new();
1021        let $var =
1022            unsafe { ::core::pin::Pin::new_unchecked(&mut storage) }.init($crate::init_pin!($init));
1023    };
1024}