Skip to content

Commit

Permalink
Rollup merge of rust-lang#129668 - coolreader18:fix-pin-set-regr, r=d…
Browse files Browse the repository at this point in the history
…tolnay

Fix Pin::set bounds regression

Fixes rust-lang#129601

Fixes the regression from rust-lang#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`
  • Loading branch information
matthiaskrgr committed Aug 28, 2024
2 parents 472c964 + 0d6c915 commit 27d7fb0
Showing 1 changed file with 12 additions and 9 deletions.
21 changes: 12 additions & 9 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>`.
Expand Down Expand Up @@ -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) }
}
Expand All @@ -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>>
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 27d7fb0

Please sign in to comment.