diff --git a/tokio/src/macros/pin.rs b/tokio/src/macros/pin.rs index e8511d3f3..5b677610a 100644 --- a/tokio/src/macros/pin.rs +++ b/tokio/src/macros/pin.rs @@ -97,6 +97,30 @@ /// } /// } /// ``` +/// +/// Because assigning to a variable followed by pinning is common, there is also +/// a variant of the macro that supports doing both in one go. +/// +/// ``` +/// use tokio::{pin, select}; +/// +/// async fn my_async_fn() { +/// // async logic here +/// } +/// +/// #[tokio::main] +/// async fn main() { +/// pin! { +/// let future1 = my_async_fn(); +/// let future2 = my_async_fn(); +/// } +/// +/// select! { +/// _ = &mut future1 => {} +/// _ = &mut future2 => {} +/// } +/// } +/// ``` #[macro_export] macro_rules! pin { ($($x:ident),*) => { $( @@ -108,5 +132,13 @@ macro_rules! pin { let mut $x = unsafe { $crate::macros::support::Pin::new_unchecked(&mut $x) }; - )* } + )* }; + ($( + let $x:ident = $init:expr; + )*) => { + $( + let $x = $init; + crate::pin!($x); + )* + }; } diff --git a/tokio/tests/macros_pin.rs b/tokio/tests/macros_pin.rs new file mode 100644 index 000000000..1d9c27b2b --- /dev/null +++ b/tokio/tests/macros_pin.rs @@ -0,0 +1,15 @@ +use tokio::pin; + +async fn one() {} +async fn two() {} + +#[tokio::test] +async fn multi_pin() { + pin! { + let f1 = one(); + let f2 = two(); + } + + (&mut f1).await; + (&mut f2).await; +}