Skip to content

Commit 17d78c4

Browse files
committed
poll_fn and Unpin: fix pinning
1 parent c97d02c commit 17d78c4

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

library/core/src/future/poll_fn.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use crate::task::{Context, Poll};
55

66
/// Creates a future that wraps a function returning [`Poll`].
77
///
8-
/// Polling the future delegates to the wrapped function.
8+
/// Polling the future delegates to the wrapped function. If the returned future is pinned, then the
9+
/// captured environment of the wrapped function is also pinned in-place, so as long as the closure
10+
/// does not move out of its captures it can soundly create pinned references to them.
911
///
1012
/// # Examples
1113
///
@@ -41,7 +43,7 @@ pub struct PollFn<F> {
4143
}
4244

4345
#[stable(feature = "future_poll_fn", since = "1.64.0")]
44-
impl<F> Unpin for PollFn<F> {}
46+
impl<F: Unpin> Unpin for PollFn<F> {}
4547

4648
#[stable(feature = "future_poll_fn", since = "1.64.0")]
4749
impl<F> fmt::Debug for PollFn<F> {
@@ -57,7 +59,8 @@ where
5759
{
5860
type Output = T;
5961

60-
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
61-
(&mut self.f)(cx)
62+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
63+
// SAFETY: We are not moving out of the pinned field.
64+
(unsafe { &mut self.get_unchecked_mut().f })(cx)
6265
}
6366
}

0 commit comments

Comments
 (0)