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}