Skip to content

Commit 63adb5e

Browse files
authored
Rollup merge of rust-lang#60165 - Nemo157:pin-into-inner, r=cramertj
Add Pin::{into_inner,into_inner_unchecked} These functions are useful for unsafe code that needs to temporarily pull smart pointers out of the `Pin`, e.g. [the change that inspired them](Nemo157/futures-rs@b436178#diff-1a4e0ba4d1b539412ca576411ec6c7c2R258) is taking a `Pin<Box<dyn Future>>`, turning it into a `*mut dyn Future` via `Box::into_raw(unsafe { Pin::into_inner_unchecked(pin) })` then later dropping this via `drop(Pin::from(Box::from_raw(ptr)))`. This can be accomplished today via `{ let ptr = unsafe { Pin::get_unchecked_mut(pin.as_mut()) } as *mut dyn Future; mem::forget(pin); ptr }`, but this is far more complicated and loses out on the symmetry of using `Box::into_raw` and `Box::from_raw`. I'll extend the documentation on what guarantees `into_inner_unchecked` needs to uphold once I get some feedback on whether this API is wanted or not. r? @withoutboats
2 parents 5c134f6 + a0e0849 commit 63adb5e

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/libcore/pin.rs

+34
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,18 @@ where
349349
// around pinning.
350350
unsafe { Pin::new_unchecked(pointer) }
351351
}
352+
353+
/// Unwraps this `Pin<P>` returning the underlying pointer.
354+
///
355+
/// This requires that the data inside this `Pin` is [`Unpin`] so that we
356+
/// can ignore the pinning invariants when unwrapping it.
357+
///
358+
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
359+
#[unstable(feature = "pin_into_inner", issue = "60245")]
360+
#[inline(always)]
361+
pub fn into_inner(pin: Pin<P>) -> P {
362+
pin.pointer
363+
}
352364
}
353365

354366
impl<P: Deref> Pin<P> {
@@ -434,6 +446,28 @@ impl<P: Deref> Pin<P> {
434446
pub fn as_ref(self: &Pin<P>) -> Pin<&P::Target> {
435447
unsafe { Pin::new_unchecked(&*self.pointer) }
436448
}
449+
450+
/// Unwraps this `Pin<P>` returning the underlying pointer.
451+
///
452+
/// # Safety
453+
///
454+
/// This function is unsafe. You must guarantee that you will continue to
455+
/// treat the pointer `P` as pinned after you call this function, so that
456+
/// the invariants on the `Pin` type can be upheld. If the code using the
457+
/// resulting `P` does not continue to maintain the pinning invariants that
458+
/// is a violation of the API contract and may lead to undefined behavior in
459+
/// later (safe) operations.
460+
///
461+
/// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
462+
/// instead.
463+
///
464+
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
465+
/// [`Pin::into_inner`]: #method.into_inner
466+
#[unstable(feature = "pin_into_inner", issue = "60245")]
467+
#[inline(always)]
468+
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
469+
pin.pointer
470+
}
437471
}
438472

439473
impl<P: DerefMut> Pin<P> {

0 commit comments

Comments
 (0)