diff --git a/actix-http/src/client/pool.rs b/actix-http/src/client/pool.rs index acf76559a..8c94423ac 100644 --- a/actix-http/src/client/pool.rs +++ b/actix-http/src/client/pool.rs @@ -488,10 +488,12 @@ where } } +#[pin_project::pin_project(PinnedDrop)] struct OpenWaitingConnection where Io: AsyncRead + AsyncWrite + Unpin + 'static, { + #[pin] fut: F, key: Key, h2: Option< @@ -525,12 +527,13 @@ where } } -impl Drop for OpenWaitingConnection +#[pin_project::pinned_drop] +impl PinnedDrop for OpenWaitingConnection where Io: AsyncRead + AsyncWrite + Unpin + 'static, { - fn drop(&mut self) { - if let Some(inner) = self.inner.take() { + fn drop(self: Pin<&mut Self>) { + if let Some(inner) = self.project().inner.take() { let mut inner = inner.as_ref().borrow_mut(); inner.release(); inner.check_availibility(); @@ -545,8 +548,8 @@ where { type Output = (); - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = unsafe { self.get_unchecked_mut() }; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.as_mut().project(); if let Some(ref mut h2) = this.h2 { return match Pin::new(h2).poll(cx) { @@ -571,7 +574,7 @@ where }; } - match unsafe { Pin::new_unchecked(&mut this.fut) }.poll(cx) { + match this.fut.poll(cx) { Poll::Ready(Err(err)) => { let _ = this.inner.take(); if let Some(rx) = this.rx.take() { @@ -589,8 +592,8 @@ where ))); Poll::Ready(()) } else { - this.h2 = Some(handshake(io).boxed_local()); - unsafe { Pin::new_unchecked(this) }.poll(cx) + *this.h2 = Some(handshake(io).boxed_local()); + self.poll(cx) } } Poll::Pending => Poll::Pending, diff --git a/actix-http/src/h2/dispatcher.rs b/actix-http/src/h2/dispatcher.rs index a4ec15fab..8b17e9479 100644 --- a/actix-http/src/h2/dispatcher.rs +++ b/actix-http/src/h2/dispatcher.rs @@ -158,14 +158,16 @@ where #[pin_project::pin_project] struct ServiceResponse { + #[pin] state: ServiceResponseState, config: ServiceConfig, buffer: Option, _t: PhantomData<(I, E)>, } +#[pin_project::pin_project] enum ServiceResponseState { - ServiceCall(F, Option>), + ServiceCall(#[pin] F, Option>), SendPayload(SendStream, ResponseBody), } @@ -247,12 +249,14 @@ where { type Output = (); + #[pin_project::project] fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.as_mut().project(); - match this.state { - ServiceResponseState::ServiceCall(ref mut call, ref mut send) => { - match unsafe { Pin::new_unchecked(call) }.poll(cx) { + #[project] + match this.state.project() { + ServiceResponseState::ServiceCall(call, send) => { + match call.poll(cx) { Poll::Ready(Ok(res)) => { let (res, body) = res.into().replace_body(()); @@ -273,8 +277,7 @@ where if size.is_eof() { Poll::Ready(()) } else { - *this.state = - ServiceResponseState::SendPayload(stream, body); + this.state.set(ServiceResponseState::SendPayload(stream, body)); self.poll(cx) } } @@ -300,10 +303,10 @@ where if size.is_eof() { Poll::Ready(()) } else { - *this.state = ServiceResponseState::SendPayload( + this.state.set(ServiceResponseState::SendPayload( stream, body.into_body(), - ); + )); self.poll(cx) } }