Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
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
1 change: 0 additions & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1735,7 +1735,6 @@ symbols! {
unsafe_cell,
unsafe_cell_raw_get,
unsafe_no_drop_flag,
unsafe_pin_internals,
unsize,
unsized_fn_params,
unsized_locals,
Expand Down
24 changes: 13 additions & 11 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,7 @@ use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct Pin<P> {
// FIXME(#93176): this field is made `#[unstable] #[doc(hidden)] pub` to:
// - deter downstream users from accessing it (which would be unsound!),
// - let the `pin!` macro access it (such a macro requires using struct
// literal syntax in order to benefit from lifetime extension).
// Long-term, `unsafe` fields or macro hygiene are expected to offer more robust alternatives.
#[unstable(feature = "unsafe_pin_internals", issue = "none")]
#[doc(hidden)]
pub pointer: P,
pointer: P,
}

// The following implementations aren't derived in order to avoid soundness
Expand Down Expand Up @@ -1173,8 +1166,6 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
///
/// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin
#[stable(feature = "pin_macro", since = "1.68.0")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(unsafe_pin_internals)]
pub macro pin($value:expr $(,)?) {
// This is `Pin::new_unchecked(&mut { $value })`, so, for starters, let's
// review such a hypothetical macro (that any user-code could define):
Expand Down Expand Up @@ -1246,5 +1237,16 @@ pub macro pin($value:expr $(,)?) {
//
// See https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension
// for more info.
$crate::pin::Pin::<&mut _> { pointer: &mut { $value } }
//
// # Avoiding coercion
//
// We need to explicitly constrain the pointer type to avoid (unsound) coercion. Otherwise, you
// could write code like
// ```rust
// let rc = Rc::new(PhantomPinned);
// let _pinned: Pin<&PhantomPinned> = pin!(rc.clone());
// let moved = Rc::into_inner(rc).unwrap();
// ```
// since the `&mut Rc` is coerced to a `&PhantomPinned`.
Pin::<&mut _> { pointer: &mut { $value } }
}
11 changes: 11 additions & 0 deletions library/core/tests/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,14 @@ fn pin_const() {

pin_mut_const();
}

#[test]
fn dont_shadow() {
// test that the pointer field does not shadow fields of the pinned data.

struct Pinned {
pointer: i32,
}

let _: i32 = Pin::new(&mut Pinned { pointer: 0 }).pointer;
}
16 changes: 0 additions & 16 deletions tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs

This file was deleted.

15 changes: 0 additions & 15 deletions tests/ui/feature-gates/feature-gate-unsafe_pin_internals.stderr

This file was deleted.

2 changes: 1 addition & 1 deletion tests/ui/pin-macro/cant_access_internals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ use core::{

fn main() {
let mut phantom_pinned = pin!(PhantomPinned);
mem::take(phantom_pinned.pointer); //~ ERROR use of unstable library feature 'unsafe_pin_internals'
mem::take(phantom_pinned.pointer); //~ ERROR field `pointer` of struct `Pin` is private
}
10 changes: 4 additions & 6 deletions tests/ui/pin-macro/cant_access_internals.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
error[E0658]: use of unstable library feature 'unsafe_pin_internals'
--> $DIR/cant_access_internals.rs:11:15
error[E0616]: field `pointer` of struct `Pin` is private
--> $DIR/cant_access_internals.rs:11:30
|
LL | mem::take(phantom_pinned.pointer);
| ^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unsafe_pin_internals)]` to the crate attributes to enable
| ^^^^^^^ private field

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0658`.
For more information about this error, try `rustc --explain E0616`.