-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Remove P: Unpin bound on impl Future for Pin #81363
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -802,6 +802,44 @@ impl<T: ?Sized> Pin<&'static T> { | |
} | ||
} | ||
|
||
impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> { | ||
/// Gets a pinned mutable reference from this nested pinned 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 `P::DerefMut` are likewise ruled out by the contract of | ||
/// `Pin::new_unchecked`. | ||
#[unstable(feature = "pin_deref_mut", issue = "86918")] | ||
#[inline(always)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We generally use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used |
||
pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> { | ||
// SAFETY: What we're asserting here is that going from | ||
// | ||
// Pin<&mut Pin<P>> | ||
// | ||
// to | ||
// | ||
// Pin<&mut P::Target> | ||
// | ||
// is safe. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My own justification attempts to follow the invariant I sketched here. First of all, it seems like Thus we can turn |
||
// | ||
// We need to ensure that two things hold for that to be the case: | ||
// | ||
// 1) Once we give out a `Pin<&mut P::Target>`, an `&mut P::Target` will not be given out. | ||
// 2) By giving out a `Pin<&mut P::Target>`, we do not risk of violating `Pin<&mut Pin<P>>` | ||
// | ||
// The existence of `Pin<P>` is sufficient to guarantee #1: since we already have a | ||
// `Pin<P>`, it must already uphold the pinning guarantees, which must mean that | ||
// `Pin<&mut P::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely | ||
// on the fact that P is _also_ pinned. | ||
// | ||
// For #2, we need to ensure that code given a `Pin<&mut P::Target>` cannot cause the | ||
// `Pin<P>` to move? That is not possible, since `Pin<&mut P::Target>` no longer retains | ||
// any access to the `P` itself, much less the `Pin<P>`. | ||
unsafe { self.get_unchecked_mut() }.as_mut() | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Pin<&'static mut T> { | ||
/// Get a pinned mutable reference from a static mutable reference. | ||
/// | ||
|
Uh oh!
There was an error while loading. Please reload this page.