Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make some methods of Pin unstable const #76655

Merged
merged 2 commits into from
Sep 22, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Make some methods of Pin unstable const
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: #76654
  • Loading branch information
CDirkx committed Sep 12, 2020
commit 8f27e3cb1b4140d9124d60df0850ef734e73b884
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)
}