Attribute Macro async_fn::bare_future [−][src]
#[bare_future]
Expand description
One of the main macros of the crate.
#[async_fn::bare_future]
allows to express the actual Future
return type
of an async fn
.
Implementation-wise, and thus, semantic-wise, what this macro does is very
simple: it removes the async
from the async fn
, and wraps the function
body within an async move { … }
block (except for the statements inside
the before_async!
eager prelude).
The point of doing this is to reduce the rightwards drift that an explicit
async move
block requires.
Example / unsugaring
use ::async_fn::prelude::*;
async fn foo(/* … */) { /* … */ }
async fn bar(/* … */) -> i32 {
// …
}
struct Foo {
// …
}
impl Foo {
#[bare_future]
async fn thread_safe_async_method(&self) -> impl Fut<'_, i32> + Send {
foo(/* … */).await;
bar(/* … */).await
}
}
/// The above is sugar for:
impl Foo {
fn thread_safe_async_method(&self) -> impl Fut<'_, i32> + Send {
async move {
foo(/* … */).await;
bar(/* … */).await
}
}
}
The advantages of using #[bare_future]
over an async move
body are thus
slim, but non-negligible:
- The function is still marked as / appears as
async fn
, which makes it easier to grep for; - The extra rightward drift in the
async move { … }
body is avoided.
Extra features and benefits
1 — The 'args
lifetime
⚠️ Not implemented yet. ⚠️
A [bare_future] async fn
function will feature a magical 'args
lifetime (parameter) which will represent the “intersection” of the
lifetimes / spans of usability of each function parameter. This makes it
so:
#[bare_future]
async fn fname(/* args… */) -> impl Fut<'args, RetTy>
/// Has the same semantics as:
async fn fname(/* args… */) -> RetTy
2 — The before_async!
eager prelude
- This is for an opposite goal to that of using
'args
, mainly, when wanting to yield a'static + Future
.
See before_async!
for more info.