diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-01-26 23:15:49 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-26 23:15:49 +0100 |
| commit | 346397d081d289db20bc5cbdc23c96e00e60825f (patch) | |
| tree | 3a8002304fb5be76fdd672b914bb2da34ba30221 | |
| parent | 7f1936556083dd93cfe4b1640f2f6eba50ed3995 (diff) | |
| parent | bc3fb5245a248070b76e535be4f342e2be12a9b5 (diff) | |
| download | rust-346397d081d289db20bc5cbdc23c96e00e60825f.tar.gz rust-346397d081d289db20bc5cbdc23c96e00e60825f.zip | |
Rollup merge of #119562 - LegionMammal978:rename-pin-pointer, r=Amanieu,dtolnay
Rename `pointer` field on `Pin`
A few days ago, I was helping another user create a self-referential type using `PhantomPinned`. However, I noticed an odd behavior when I tried to access one of the type's fields via `Pin`'s `Deref` impl:
```rust
use std::{marker::PhantomPinned, ptr};
struct Pinned {
data: i32,
pointer: *const i32,
_pin: PhantomPinned,
}
fn main() {
let mut b = Box::pin(Pinned {
data: 42,
pointer: ptr::null(),
_pin: PhantomPinned,
});
{
let pinned = unsafe { b.as_mut().get_unchecked_mut() };
pinned.pointer = &pinned.data;
}
println!("{}", unsafe { *b.pointer });
}
```
```rust
error[E0658]: use of unstable library feature 'unsafe_pin_internals'
--> <source>:19:30
|
19 | println!("{}", unsafe { *b.pointer });
| ^^^^^^^^^
error[E0277]: `Pinned` doesn't implement `std::fmt::Display`
--> <source>:19:20
|
19 | println!("{}", unsafe { *b.pointer });
| ^^^^^^^^^^^^^^^^^^^^^ `Pinned` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Pinned`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Since the user named their field `pointer`, it conflicts with the `pointer` field on `Pin`, which is public but unstable since Rust 1.60.0 with #93176. On versions from 1.33.0 to 1.59.0, where the field on `Pin` is private, this program compiles and prints `42` as expected.
To avoid this confusing behavior, this PR renames `pointer` to `__pointer`, so that it's less likely to conflict with a `pointer` field on the underlying type, as accessed through the `Deref` impl. This is technically a breaking change for anyone who names their field `__pointer` on the inner type; if this is undesirable, it could be renamed to something more longwinded. It's also a nightly breaking change for any external users of `unsafe_pin_internals`.
8 files changed, 35 insertions, 29 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 7780ceda1c1..896d000233a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2040,7 +2040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_is_local = sole_field.did.is_local(); let field_is_accessible = sole_field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx) - // Skip suggestions for unstable public fields (for example `Pin::pointer`) + // Skip suggestions for unstable public fields (for example `Pin::__pointer`) && matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked); if !field_is_local && !field_is_accessible { diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index bb6c81a486a..a0227d9130b 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1092,14 +1092,20 @@ pub struct Pin<Ptr> { // - 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. + // + // However, if the `Deref` impl exposes a field with the same name as this + // field, then the two will collide, resulting in a confusing error when the + // user attempts to access the field through a `Pin<Ptr>`. Therefore, the + // name `__pointer` is designed to be unlikely to collide with any other + // field. Long-term, macro hygiene is expected to offer a more robust + // alternative, alongside `unsafe` fields. #[unstable(feature = "unsafe_pin_internals", issue = "none")] #[doc(hidden)] - pub pointer: Ptr, + pub __pointer: Ptr, } // The following implementations aren't derived in order to avoid soundness -// issues. `&self.pointer` should not be accessible to untrusted trait +// issues. `&self.__pointer` should not be accessible to untrusted trait // implementations. // // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> for more details. @@ -1212,7 +1218,7 @@ impl<Ptr: Deref<Target: Unpin>> Pin<Ptr> { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin_into_inner", since = "1.39.0")] pub const fn into_inner(pin: Pin<Ptr>) -> Ptr { - pin.pointer + pin.__pointer } } @@ -1349,7 +1355,7 @@ impl<Ptr: Deref> Pin<Ptr> { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] pub const unsafe fn new_unchecked(pointer: Ptr) -> Pin<Ptr> { - Pin { pointer } + Pin { __pointer: pointer } } /// Gets a shared reference to the pinned value this [`Pin`] points to. @@ -1363,7 +1369,7 @@ impl<Ptr: Deref> Pin<Ptr> { #[inline(always)] pub fn as_ref(&self) -> Pin<&Ptr::Target> { // SAFETY: see documentation on this function - unsafe { Pin::new_unchecked(&*self.pointer) } + unsafe { Pin::new_unchecked(&*self.__pointer) } } /// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`. @@ -1388,7 +1394,7 @@ impl<Ptr: Deref> Pin<Ptr> { #[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<Ptr>) -> Ptr { - pin.pointer + pin.__pointer } } @@ -1426,7 +1432,7 @@ impl<Ptr: DerefMut> Pin<Ptr> { #[inline(always)] pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> { // SAFETY: see documentation on this function - unsafe { Pin::new_unchecked(&mut *self.pointer) } + unsafe { Pin::new_unchecked(&mut *self.__pointer) } } /// Assigns a new value to the memory location pointed to by the `Pin<Ptr>`. @@ -1455,7 +1461,7 @@ impl<Ptr: DerefMut> Pin<Ptr> { where Ptr::Target: Sized, { - *(self.pointer) = value; + *(self.__pointer) = value; } } @@ -1481,7 +1487,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { U: ?Sized, F: FnOnce(&T) -> &U, { - let pointer = &*self.pointer; + let pointer = &*self.__pointer; let new_pointer = func(pointer); // SAFETY: the safety contract for `new_unchecked` must be @@ -1511,7 +1517,7 @@ impl<'a, T: ?Sized> Pin<&'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 + self.__pointer } } @@ -1522,7 +1528,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] pub const fn into_ref(self) -> Pin<&'a T> { - Pin { pointer: self.pointer } + Pin { __pointer: self.__pointer } } /// Gets a mutable reference to the data inside of this `Pin`. @@ -1542,7 +1548,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { where T: Unpin, { - self.pointer + self.__pointer } /// Gets a mutable reference to the data inside of this `Pin`. @@ -1560,7 +1566,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { #[stable(feature = "pin", since = "1.33.0")] #[rustc_const_unstable(feature = "const_pin", issue = "76654")] pub const unsafe fn get_unchecked_mut(self) -> &'a mut T { - self.pointer + self.__pointer } /// Construct a new pin by mapping the interior value. @@ -1684,21 +1690,21 @@ impl<Ptr: Receiver> Receiver for Pin<Ptr> {} #[stable(feature = "pin", since = "1.33.0")] impl<Ptr: fmt::Debug> fmt::Debug for Pin<Ptr> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.pointer, f) + fmt::Debug::fmt(&self.__pointer, f) } } #[stable(feature = "pin", since = "1.33.0")] impl<Ptr: fmt::Display> fmt::Display for Pin<Ptr> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.pointer, f) + fmt::Display::fmt(&self.__pointer, f) } } #[stable(feature = "pin", since = "1.33.0")] impl<Ptr: fmt::Pointer> fmt::Pointer for Pin<Ptr> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&self.pointer, f) + fmt::Pointer::fmt(&self.__pointer, f) } } @@ -1941,16 +1947,16 @@ pub macro pin($value:expr $(,)?) { // instead, dropped _at the end of the enscoping block_. // For instance, // ```rust - // let p = Pin { pointer: &mut <temporary> }; + // let p = Pin { __pointer: &mut <temporary> }; // ``` // becomes: // ```rust // let mut anon = <temporary>; - // let p = Pin { pointer: &mut anon }; + // let p = Pin { __pointer: &mut anon }; // ``` // which is *exactly* what we want. // // 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 } } + $crate::pin::Pin::<&mut _> { __pointer: &mut { $value } } } diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index 624d8cc5cc5..f8569ef2594 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -99,9 +99,9 @@ </Type> <Type Name="core::pin::Pin<*>"> - <DisplayString>Pin({(void*)pointer}: {pointer})</DisplayString> + <DisplayString>Pin({(void*)__pointer}: {__pointer})</DisplayString> <Expand> - <ExpandedItem>pointer</ExpandedItem> + <ExpandedItem>__pointer</ExpandedItem> </Expand> </Type> diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff index 8e53427e7e0..a38b8246bde 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff @@ -36,7 +36,7 @@ - _4 = g() -> [return: bb1, unwind unreachable]; + _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index b06db41af9d..dc6628ab44c 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -36,7 +36,7 @@ - _4 = g() -> [return: bb1, unwind continue]; + _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs index 134ea25b75a..594a2672d43 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs @@ -7,7 +7,7 @@ use core::{marker::PhantomPinned, pin::Pin}; /// The `unsafe_pin_internals` is indeed unsound. fn non_unsafe_pin_new_unchecked<T>(pointer: &mut T) -> Pin<&mut T> { - Pin { pointer } + Pin { __pointer: pointer } } fn main() { diff --git a/tests/ui/pin-macro/cant_access_internals.rs b/tests/ui/pin-macro/cant_access_internals.rs index 5826a18b571..4aeb6a643d9 100644 --- a/tests/ui/pin-macro/cant_access_internals.rs +++ b/tests/ui/pin-macro/cant_access_internals.rs @@ -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 use of unstable library feature 'unsafe_pin_internals' } diff --git a/tests/ui/pin-macro/cant_access_internals.stderr b/tests/ui/pin-macro/cant_access_internals.stderr index 2737b84f599..444314a9d8b 100644 --- a/tests/ui/pin-macro/cant_access_internals.stderr +++ b/tests/ui/pin-macro/cant_access_internals.stderr @@ -1,8 +1,8 @@ error[E0658]: use of unstable library feature 'unsafe_pin_internals' --> $DIR/cant_access_internals.rs:11:15 | -LL | mem::take(phantom_pinned.pointer); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | mem::take(phantom_pinned.__pointer); + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unsafe_pin_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
