Skip to content

Commit

Permalink
Make some methods of Pin unstable const
Browse files Browse the repository at this point in the history
Make the following methods unstable const under the `const_pin` feature:
- `new`
- `new_unchecked`
- `into_inner`
- `into_inner_unchecked`
- `get_ref`
- `into_ref`

Also adds tests for these methods in a const context.

Tracking issue: rust-lang#76654
  • Loading branch information
CDirkx committed Sep 12, 2020
1 parent 9891908 commit 8f27e3c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#![feature(const_int_pow)]
#![feature(constctlz)]
#![feature(const_panic)]
#![feature(const_pin)]
#![feature(const_fn_union)]
#![feature(const_generics)]
#![feature(const_option)]
Expand Down
27 changes: 16 additions & 11 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,9 +471,10 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
///
/// Unlike `Pin::new_unchecked`, this method is safe because the pointer
/// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees.
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
pub fn new(pointer: P) -> Pin<P> {
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin", since = "1.33.0")]
pub const fn new(pointer: P) -> Pin<P> {
// SAFETY: the value pointed to is `Unpin`, and so has no requirements
// around pinning.
unsafe { Pin::new_unchecked(pointer) }
Expand All @@ -483,9 +484,10 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
///
/// This requires that the data inside this `Pin` is [`Unpin`] so that we
/// can ignore the pinning invariants when unwrapping it.
#[stable(feature = "pin_into_inner", since = "1.39.0")]
#[inline(always)]
pub fn into_inner(pin: Pin<P>) -> P {
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin_into_inner", since = "1.39.0")]
pub const fn into_inner(pin: Pin<P>) -> P {
pin.pointer
}
}
Expand Down Expand Up @@ -556,9 +558,10 @@ impl<P: Deref> Pin<P> {
///
/// [`mem::swap`]: crate::mem::swap
#[lang = "new_unchecked"]
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin", since = "1.33.0")]
pub const unsafe fn new_unchecked(pointer: P) -> Pin<P> {
Pin { pointer }
}

Expand Down Expand Up @@ -589,9 +592,10 @@ impl<P: Deref> Pin<P> {
///
/// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
/// instead.
#[stable(feature = "pin_into_inner", since = "1.39.0")]
#[inline(always)]
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin_into_inner", since = "1.39.0")]
pub const unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
pin.pointer
}
}
Expand Down Expand Up @@ -693,17 +697,18 @@ impl<'a, T: ?Sized> Pin<&'a T> {
/// with the same lifetime as the original `Pin`.
///
/// ["pinning projections"]: self#projections-and-structural-pinning
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
pub fn get_ref(self) -> &'a T {
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
#[stable(feature = "pin", since = "1.33.0")]
pub const fn get_ref(self) -> &'a T {
self.pointer
}
}

impl<'a, T: ?Sized> Pin<&'a mut T> {
/// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
#[stable(feature = "pin", since = "1.33.0")]
#[inline(always)]
#[stable(feature = "pin", since = "1.33.0")]
pub fn into_ref(self) -> Pin<&'a T> {
Pin { pointer: self.pointer }
}
Expand Down
2 changes: 2 additions & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#![feature(iter_order_by)]
#![feature(cmp_min_max_by)]
#![feature(iter_map_while)]
#![feature(const_pin)]
#![feature(const_slice_from_raw_parts)]
#![feature(const_raw_ptr_deref)]
#![feature(never_type)]
Expand Down Expand Up @@ -74,6 +75,7 @@ mod num;
mod ops;
mod option;
mod pattern;
mod pin;
mod ptr;
mod result;
mod slice;
Expand Down
21 changes: 21 additions & 0 deletions library/core/tests/pin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use core::pin::Pin;

#[test]
fn pin_const() {
// test that the methods of `Pin` are usable in a const context

const POINTER: &'static usize = &2;

const PINNED: Pin<&'static usize> = Pin::new(POINTER);
const PINNED_UNCHECKED: Pin<&'static usize> = unsafe { Pin::new_unchecked(POINTER) };
assert_eq!(PINNED_UNCHECKED, PINNED);

const INNER: &'static usize = Pin::into_inner(PINNED);
assert_eq!(INNER, POINTER);

const INNER_UNCHECKED: &'static usize = unsafe { Pin::into_inner_unchecked(PINNED) };
assert_eq!(INNER_UNCHECKED, POINTER);

const REF: &'static usize = PINNED.get_ref();
assert_eq!(REF, POINTER)
}

0 comments on commit 8f27e3c

Please sign in to comment.