Static rustc_lint::async_fn_in_trait::ASYNC_FN_IN_TRAIT
source · pub static ASYNC_FN_IN_TRAIT: &Lint
Expand description
The async_fn_in_trait
lint detects use of async fn
in the
definition of a publicly-reachable trait.
Example
pub trait Trait {
async fn method(&self);
}
{{produces}}
Explanation
When async fn
is used in a trait definition, the trait does not
promise that the opaque Future
returned by the associated function
or method will implement any auto traits such as Send
. This may
be surprising and may make the associated functions or methods on the
trait less useful than intended. On traits exposed publicly from a
crate, this may affect downstream crates whose authors cannot alter
the trait definition.
For example, this code is invalid:
pub trait Trait {
async fn method(&self) {}
}
fn test<T: Trait>(x: T) {
fn spawn<T: Send>(_: T) {}
spawn(x.method()); // Not OK.
}
This lint exists to warn authors of publicly-reachable traits that
they may want to consider desugaring the async fn
to a normal fn
that returns an opaque impl Future<..> + Send
type.
For example, instead of:
pub trait Trait {
async fn method(&self) {}
}
The author of the trait may want to write:
use core::future::Future;
pub trait Trait {
fn method(&self) -> impl Future<Output = ()> + Send { async {} }
}
This still allows the use of async fn
within impls of the trait.
However, it also means that the trait will never be compatible with
impls where the returned Future
of the method does not implement
Send
.
Conversely, if the trait is used only locally, if it is never used in
generic functions, or if it is only used in single-threaded contexts
that do not care whether the returned Future
implements Send
,
then the lint may be suppressed.