Skip to content

Commit 8f27e3c

Browse files
committed
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: rust-lang#76654
1 parent 9891908 commit 8f27e3c

File tree

4 files changed

+40
-11
lines changed

4 files changed

+40
-11
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#![feature(const_int_pow)]
8181
#![feature(constctlz)]
8282
#![feature(const_panic)]
83+
#![feature(const_pin)]
8384
#![feature(const_fn_union)]
8485
#![feature(const_generics)]
8586
#![feature(const_option)]

library/core/src/pin.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,10 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
471471
///
472472
/// Unlike `Pin::new_unchecked`, this method is safe because the pointer
473473
/// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees.
474-
#[stable(feature = "pin", since = "1.33.0")]
475474
#[inline(always)]
476-
pub fn new(pointer: P) -> Pin<P> {
475+
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
476+
#[stable(feature = "pin", since = "1.33.0")]
477+
pub const fn new(pointer: P) -> Pin<P> {
477478
// SAFETY: the value pointed to is `Unpin`, and so has no requirements
478479
// around pinning.
479480
unsafe { Pin::new_unchecked(pointer) }
@@ -483,9 +484,10 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
483484
///
484485
/// This requires that the data inside this `Pin` is [`Unpin`] so that we
485486
/// can ignore the pinning invariants when unwrapping it.
486-
#[stable(feature = "pin_into_inner", since = "1.39.0")]
487487
#[inline(always)]
488-
pub fn into_inner(pin: Pin<P>) -> P {
488+
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
489+
#[stable(feature = "pin_into_inner", since = "1.39.0")]
490+
pub const fn into_inner(pin: Pin<P>) -> P {
489491
pin.pointer
490492
}
491493
}
@@ -556,9 +558,10 @@ impl<P: Deref> Pin<P> {
556558
///
557559
/// [`mem::swap`]: crate::mem::swap
558560
#[lang = "new_unchecked"]
559-
#[stable(feature = "pin", since = "1.33.0")]
560561
#[inline(always)]
561-
pub unsafe fn new_unchecked(pointer: P) -> Pin<P> {
562+
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
563+
#[stable(feature = "pin", since = "1.33.0")]
564+
pub const unsafe fn new_unchecked(pointer: P) -> Pin<P> {
562565
Pin { pointer }
563566
}
564567

@@ -589,9 +592,10 @@ impl<P: Deref> Pin<P> {
589592
///
590593
/// If the underlying data is [`Unpin`], [`Pin::into_inner`] should be used
591594
/// instead.
592-
#[stable(feature = "pin_into_inner", since = "1.39.0")]
593595
#[inline(always)]
594-
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
596+
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
597+
#[stable(feature = "pin_into_inner", since = "1.39.0")]
598+
pub const unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
595599
pin.pointer
596600
}
597601
}
@@ -693,17 +697,18 @@ impl<'a, T: ?Sized> Pin<&'a T> {
693697
/// with the same lifetime as the original `Pin`.
694698
///
695699
/// ["pinning projections"]: self#projections-and-structural-pinning
696-
#[stable(feature = "pin", since = "1.33.0")]
697700
#[inline(always)]
698-
pub fn get_ref(self) -> &'a T {
701+
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]
702+
#[stable(feature = "pin", since = "1.33.0")]
703+
pub const fn get_ref(self) -> &'a T {
699704
self.pointer
700705
}
701706
}
702707

703708
impl<'a, T: ?Sized> Pin<&'a mut T> {
704709
/// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
705-
#[stable(feature = "pin", since = "1.33.0")]
706710
#[inline(always)]
711+
#[stable(feature = "pin", since = "1.33.0")]
707712
pub fn into_ref(self) -> Pin<&'a T> {
708713
Pin { pointer: self.pointer }
709714
}

library/core/tests/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#![feature(iter_order_by)]
4040
#![feature(cmp_min_max_by)]
4141
#![feature(iter_map_while)]
42+
#![feature(const_pin)]
4243
#![feature(const_slice_from_raw_parts)]
4344
#![feature(const_raw_ptr_deref)]
4445
#![feature(never_type)]
@@ -74,6 +75,7 @@ mod num;
7475
mod ops;
7576
mod option;
7677
mod pattern;
78+
mod pin;
7779
mod ptr;
7880
mod result;
7981
mod slice;

library/core/tests/pin.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use core::pin::Pin;
2+
3+
#[test]
4+
fn pin_const() {
5+
// test that the methods of `Pin` are usable in a const context
6+
7+
const POINTER: &'static usize = &2;
8+
9+
const PINNED: Pin<&'static usize> = Pin::new(POINTER);
10+
const PINNED_UNCHECKED: Pin<&'static usize> = unsafe { Pin::new_unchecked(POINTER) };
11+
assert_eq!(PINNED_UNCHECKED, PINNED);
12+
13+
const INNER: &'static usize = Pin::into_inner(PINNED);
14+
assert_eq!(INNER, POINTER);
15+
16+
const INNER_UNCHECKED: &'static usize = unsafe { Pin::into_inner_unchecked(PINNED) };
17+
assert_eq!(INNER_UNCHECKED, POINTER);
18+
19+
const REF: &'static usize = PINNED.get_ref();
20+
assert_eq!(REF, POINTER)
21+
}

0 commit comments

Comments
 (0)