## ASYNC_FN_IN_TRAIT

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