about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-28 17:12:20 +0200
committerGitHub <noreply@github.com>2024-08-28 17:12:20 +0200
commit27d7fb0cfad092c528b166e221a1f4ef8e60176e (patch)
treef61091b6cf7f45ed677594fe7e51bbb66aaa77cc
parent472c9645fbe24060f542d1a48656883db97391e8 (diff)
parent0d6c9152fa8cfaf4b430beef643565ede7de1067 (diff)
downloadrust-27d7fb0cfad092c528b166e221a1f4ef8e60176e.tar.gz
rust-27d7fb0cfad092c528b166e221a1f4ef8e60176e.zip
Rollup merge of #129668 - coolreader18:fix-pin-set-regr, r=dtolnay
Fix Pin::set bounds regression

Fixes #129601

Fixes the regression from #129449, where changing the bounds of the impl block containing `Pin::set` changed the method resolution behavior.

```rust
struct A;
impl A {
    fn set(&self) {}
}

let a: Pin<&A>;
a.set();
// before:
// - checks <impl<Ptr: DerefMut> Pin<Ptr>>::set(): `&A` doesn't impl `DerefMut`
// - autorefs -> &A: resolves to A::set()
// now:
// - checks <impl<Ptr: Deref> Pin<Ptr>>::set(): `&A` impls `Deref`! resolves to Pin::set()
// - check method bounds: `&A` doesn't impl DerefMut: error
```

r? `@dtolnay`
-rw-r--r--library/core/src/pin.rs21
1 files changed, 12 insertions, 9 deletions
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 780e476f531..65f6bfb7ee1 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1370,7 +1370,15 @@ impl<Ptr: Deref> Pin<Ptr> {
         // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&*self.__pointer) }
     }
+}
 
+// These methods being in a `Ptr: DerefMut` impl block concerns semver stability.
+// Currently, calling e.g. `.set()` on a `Pin<&T>` sees that `Ptr: DerefMut`
+// doesn't hold, and goes to check for a `.set()` method on `T`. But, if the
+// `where Ptr: DerefMut` bound is moved to the method, rustc sees the impl block
+// as a valid candidate, and doesn't go on to check other candidates when it
+// sees that the bound on the method.
+impl<Ptr: DerefMut> Pin<Ptr> {
     /// Gets a mutable reference to the pinned value this `Pin<Ptr>` points to.
     ///
     /// This is a generic method to go from `&mut Pin<Pointer<T>>` to `Pin<&mut T>`.
@@ -1402,10 +1410,7 @@ impl<Ptr: Deref> Pin<Ptr> {
     /// ```
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target>
-    where
-        Ptr: DerefMut,
-    {
+    pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> {
         // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&mut *self.__pointer) }
     }
@@ -1420,10 +1425,7 @@ impl<Ptr: Deref> Pin<Ptr> {
     #[unstable(feature = "pin_deref_mut", issue = "86918")]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline(always)]
-    pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target>
-    where
-        Ptr: DerefMut,
-    {
+    pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target> {
         // SAFETY: What we're asserting here is that going from
         //
         //     Pin<&mut Pin<Ptr>>
@@ -1475,12 +1477,13 @@ impl<Ptr: Deref> Pin<Ptr> {
     #[inline(always)]
     pub fn set(&mut self, value: Ptr::Target)
     where
-        Ptr: DerefMut,
         Ptr::Target: Sized,
     {
         *(self.__pointer) = value;
     }
+}
 
+impl<Ptr: Deref> Pin<Ptr> {
     /// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
     ///
     /// # Safety