Skip to content

Commit b968b26

Browse files
committed
Put Pin::as_deref_mut in impl Pin<Ptr>
1 parent 5ad98b4 commit b968b26

File tree

1 file changed

+62
-59
lines changed

1 file changed

+62
-59
lines changed

library/core/src/pin.rs

+62-59
Original file line numberDiff line numberDiff line change
@@ -1291,8 +1291,8 @@ impl<Ptr: Deref> Pin<Ptr> {
12911291
/// // Now, if `x` was the only reference, we have a mutable reference to
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.
1294-
/// }
1295-
/// ```
1294+
/// }
1295+
/// ```
12961296
///
12971297
/// ## Pinning of closure captures
12981298
///
@@ -1356,20 +1356,6 @@ impl<Ptr: Deref> Pin<Ptr> {
13561356
Pin { __pointer: pointer }
13571357
}
13581358

1359-
/// Gets a shared reference to the pinned value this [`Pin`] points to.
1360-
///
1361-
/// This is a generic method to go from `&Pin<Pointer<T>>` to `Pin<&T>`.
1362-
/// It is safe because, as part of the contract of `Pin::new_unchecked`,
1363-
/// the pointee cannot move after `Pin<Pointer<T>>` got created.
1364-
/// "Malicious" implementations of `Pointer::Deref` are likewise
1365-
/// ruled out by the contract of `Pin::new_unchecked`.
1366-
#[stable(feature = "pin", since = "1.33.0")]
1367-
#[inline(always)]
1368-
pub fn as_ref(&self) -> Pin<&Ptr::Target> {
1369-
// SAFETY: see documentation on this function
1370-
unsafe { Pin::new_unchecked(&*self.__pointer) }
1371-
}
1372-
13731359
/// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
13741360
///
13751361
/// # Safety
@@ -1394,9 +1380,21 @@ impl<Ptr: Deref> Pin<Ptr> {
13941380
pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
13951381
pin.__pointer
13961382
}
1397-
}
13981383

1399-
impl<Ptr: DerefMut> Pin<Ptr> {
1384+
/// Gets a shared reference to the pinned value this [`Pin`] points to.
1385+
///
1386+
/// This is a generic method to go from `&Pin<Pointer<T>>` to `Pin<&T>`.
1387+
/// It is safe because, as part of the contract of `Pin::new_unchecked`,
1388+
/// the pointee cannot move after `Pin<Pointer<T>>` got created.
1389+
/// "Malicious" implementations of `Pointer::Deref` are likewise
1390+
/// ruled out by the contract of `Pin::new_unchecked`.
1391+
#[stable(feature = "pin", since = "1.33.0")]
1392+
#[inline(always)]
1393+
pub fn as_ref(&self) -> Pin<&Ptr::Target> {
1394+
// SAFETY: see documentation on this function
1395+
unsafe { Pin::new_unchecked(&*self.__pointer) }
1396+
}
1397+
14001398
/// Gets a mutable reference to the pinned value this `Pin<Ptr>` points to.
14011399
///
14021400
/// This is a generic method to go from `&mut Pin<Pointer<T>>` to `Pin<&mut T>`.
@@ -1428,11 +1426,55 @@ impl<Ptr: DerefMut> Pin<Ptr> {
14281426
/// ```
14291427
#[stable(feature = "pin", since = "1.33.0")]
14301428
#[inline(always)]
1431-
pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> {
1429+
pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target>
1430+
where
1431+
Ptr: DerefMut,
1432+
{
14321433
// SAFETY: see documentation on this function
14331434
unsafe { Pin::new_unchecked(&mut *self.__pointer) }
14341435
}
14351436

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

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-
16561659
impl<T: ?Sized> Pin<&'static mut T> {
16571660
/// Gets a pinning mutable reference from a static mutable reference.
16581661
///

0 commit comments

Comments
 (0)