diff --git a/tokio/src/future/maybe_done.rs b/tokio/src/future/maybe_done.rs index 506b4f26c18..8b270b3a01f 100644 --- a/tokio/src/future/maybe_done.rs +++ b/tokio/src/future/maybe_done.rs @@ -1,7 +1,7 @@ //! Definition of the [`MaybeDone`] combinator. use pin_project_lite::pin_project; -use std::future::Future; +use std::future::{Future, IntoFuture}; use std::pin::Pin; use std::task::{Context, Poll}; @@ -22,8 +22,10 @@ pin_project! { } /// Wraps a future into a `MaybeDone`. -pub fn maybe_done(future: Fut) -> MaybeDone { - MaybeDone::Future { future } +pub fn maybe_done(future: F) -> MaybeDone { + MaybeDone::Future { + future: future.into_future(), + } } impl MaybeDone { diff --git a/tokio/src/macros/select.rs b/tokio/src/macros/select.rs index 124d7827086..505c70dd060 100644 --- a/tokio/src/macros/select.rs +++ b/tokio/src/macros/select.rs @@ -495,7 +495,7 @@ doc! {macro_rules! select { // We can't use the `pin!` macro for this because `futures` is a // tuple and the standard library provides no way to pin-project to // the fields of a tuple. - let mut futures = ( $( $fut , )+ ); + let mut futures = ( $( $crate::macros::support::IntoFuture::into_future($fut) , )+ ); // This assignment makes sure that the `poll_fn` closure only has a // reference to the futures, instead of taking ownership of them. diff --git a/tokio/src/macros/support.rs b/tokio/src/macros/support.rs index 10526bcbca7..d077a0823c7 100644 --- a/tokio/src/macros/support.rs +++ b/tokio/src/macros/support.rs @@ -8,6 +8,6 @@ cfg_macros! { } } -pub use std::future::Future; +pub use std::future::{Future, IntoFuture}; pub use std::pin::Pin; pub use std::task::Poll; diff --git a/tokio/tests/macros_join.rs b/tokio/tests/macros_join.rs index 37dd05f0e13..4deaf120a95 100644 --- a/tokio/tests/macros_join.rs +++ b/tokio/tests/macros_join.rs @@ -159,3 +159,18 @@ async fn a_different_future_is_polled_first_every_time_poll_fn_is_polled() { async fn empty_join() { assert_eq!(tokio::join!(), ()); } + +#[tokio::test] +async fn join_into_future() { + struct NotAFuture; + impl std::future::IntoFuture for NotAFuture { + type Output = (); + type IntoFuture = std::future::Ready<()>; + + fn into_future(self) -> Self::IntoFuture { + std::future::ready(()) + } + } + + tokio::join!(NotAFuture); +} diff --git a/tokio/tests/macros_select.rs b/tokio/tests/macros_select.rs index cbad971ab1f..c91d696426c 100644 --- a/tokio/tests/macros_select.rs +++ b/tokio/tests/macros_select.rs @@ -692,3 +692,20 @@ mod unstable { ) } } + +#[tokio::test] +async fn select_into_future() { + struct NotAFuture; + impl std::future::IntoFuture for NotAFuture { + type Output = (); + type IntoFuture = std::future::Ready<()>; + + fn into_future(self) -> Self::IntoFuture { + std::future::ready(()) + } + } + + tokio::select! { + () = NotAFuture => {}, + } +}