    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340

    //! [![github]](https://github.com/dtolnay/async-trait)&ensp;[![crates-io]](https://crates.io/crates/async-trait)&ensp;[![docs-rs]](https://docs.rs/async-trait)
    //!
    //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
    //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
    //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
    //!
    //! <br>
    //!
    //! <h5>Type erasure for async trait methods</h5>
    //!
    //! The initial round of stabilizations for the async/await language feature in
    //! Rust 1.39 did not include support for async fn in traits. Trying to include
    //! an async fn in a trait produces the following error:
    //!
    //! ```compile_fail
    //! trait MyTrait {
    //!     async fn f() {}
    //! }
    //! ```
    //!
    //! ```text
    //! error[E0706]: trait fns cannot be declared `async`
    //!  --> src/main.rs:4:5
    //!   |
    //! 4 |     async fn f() {}
    //!   |     ^^^^^^^^^^^^^^^
    //! ```
    //!
    //! This crate provides an attribute macro to make async fn in traits work.
    //!
    //! Please refer to [*why async fn in traits are hard*][hard] for a deeper
    //! analysis of how this implementation differs from what the compiler and
    //! language hope to deliver in the future.
    //!
    //! [hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
    //!
    //! <br>
    //!
    //! # Example
    //!
    //! This example implements the core of a highly effective advertising platform
    //! using async fn in a trait.
    //!
    //! The only thing to notice here is that we write an `#[async_trait]` macro on
    //! top of traits and trait impls that contain async fn, and then they work.
    //!
    //! ```
    //! use async_trait::async_trait;
    //!
    //! #[async_trait]
    //! trait Advertisement {
    //!     async fn run(&self);
    //! }
    //!
    //! struct Modal;
    //!
    //! #[async_trait]
    //! impl Advertisement for Modal {
    //!     async fn run(&self) {
    //!         self.render_fullscreen().await;
    //!         for _ in 0..4u16 {
    //!             remind_user_to_join_mailing_list().await;
    //!         }
    //!         self.hide_for_now().await;
    //!     }
    //! }
    //!
    //! struct AutoplayingVideo {
    //!     media_url: String,
    //! }
    //!
    //! #[async_trait]
    //! impl Advertisement for AutoplayingVideo {
    //!     async fn run(&self) {
    //!         let stream = connect(&self.media_url).await;
    //!         stream.play().await;
    //!
    //!         // Video probably persuaded user to join our mailing list!
    //!         Modal.run().await;
    //!     }
    //! }
    //! #
    //! # impl Modal {
    //! #     async fn render_fullscreen(&self) {}
    //! #     async fn hide_for_now(&self) {}
    //! # }
    //! #
    //! # async fn remind_user_to_join_mailing_list() {}
    //! #
    //! # struct Stream;
    //! # async fn connect(_media_url: &str) -> Stream { Stream }
    //! # impl Stream {
    //! #     async fn play(&self) {}
    //! # }
    //! ```
    //!
    //! <br><br>
    //!
    //! # Supported features
    //!
    //! It is the intention that all features of Rust traits should work nicely with
    //! #\[async_trait\], but the edge cases are numerous. Please file an issue if
    //! you see unexpected borrow checker errors, type errors, or warnings. There is
    //! no use of `unsafe` in the expanded code, so rest assured that if your code
    //! compiles it can't be that badly broken.
    //!
    //! > &#9745;&emsp;Self by value, by reference, by mut reference, or no self;<br>
    //! > &#9745;&emsp;Any number of arguments, any return value;<br>
    //! > &#9745;&emsp;Generic type parameters and lifetime parameters;<br>
    //! > &#9745;&emsp;Associated types;<br>
    //! > &#9745;&emsp;Having async and non-async functions in the same trait;<br>
    //! > &#9745;&emsp;Default implementations provided by the trait;<br>
    //! > &#9745;&emsp;Elided lifetimes;<br>
    //! > &#9745;&emsp;Dyn-capable traits.<br>
    //!
    //! <br>
    //!
    //! # Explanation
    //!
    //! Async fns get transformed into methods that return `Pin<Box<dyn Future +
    //! Send + 'async>>` and delegate to a private async freestanding function.
    //!
    //! For example the `impl Advertisement for AutoplayingVideo` above would be
    //! expanded as:
    //!
    //! ```
    //! # const IGNORE: &str = stringify! {
    //! impl Advertisement for AutoplayingVideo {
    //!     fn run<'async>(
    //!         &'async self,
    //!     ) -> Pin<Box<dyn core::future::Future<Output = ()> + Send + 'async>>
    //!     where
    //!         Self: Sync + 'async,
    //!     {
    //!         async fn run(_self: &AutoplayingVideo) {
    //!             /* the original method body */
    //!         }
    //!
    //!         Box::pin(run(self))
    //!     }
    //! }
    //! # };
    //! ```
    //!
    //! <br><br>
    //!
    //! # Non-threadsafe futures
    //!
    //! Not all async traits need futures that are `dyn Future + Send`. To avoid
    //! having Send and Sync bounds placed on the async trait methods, invoke the
    //! async trait macro as `#[async_trait(?Send)]` on both the trait and the impl
    //! blocks.
    //!
    //! <br>
    //!
    //! # Elided lifetimes
    //!
    //! Be aware that async fn syntax does not allow lifetime elision outside of `&`
    //! and `&mut` references. (This is true even when not using #\[async_trait\].)
    //! Lifetimes must be named or marked by the placeholder `'_`.
    //!
    //! Fortunately the compiler is able to diagnose missing lifetimes with a good
    //! error message.
    //!
    //! ```compile_fail
    //! # use async_trait::async_trait;
    //! #
    //! type Elided<'a> = &'a usize;
    //!
    //! #[async_trait]
    //! trait Test {
    //!     async fn test(not_okay: Elided, okay: &usize) {}
    //! }
    //! ```
    //!
    //! ```text
    //! error[E0726]: implicit elided lifetime not allowed here
    //!  --> src/main.rs:9:29
    //!   |
    //! 9 |     async fn test(not_okay: Elided, okay: &usize) {}
    //!   |                             ^^^^^^- help: indicate the anonymous lifetime: `<'_>`
    //! ```
    //!
    //! The fix is to name the lifetime or use `'_`.
    //!
    //! ```
    //! # use async_trait::async_trait;
    //! #
    //! # type Elided<'a> = &'a usize;
    //! #
    //! #[async_trait]
    //! trait Test {
    //!     // either
    //!     async fn test<'e>(elided: Elided<'e>) {}
    //! # }
    //! # #[async_trait]
    //! # trait Test2 {
    //!     // or
    //!     async fn test(elided: Elided<'_>) {}
    //! }
    //! ```
    //!
    //! <br><br>
    //!
    //! # Dyn traits
    //!
    //! Traits with async methods can be used as trait objects as long as they meet
    //! the usual requirements for dyn -- no methods with type parameters, no self
    //! by value, no associated types, etc.
    //!
    //! ```
    //! # use async_trait::async_trait;
    //! #
    //! #[async_trait]
    //! pub trait ObjectSafe {
    //!     async fn f(&self);
    //!     async fn g(&mut self);
    //! }
    //!
    //! # const IGNORE: &str = stringify! {
    //! impl ObjectSafe for MyType {...}
    //!
    //! let value: MyType = ...;
    //! # };
    //! #
    //! # struct MyType;
    //! #
    //! # #[async_trait]
    //! # impl ObjectSafe for MyType {
    //! #     async fn f(&self) {}
    //! #     async fn g(&mut self) {}
    //! # }
    //! #
    //! # let value: MyType = MyType;
    //! let object = &value as &dyn ObjectSafe;  // make trait object
    //! ```
    //!
    //! The one wrinkle is in traits that provide default implementations of async
    //! methods. In order for the default implementation to produce a future that is
    //! Send, the async_trait macro must emit a bound of `Self: Sync` on trait
    //! methods that take `&self` and a bound `Self: Send` on trait methods that
    //! take `&mut self`. An example of the former is visible in the expanded code
    //! in the explanation section above.
    //!
    //! If you make a trait with async methods that have default implementations,
    //! everything will work except that the trait cannot be used as a trait object.
    //! Creating a value of type `&dyn Trait` will produce an error that looks like
    //! this:
    //!
    //! ```text
    //! error: the trait `Test` cannot be made into an object
    //!  --> src/main.rs:8:5
    //!   |
    //! 8 |     async fn cannot_dyn(&self) {}
    //!   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    //! ```
    //!
    //! For traits that need to be object safe and need to have default
    //! implementations for some async methods, there are two resolutions. Either
    //! you can add Send and/or Sync as supertraits (Send if there are `&mut self`
    //! methods with default implementations, Sync if there are `&self` methods with
    //! default implementations) to constrain all implementors of the trait such that
    //! the default implementations are applicable to them:
    //!
    //! ```
    //! # use async_trait::async_trait;
    //! #
    //! #[async_trait]
    //! pub trait ObjectSafe: Sync {  // added supertrait
    //!     async fn can_dyn(&self) {}
    //! }
    //! #
    //! # struct MyType;
    //! #
    //! # #[async_trait]
    //! # impl ObjectSafe for MyType {}
    //! #
    //! # let value = MyType;
    //!
    //! let object = &value as &dyn ObjectSafe;
    //! ```
    //!
    //! or you can strike the problematic methods from your trait object by
    //! bounding them with `Self: Sized`:
    //!
    //! ```
    //! # use async_trait::async_trait;
    //! #
    //! #[async_trait]
    //! pub trait ObjectSafe {
    //!     async fn cannot_dyn(&self) where Self: Sized {}
    //!
    //!     // presumably other methods
    //! }
    //! #
    //! # struct MyType;
    //! #
    //! # #[async_trait]
    //! # impl ObjectSafe for MyType {}
    //! #
    //! # let value = MyType;
    //!
    //! let object = &value as &dyn ObjectSafe;
    //! ```

    #![allow(
        clippy::default_trait_access,
        clippy::doc_markdown,
        clippy::explicit_auto_deref,
        clippy::if_not_else,
        clippy::items_after_statements,
        clippy::module_name_repetitions,
        clippy::shadow_unrelated,
        clippy::similar_names,
        clippy::too_many_lines
    )]

    extern crate proc_macro;

    mod args;
    mod bound;
    mod expand;
    mod lifetime;
    mod parse;
    mod receiver;

    use crate::args::Args;
    use crate::expand::expand;
    use crate::parse::Item;
    use proc_macro::TokenStream;
    use quote::quote;
    use syn::parse_macro_input;

    #[proc_macro_attribute]
    pub fn async_trait(args: TokenStream, input: TokenStream) -> TokenStream {
        let args = parse_macro_input!(args as Args);
        let mut item = parse_macro_input!(input as Item);
        expand(&mut item, args.local);
        TokenStream::from(quote!(#item))
    }