#[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.