From f4fa9196d2768f31fcc7b3a75d48a212c83d51de Mon Sep 17 00:00:00 2001 From: Theemathas Chirananthavat Date: Sat, 22 Nov 2025 22:58:39 +0700 Subject: [PATCH] Make PinCoerceUnsized require Deref Also, delete impls on non-Deref types. Pin doesn't do anything useful for non-Deref types, so PinCoerceUnsized on such types makes no sense. This is a breaking change, since stable code can observe the deleted `PinCoerceUnsized` impls by uselessly coercing between such types inside a `Pin`. There is still some strange behavior, such as `Pin<&mut i32>` being able to coerce to `Pin<&dyn Send>`, but not being able to coerce to `Pin<&i32>`. However, I don't think it's possible to fix this. Fixes https://github.com/rust-lang/rust/issues/145081 --- library/alloc/src/rc.rs | 3 --- library/alloc/src/sync.rs | 3 --- library/core/src/cell.rs | 12 ------------ library/core/src/pin.rs | 8 +------- library/core/src/ptr/non_null.rs | 4 ---- library/core/src/ptr/unique.rs | 4 ---- library/coretests/tests/pin.rs | 25 ------------------------- 7 files changed, 1 insertion(+), 58 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 0ab019a68ea05..bc6a5ac9f7184 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2341,9 +2341,6 @@ unsafe impl PinCoerceUnsized for Rc {} #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl PinCoerceUnsized for UniqueRc {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for Weak {} - #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Rc {} diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index c302f35e5ed6e..423eb851efbcd 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2330,9 +2330,6 @@ impl Deref for Arc { #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl PinCoerceUnsized for Arc {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for Weak {} - #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Arc {} diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 988c50795e299..4894d08365482 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2679,18 +2679,6 @@ fn assert_coerce_unsized( let _: RefCell<&dyn Send> = d; } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for UnsafeCell {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for SyncUnsafeCell {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for Cell {} - -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for RefCell {} - #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] unsafe impl<'b, T: ?Sized> PinCoerceUnsized for Ref<'b, T> {} diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 81c2dabf0d1d8..6db8b880c4f7a 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1844,7 +1844,7 @@ where /// to. The concrete type of a slice is an array of the same element type and /// the length specified in the metadata. The concrete type of a sized type /// is the type itself. -pub unsafe trait PinCoerceUnsized {} +pub unsafe trait PinCoerceUnsized: Deref {} #[stable(feature = "pin", since = "1.33.0")] unsafe impl<'a, T: ?Sized> PinCoerceUnsized for &'a T {} @@ -1855,12 +1855,6 @@ unsafe impl<'a, T: ?Sized> PinCoerceUnsized for &'a mut T {} #[stable(feature = "pin", since = "1.33.0")] unsafe impl PinCoerceUnsized for Pin {} -#[stable(feature = "pin", since = "1.33.0")] -unsafe impl PinCoerceUnsized for *const T {} - -#[stable(feature = "pin", since = "1.33.0")] -unsafe impl PinCoerceUnsized for *mut T {} - /// Constructs a [Pin]<[&mut] T>, by pinning a `value: T` locally. /// /// Unlike [`Box::pin`], this does not create a new heap allocation. As explained diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index aa3af2f185287..5faa74955568e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -4,7 +4,6 @@ use crate::marker::{Destruct, PointeeSized, Unsize}; use crate::mem::{MaybeUninit, SizedTypeProperties}; use crate::num::NonZero; use crate::ops::{CoerceUnsized, DispatchFromDyn}; -use crate::pin::PinCoerceUnsized; use crate::ptr::Unique; use crate::slice::{self, SliceIndex}; use crate::ub_checks::assert_unsafe_precondition; @@ -1664,9 +1663,6 @@ impl CoerceUnsized> for NonNull #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl DispatchFromDyn> for NonNull where T: Unsize {} -#[stable(feature = "pin", since = "1.33.0")] -unsafe impl PinCoerceUnsized for NonNull {} - #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 5e7b1f7038024..b97e07a787eea 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -2,7 +2,6 @@ use crate::clone::TrivialClone; use crate::fmt; use crate::marker::{PhantomData, PointeeSized, Unsize}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; -use crate::pin::PinCoerceUnsized; use crate::ptr::NonNull; /// A wrapper around a raw non-null `*mut T` that indicates that the possessor @@ -176,9 +175,6 @@ impl CoerceUnsized> for Unique wh #[unstable(feature = "ptr_internals", issue = "none")] impl DispatchFromDyn> for Unique where T: Unsize {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl PinCoerceUnsized for Unique {} - #[unstable(feature = "ptr_internals", issue = "none")] impl fmt::Debug for Unique { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/coretests/tests/pin.rs b/library/coretests/tests/pin.rs index b3fb06e710d44..37a729ae4f1c4 100644 --- a/library/coretests/tests/pin.rs +++ b/library/coretests/tests/pin.rs @@ -45,22 +45,6 @@ mod pin_coerce_unsized { pub trait MyTrait {} impl MyTrait for String {} - // These Pins should continue to compile. - // Do note that these instances of Pin types cannot be used - // meaningfully because all methods require a Deref/DerefMut - // bounds on the pointer type and Cell, RefCell and UnsafeCell - // do not implement Deref/DerefMut. - - pub fn cell(arg: Pin>>) -> Pin>> { - arg - } - pub fn ref_cell(arg: Pin>>) -> Pin>> { - arg - } - pub fn unsafe_cell(arg: Pin>>) -> Pin>> { - arg - } - // These sensible Pin coercions are possible. pub fn pin_mut_ref(arg: Pin<&mut String>) -> Pin<&mut dyn MyTrait> { arg @@ -68,15 +52,6 @@ mod pin_coerce_unsized { pub fn pin_ref(arg: Pin<&String>) -> Pin<&dyn MyTrait> { arg } - pub fn pin_ptr(arg: Pin<*const String>) -> Pin<*const dyn MyTrait> { - arg - } - pub fn pin_ptr_mut(arg: Pin<*mut String>) -> Pin<*mut dyn MyTrait> { - arg - } - pub fn pin_non_null(arg: Pin>) -> Pin> { - arg - } pub fn nesting_pins(arg: Pin>) -> Pin> { arg }