Skip to content

Commit f43940b

Browse files
committed
Move Pin::as_deref_mut to the same impl block as as_mut
1 parent 5ad98b4 commit f43940b

File tree

1 file changed

+39
-41
lines changed

1 file changed

+39
-41
lines changed

library/core/src/pin.rs

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ impl<Ptr: Deref> Pin<Ptr> {
12921292
/// // data that we pinned above, which we could use to move it as we have
12931293
/// // seen in the previous example. We have violated the pinning API contract.
12941294
/// }
1295-
/// ```
1295+
/// ```
12961296
///
12971297
/// ## Pinning of closure captures
12981298
///
@@ -1433,6 +1433,44 @@ impl<Ptr: DerefMut> Pin<Ptr> {
14331433
unsafe { Pin::new_unchecked(&mut *self.__pointer) }
14341434
}
14351435

1436+
/// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
1437+
///
1438+
/// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
1439+
/// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
1440+
/// move in the future, and this method does not enable the pointee to move. "Malicious"
1441+
/// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
1442+
/// `Pin::new_unchecked`.
1443+
#[unstable(feature = "pin_deref_mut", issue = "86918")]
1444+
#[must_use = "`self` will be dropped if the result is not used"]
1445+
#[inline(always)]
1446+
pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target> {
1447+
// SAFETY: What we're asserting here is that going from
1448+
//
1449+
// Pin<&mut Pin<Ptr>>
1450+
//
1451+
// to
1452+
//
1453+
// Pin<&mut Ptr::Target>
1454+
//
1455+
// is safe.
1456+
//
1457+
// We need to ensure that two things hold for that to be the case:
1458+
//
1459+
// 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
1460+
// 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
1461+
// `Pin<&mut Pin<Ptr>>`
1462+
//
1463+
// The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
1464+
// `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
1465+
// `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
1466+
// on the fact that `Ptr` is _also_ pinned.
1467+
//
1468+
// For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
1469+
// `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
1470+
// any access to the `Ptr` itself, much less the `Pin<Ptr>`.
1471+
unsafe { self.get_unchecked_mut() }.as_mut()
1472+
}
1473+
14361474
/// Assigns a new value to the memory location pointed to by the `Pin<Ptr>`.
14371475
///
14381476
/// This overwrites pinned data, but that is okay: the original pinned value's destructor gets
@@ -1613,46 +1651,6 @@ impl<T: ?Sized> Pin<&'static T> {
16131651
}
16141652
}
16151653

1616-
impl<'a, Ptr: DerefMut> Pin<&'a mut Pin<Ptr>> {
1617-
/// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
1618-
///
1619-
/// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
1620-
/// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
1621-
/// move in the future, and this method does not enable the pointee to move. "Malicious"
1622-
/// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
1623-
/// `Pin::new_unchecked`.
1624-
#[unstable(feature = "pin_deref_mut", issue = "86918")]
1625-
#[must_use = "`self` will be dropped if the result is not used"]
1626-
#[inline(always)]
1627-
pub fn as_deref_mut(self) -> Pin<&'a mut Ptr::Target> {
1628-
// SAFETY: What we're asserting here is that going from
1629-
//
1630-
// Pin<&mut Pin<Ptr>>
1631-
//
1632-
// to
1633-
//
1634-
// Pin<&mut Ptr::Target>
1635-
//
1636-
// is safe.
1637-
//
1638-
// We need to ensure that two things hold for that to be the case:
1639-
//
1640-
// 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
1641-
// 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
1642-
// `Pin<&mut Pin<Ptr>>`
1643-
//
1644-
// The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
1645-
// `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
1646-
// `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
1647-
// on the fact that `Ptr` is _also_ pinned.
1648-
//
1649-
// For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
1650-
// `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
1651-
// any access to the `Ptr` itself, much less the `Pin<Ptr>`.
1652-
unsafe { self.get_unchecked_mut() }.as_mut()
1653-
}
1654-
}
1655-
16561654
impl<T: ?Sized> Pin<&'static mut T> {
16571655
/// Gets a pinning mutable reference from a static mutable reference.
16581656
///

0 commit comments

Comments
 (0)