-
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? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 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 = "none")] | ||
jonhoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[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.