poll_fn and Unpin: fix pinning

This commit is contained in:
Ralf Jung 2022-10-06 13:36:07 +02:00
parent c97d02cdb5
commit 17d78c4ef9

View File

@ -5,7 +5,9 @@
/// Creates a future that wraps a function returning [`Poll`]. /// Creates a future that wraps a function returning [`Poll`].
/// ///
/// Polling the future delegates to the wrapped function. /// Polling the future delegates to the wrapped function. If the returned future is pinned, then the
/// captured environment of the wrapped function is also pinned in-place, so as long as the closure
/// does not move out of its captures it can soundly create pinned references to them.
/// ///
/// # Examples /// # Examples
/// ///
@ -41,7 +43,7 @@ pub struct PollFn<F> {
} }
#[stable(feature = "future_poll_fn", since = "1.64.0")] #[stable(feature = "future_poll_fn", since = "1.64.0")]
impl<F> Unpin for PollFn<F> {} impl<F: Unpin> Unpin for PollFn<F> {}
#[stable(feature = "future_poll_fn", since = "1.64.0")] #[stable(feature = "future_poll_fn", since = "1.64.0")]
impl<F> fmt::Debug for PollFn<F> { impl<F> fmt::Debug for PollFn<F> {
@ -57,7 +59,8 @@ impl<T, F> Future for PollFn<F>
{ {
type Output = T; type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
(&mut self.f)(cx) // SAFETY: We are not moving out of the pinned field.
(unsafe { &mut self.get_unchecked_mut().f })(cx)
} }
} }