diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-08-28 17:12:20 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-28 17:12:20 +0200 |
| commit | 27d7fb0cfad092c528b166e221a1f4ef8e60176e (patch) | |
| tree | f61091b6cf7f45ed677594fe7e51bbb66aaa77cc | |
| parent | 472c9645fbe24060f542d1a48656883db97391e8 (diff) | |
| parent | 0d6c9152fa8cfaf4b430beef643565ede7de1067 (diff) | |
| download | rust-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.rs | 21 |
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 |
