Put Pin::as_deref_mut in impl Pin<Ptr>
This commit is contained in:
parent
5ad98b4026
commit
b968b26c03
@ -1291,8 +1291,8 @@ impl<Ptr: Deref> Pin<Ptr> {
|
|||||||
/// // Now, if `x` was the only reference, we have a mutable reference to
|
/// // 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
|
/// // 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.
|
/// // seen in the previous example. We have violated the pinning API contract.
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ## Pinning of closure captures
|
/// ## Pinning of closure captures
|
||||||
///
|
///
|
||||||
@ -1356,20 +1356,6 @@ impl<Ptr: Deref> Pin<Ptr> {
|
|||||||
Pin { __pointer: pointer }
|
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`.
|
/// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -1394,9 +1380,21 @@ pub fn as_ref(&self) -> Pin<&Ptr::Target> {
|
|||||||
pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
|
pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
|
||||||
pin.__pointer
|
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.
|
/// 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>`.
|
/// 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")]
|
#[stable(feature = "pin", since = "1.33.0")]
|
||||||
#[inline(always)]
|
#[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
|
// SAFETY: see documentation on this function
|
||||||
unsafe { Pin::new_unchecked(&mut *self.__pointer) }
|
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>`.
|
/// 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
|
/// This overwrites pinned data, but that is okay: the original pinned value's destructor gets
|
||||||
@ -1457,6 +1499,7 @@ pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set(&mut self, value: Ptr::Target)
|
pub fn set(&mut self, value: Ptr::Target)
|
||||||
where
|
where
|
||||||
|
Ptr: DerefMut,
|
||||||
Ptr::Target: Sized,
|
Ptr::Target: Sized,
|
||||||
{
|
{
|
||||||
*(self.__pointer) = value;
|
*(self.__pointer) = value;
|
||||||
@ -1613,46 +1656,6 @@ pub const fn static_ref(r: &'static T) -> 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> {
|
impl<T: ?Sized> Pin<&'static mut T> {
|
||||||
/// Gets a pinning mutable reference from a static mutable reference.
|
/// Gets a pinning mutable reference from a static mutable reference.
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user