Remove pin-related unsafe code

This commit is contained in:
Taiki Endo
2020-11-14 05:46:10 +09:00
committed by Sean McArthur
parent ff507e12fc
commit 2dec3b725f
2 changed files with 35 additions and 25 deletions

View File

@@ -6,6 +6,7 @@ use std::task::{Context, Poll};
use bytes::Bytes; use bytes::Bytes;
use futures_core::Stream; use futures_core::Stream;
use http_body::Body as HttpBody; use http_body::Body as HttpBody;
use pin_project_lite::pin_project;
use tokio::time::Delay; use tokio::time::Delay;
/// An asynchronous request body. /// An asynchronous request body.
@@ -30,7 +31,12 @@ enum Inner {
}, },
} }
struct WrapStream<S>(S); pin_project! {
struct WrapStream<S> {
#[pin]
inner: S,
}
}
struct WrapHyper(hyper::Body); struct WrapHyper(hyper::Body);
@@ -86,9 +92,9 @@ impl Body {
{ {
use futures_util::TryStreamExt; use futures_util::TryStreamExt;
let body = Box::pin(WrapStream( let body = Box::pin(WrapStream {
stream.map_ok(Bytes::from).map_err(Into::into), inner: stream.map_ok(Bytes::from).map_err(Into::into),
)); });
Body { Body {
inner: Inner::Streaming { inner: Inner::Streaming {
body, body,
@@ -279,11 +285,7 @@ where
self: Pin<&mut Self>, self: Pin<&mut Self>,
cx: &mut Context, cx: &mut Context,
) -> Poll<Option<Result<Self::Data, Self::Error>>> { ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
// safe pin projection let item = futures_core::ready!(self.project().inner.poll_next(cx)?);
let item =
futures_core::ready!(
unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0) }.poll_next(cx)?
);
Poll::Ready(item.map(|val| Ok(val.into()))) Poll::Ready(item.map(|val| Ok(val.into())))
} }

View File

@@ -25,6 +25,7 @@ use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use tokio::time::Delay; use tokio::time::Delay;
use pin_project_lite::pin_project;
use log::debug; use log::debug;
@@ -1265,8 +1266,11 @@ impl ClientRef {
} }
} }
pub(super) struct Pending { pin_project! {
inner: PendingInner, pub(super) struct Pending {
#[pin]
inner: PendingInner,
}
} }
enum PendingInner { enum PendingInner {
@@ -1274,35 +1278,39 @@ enum PendingInner {
Error(Option<crate::Error>), Error(Option<crate::Error>),
} }
struct PendingRequest { pin_project! {
method: Method, struct PendingRequest {
url: Url, method: Method,
headers: HeaderMap, url: Url,
body: Option<Option<Bytes>>, headers: HeaderMap,
body: Option<Option<Bytes>>,
urls: Vec<Url>, urls: Vec<Url>,
client: Arc<ClientRef>, client: Arc<ClientRef>,
in_flight: ResponseFuture, #[pin]
timeout: Option<Delay>, in_flight: ResponseFuture,
#[pin]
timeout: Option<Delay>,
}
} }
impl PendingRequest { impl PendingRequest {
fn in_flight(self: Pin<&mut Self>) -> Pin<&mut ResponseFuture> { fn in_flight(self: Pin<&mut Self>) -> Pin<&mut ResponseFuture> {
unsafe { Pin::map_unchecked_mut(self, |x| &mut x.in_flight) } self.project().in_flight
} }
fn timeout(self: Pin<&mut Self>) -> Pin<&mut Option<Delay>> { fn timeout(self: Pin<&mut Self>) -> Pin<&mut Option<Delay>> {
unsafe { Pin::map_unchecked_mut(self, |x| &mut x.timeout) } self.project().timeout
} }
fn urls(self: Pin<&mut Self>) -> &mut Vec<Url> { fn urls(self: Pin<&mut Self>) -> &mut Vec<Url> {
unsafe { &mut Pin::get_unchecked_mut(self).urls } self.project().urls
} }
fn headers(self: Pin<&mut Self>) -> &mut HeaderMap { fn headers(self: Pin<&mut Self>) -> &mut HeaderMap {
unsafe { &mut Pin::get_unchecked_mut(self).headers } self.project().headers
} }
} }
@@ -1314,7 +1322,7 @@ impl Pending {
} }
fn inner(self: Pin<&mut Self>) -> Pin<&mut PendingInner> { fn inner(self: Pin<&mut Self>) -> Pin<&mut PendingInner> {
unsafe { Pin::map_unchecked_mut(self, |x| &mut x.inner) } self.project().inner
} }
} }