about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNoa <coolreader18@gmail.com>2024-08-22 14:42:24 -0500
committerNoa <coolreader18@gmail.com>2024-08-23 12:45:05 -0500
commitb968b26c03510c80782c4524a334f5fa440cb2d8 (patch)
tree4b42ca6dd8a027638f667d49b9b32f07c7a1df4a
parent5ad98b4026d5172f27615b105658bc8bfd677be8 (diff)
Put Pin::as_deref_mut in impl Pin<Ptr>
-rw-r--r--library/core/src/pin.rs121
1 files changed, 62 insertions, 59 deletions
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 0569b8b7624..1ad509892d2 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1291,8 +1291,8 @@ impl<Ptr: Deref> Pin<Ptr> {
     ///     // Now, if `x` was the only reference, we have a mutable reference to
     ///     // data that we pinned above, which we could use to move it as we have
     ///     // seen in the previous example. We have violated the pinning API contract.
-    ///  }
-    ///  ```
+    /// }
+    /// ```
     ///
     /// ## Pinning of closure captures
     ///
@@ -1356,20 +1356,6 @@ impl<Ptr: Deref> Pin<Ptr> {
         Pin { __pointer: pointer }
     }
 
-    /// Gets a shared reference to the pinned value this [`Pin`] points to.
-    ///
-    /// This is a generic method to go from `&Pin<Pointer<T>>` to `Pin<&T>`.
-    /// It is safe because, as part of the contract of `Pin::new_unchecked`,
-    /// the pointee cannot move after `Pin<Pointer<T>>` got created.
-    /// "Malicious" implementations of `Pointer::Deref` are likewise
-    /// ruled out by the contract of `Pin::new_unchecked`.
-    #[stable(feature = "pin", since = "1.33.0")]
-    #[inline(always)]
-    pub fn as_ref(&self) -> Pin<&Ptr::Target> {
-        // SAFETY: see documentation on this function
-        unsafe { Pin::new_unchecked(&*self.__pointer) }
-    }
-
     /// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
     ///
     /// # Safety
@@ -1394,9 +1380,21 @@ impl<Ptr: Deref> Pin<Ptr> {
     pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
         pin.__pointer
     }
-}
 
-impl<Ptr: DerefMut> Pin<Ptr> {
+    /// Gets a shared reference to the pinned value this [`Pin`] points to.
+    ///
+    /// This is a generic method to go from `&Pin<Pointer<T>>` to `Pin<&T>`.
+    /// It is safe because, as part of the contract of `Pin::new_unchecked`,
+    /// the pointee cannot move after `Pin<Pointer<T>>` got created.
+    /// "Malicious" implementations of `Pointer::Deref` are likewise
+    /// ruled out by the contract of `Pin::new_unchecked`.
+    #[stable(feature = "pin", since = "1.33.0")]
+    #[inline(always)]
+    pub fn as_ref(&self) -> Pin<&Ptr::Target> {
+        // SAFETY: see documentation on this function
+        unsafe { Pin::new_unchecked(&*self.__pointer) }
+    }
+
     /// 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>`.
@@ -1428,11 +1426,55 @@ impl<Ptr: DerefMut> Pin<Ptr> {
     /// ```
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> {
+    pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target>
+    where
+        Ptr: DerefMut,
+    {
         // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&mut *self.__pointer) }
     }
 
+    /// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
+    ///
+    /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
+    /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
+    /// move in the future, and this method does not enable the pointee to move. "Malicious"
+    /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
+    /// `Pin::new_unchecked`.
+    #[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,
+    {
+        // SAFETY: What we're asserting here is that going from
+        //
+        //     Pin<&mut Pin<Ptr>>
+        //
+        // to
+        //
+        //     Pin<&mut Ptr::Target>
+        //
+        // is safe.
+        //
+        // We need to ensure that two things hold for that to be the case:
+        //
+        // 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
+        // 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
+        // `Pin<&mut Pin<Ptr>>`
+        //
+        // The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
+        // `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
+        // `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
+        // on the fact that `Ptr` is _also_ pinned.
+        //
+        // For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
+        // `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
+        // any access to the `Ptr` itself, much less the `Pin<Ptr>`.
+        unsafe { self.get_unchecked_mut() }.as_mut()
+    }
+
     /// Assigns a new value to the memory location pointed to by the `Pin<Ptr>`.
     ///
     /// This overwrites pinned data, but that is okay: the original pinned value's destructor gets
@@ -1457,6 +1499,7 @@ impl<Ptr: DerefMut> Pin<Ptr> {
     #[inline(always)]
     pub fn set(&mut self, value: Ptr::Target)
     where
+        Ptr: DerefMut,
         Ptr::Target: Sized,
     {
         *(self.__pointer) = value;
@@ -1613,46 +1656,6 @@ impl<T: ?Sized> Pin<&'static T> {
     }
 }
 
-impl<'a, Ptr: DerefMut> Pin<&'a mut Pin<Ptr>> {
-    /// Gets `Pin<&mut T>` to the underlying pinned value from this nested `Pin`-pointer.
-    ///
-    /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
-    /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
-    /// move in the future, and this method does not enable the pointee to move. "Malicious"
-    /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of
-    /// `Pin::new_unchecked`.
-    #[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<&'a mut Ptr::Target> {
-        // SAFETY: What we're asserting here is that going from
-        //
-        //     Pin<&mut Pin<Ptr>>
-        //
-        // to
-        //
-        //     Pin<&mut Ptr::Target>
-        //
-        // is safe.
-        //
-        // We need to ensure that two things hold for that to be the case:
-        //
-        // 1) Once we give out a `Pin<&mut Ptr::Target>`, a `&mut Ptr::Target` will not be given out.
-        // 2) By giving out a `Pin<&mut Ptr::Target>`, we do not risk violating
-        // `Pin<&mut Pin<Ptr>>`
-        //
-        // The existence of `Pin<Ptr>` is sufficient to guarantee #1: since we already have a
-        // `Pin<Ptr>`, it must already uphold the pinning guarantees, which must mean that
-        // `Pin<&mut Ptr::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
-        // on the fact that `Ptr` is _also_ pinned.
-        //
-        // For #2, we need to ensure that code given a `Pin<&mut Ptr::Target>` cannot cause the
-        // `Pin<Ptr>` to move? That is not possible, since `Pin<&mut Ptr::Target>` no longer retains
-        // any access to the `Ptr` itself, much less the `Pin<Ptr>`.
-        unsafe { self.get_unchecked_mut() }.as_mut()
-    }
-}
-
 impl<T: ?Sized> Pin<&'static mut T> {
     /// Gets a pinning mutable reference from a static mutable reference.
     ///