1 #![cfg_attr(
2     async_trait_nightly_testing,
3     feature(impl_trait_in_assoc_type, min_specialization, never_type)
4 )]
5 #![deny(rust_2021_compatibility, unused_qualifications)]
6 #![allow(
7     clippy::incompatible_msrv, // https://github.com/rust-lang/rust-clippy/issues/12257
8     clippy::let_underscore_untyped,
9     clippy::let_unit_value,
10     clippy::missing_panics_doc,
11     clippy::missing_safety_doc,
12     clippy::needless_return,
13     clippy::non_minimal_cfg,
14     clippy::trivially_copy_pass_by_ref,
15     clippy::unused_async
16 )]
17 
18 use async_trait::async_trait;
19 
20 pub mod executor;
21 
22 // Dummy module to check that the expansion refer to rust's core crate
23 mod core {}
24 
25 #[async_trait]
26 trait Trait {
27     type Assoc;
28 
selfvalue(self) where Self: Sized,29     async fn selfvalue(self)
30     where
31         Self: Sized,
32     {
33     }
34 
selfref(&self)35     async fn selfref(&self) {}
36 
selfmut(&mut self)37     async fn selfmut(&mut self) {}
38 
required() -> Self::Assoc39     async fn required() -> Self::Assoc;
40 
elided_lifetime(_x: &str)41     async fn elided_lifetime(_x: &str) {}
42 
explicit_lifetime<'a>(_x: &'a str)43     async fn explicit_lifetime<'a>(_x: &'a str) {}
44 
generic_type_param<T: Send>(x: Box<T>) -> T45     async fn generic_type_param<T: Send>(x: Box<T>) -> T {
46         *x
47     }
48 
calls(&self)49     async fn calls(&self) {
50         self.selfref().await;
51         Self::elided_lifetime("").await;
52         <Self>::elided_lifetime("").await;
53     }
54 
calls_mut(&mut self)55     async fn calls_mut(&mut self) {
56         self.selfmut().await;
57     }
58 }
59 
60 struct Struct;
61 
62 #[async_trait]
63 impl Trait for Struct {
64     type Assoc = ();
65 
selfvalue(self)66     async fn selfvalue(self) {}
67 
selfref(&self)68     async fn selfref(&self) {}
69 
selfmut(&mut self)70     async fn selfmut(&mut self) {}
71 
required() -> Self::Assoc72     async fn required() -> Self::Assoc {}
73 
elided_lifetime(_x: &str)74     async fn elided_lifetime(_x: &str) {}
75 
explicit_lifetime<'a>(_x: &'a str)76     async fn explicit_lifetime<'a>(_x: &'a str) {}
77 
generic_type_param<T: Send>(x: Box<T>) -> T78     async fn generic_type_param<T: Send>(x: Box<T>) -> T {
79         *x
80     }
81 
calls(&self)82     async fn calls(&self) {
83         self.selfref().await;
84         Self::elided_lifetime("").await;
85         <Self>::elided_lifetime("").await;
86     }
87 
calls_mut(&mut self)88     async fn calls_mut(&mut self) {
89         self.selfmut().await;
90     }
91 }
92 
test()93 pub async fn test() {
94     let mut s = Struct;
95     s.selfref().await;
96     s.selfmut().await;
97     s.selfvalue().await;
98 
99     Struct::required().await;
100     Struct::elided_lifetime("").await;
101     Struct::explicit_lifetime("").await;
102     Struct::generic_type_param(Box::new("")).await;
103 
104     let mut s = Struct;
105     s.calls().await;
106     s.calls_mut().await;
107 }
108 
test_object_safe_without_default()109 pub async fn test_object_safe_without_default() {
110     #[async_trait]
111     trait ObjectSafe {
112         async fn f(&self);
113     }
114 
115     #[async_trait]
116     impl ObjectSafe for Struct {
117         async fn f(&self) {}
118     }
119 
120     let object = &Struct as &dyn ObjectSafe;
121     object.f().await;
122 }
123 
test_object_safe_with_default()124 pub async fn test_object_safe_with_default() {
125     #[async_trait]
126     trait ObjectSafe: Sync {
127         async fn f(&self) {}
128     }
129 
130     #[async_trait]
131     impl ObjectSafe for Struct {
132         async fn f(&self) {}
133     }
134 
135     let object = &Struct as &dyn ObjectSafe;
136     object.f().await;
137 }
138 
test_object_no_send()139 pub async fn test_object_no_send() {
140     #[async_trait(?Send)]
141     trait ObjectSafe: Sync {
142         async fn f(&self) {}
143     }
144 
145     #[async_trait(?Send)]
146     impl ObjectSafe for Struct {
147         async fn f(&self) {}
148     }
149 
150     let object = &Struct as &dyn ObjectSafe;
151     object.f().await;
152 }
153 
154 #[async_trait]
155 pub unsafe trait UnsafeTrait {}
156 
157 #[async_trait]
158 unsafe impl UnsafeTrait for () {}
159 
160 #[async_trait]
161 #[allow(dead_code)]
162 pub(crate) unsafe trait UnsafeTraitPubCrate {}
163 
164 #[async_trait]
165 #[allow(dead_code)]
166 unsafe trait UnsafeTraitPrivate {}
167 
test_can_destruct()168 pub async fn test_can_destruct() {
169     #[async_trait]
170     trait CanDestruct {
171         async fn f(&self, foos: (u8, u8, u8, u8));
172     }
173 
174     #[async_trait]
175     impl CanDestruct for Struct {
176         async fn f(&self, (a, ref mut b, ref c, d): (u8, u8, u8, u8)) {
177             let _a: u8 = a;
178             let _b: &mut u8 = b;
179             let _c: &u8 = c;
180             let _d: u8 = d;
181         }
182     }
183 
184     let _ = <Struct as CanDestruct>::f;
185 }
186 
test_self_in_macro()187 pub async fn test_self_in_macro() {
188     #[async_trait]
189     trait Trait {
190         async fn a(self);
191         async fn b(&mut self);
192         async fn c(&self);
193     }
194 
195     #[async_trait]
196     impl Trait for String {
197         async fn a(self) {
198             println!("{}", self);
199         }
200         async fn b(&mut self) {
201             println!("{}", self);
202         }
203         async fn c(&self) {
204             println!("{}", self);
205         }
206     }
207 
208     let _ = <String as Trait>::a;
209     let _ = <String as Trait>::b;
210     let _ = <String as Trait>::c;
211 }
212 
test_inference()213 pub async fn test_inference() {
214     #[async_trait]
215     pub trait Trait {
216         async fn f() -> Box<dyn Iterator<Item = ()>> {
217             Box::new(std::iter::empty())
218         }
219     }
220 
221     impl Trait for () {}
222 
223     let _ = <() as Trait>::f;
224 }
225 
test_internal_items()226 pub async fn test_internal_items() {
227     #[async_trait]
228     #[allow(dead_code, clippy::items_after_statements)]
229     pub trait Trait: Sized {
230         async fn f(self) {
231             struct Struct;
232 
233             impl Struct {
234                 fn f(self) {
235                     let _ = self;
236                 }
237             }
238         }
239     }
240 }
241 
test_unimplemented()242 pub async fn test_unimplemented() {
243     #[async_trait]
244     pub trait Trait {
245         async fn f() {
246             unimplemented!()
247         }
248     }
249 
250     impl Trait for () {}
251 
252     let _ = <() as Trait>::f;
253 }
254 
255 // https://github.com/dtolnay/async-trait/issues/1
256 pub mod issue1 {
257     use async_trait::async_trait;
258 
259     #[async_trait]
260     pub trait Issue1 {
f<U>(&self)261         async fn f<U>(&self);
262     }
263 
264     #[async_trait]
265     impl<T: Sync> Issue1 for Vec<T> {
f<U>(&self)266         async fn f<U>(&self) {}
267     }
268 }
269 
270 // https://github.com/dtolnay/async-trait/issues/2
271 pub mod issue2 {
272     use async_trait::async_trait;
273     use std::future::Future;
274 
275     #[async_trait]
276     pub trait Issue2: Future {
flatten(self) -> <Self::Output as Future>::Output where Self::Output: Future + Send, Self: Sized,277         async fn flatten(self) -> <Self::Output as Future>::Output
278         where
279             Self::Output: Future + Send,
280             Self: Sized,
281         {
282             let nested_future = self.await;
283             nested_future.await
284         }
285     }
286 }
287 
288 // https://github.com/dtolnay/async-trait/issues/9
289 pub mod issue9 {
290     use async_trait::async_trait;
291 
292     #[async_trait]
293     pub trait Issue9: Sized + Send {
f(_x: Self)294         async fn f(_x: Self) {}
295     }
296 }
297 
298 // https://github.com/dtolnay/async-trait/issues/11
299 pub mod issue11 {
300     use async_trait::async_trait;
301     use std::sync::Arc;
302 
303     #[async_trait]
304     pub trait Issue11 {
example(self: Arc<Self>)305         async fn example(self: Arc<Self>);
306     }
307 
308     pub struct Struct;
309 
310     #[async_trait]
311     impl Issue11 for Struct {
example(self: Arc<Self>)312         async fn example(self: Arc<Self>) {}
313     }
314 }
315 
316 // https://github.com/dtolnay/async-trait/issues/15
317 pub mod issue15 {
318     use async_trait::async_trait;
319     use std::marker::PhantomData;
320 
321     pub trait Trait {}
322 
323     #[async_trait]
324     pub trait Issue15 {
myfn(&self, _: PhantomData<dyn Trait + Send>)325         async fn myfn(&self, _: PhantomData<dyn Trait + Send>) {}
326     }
327 }
328 
329 // https://github.com/dtolnay/async-trait/issues/17
330 pub mod issue17 {
331     use async_trait::async_trait;
332 
333     #[async_trait]
334     pub trait Issue17 {
f(&self)335         async fn f(&self);
336     }
337 
338     pub struct Struct {
339         pub string: String,
340     }
341 
342     #[async_trait]
343     impl Issue17 for Struct {
f(&self)344         async fn f(&self) {
345             println!("{}", self.string);
346         }
347     }
348 }
349 
350 // https://github.com/dtolnay/async-trait/issues/23
351 pub mod issue23 {
352     use async_trait::async_trait;
353 
354     #[async_trait]
355     pub trait Issue23 {
f(self)356         async fn f(self);
357 
g(mut self) where Self: Sized,358         async fn g(mut self)
359         where
360             Self: Sized,
361         {
362             do_something(&mut self);
363         }
364     }
365 
366     #[allow(dead_code)]
367     struct S {}
368 
369     #[async_trait]
370     impl Issue23 for S {
f(mut self)371         async fn f(mut self) {
372             do_something(&mut self);
373         }
374     }
375 
do_something<T>(_: &mut T)376     fn do_something<T>(_: &mut T) {}
377 }
378 
379 // https://github.com/dtolnay/async-trait/issues/25
380 #[cfg(async_trait_nightly_testing)]
381 pub mod issue25 {
382     use crate::executor;
383     use async_trait::async_trait;
384     use std::fmt::{Display, Write};
385 
386     #[async_trait]
387     trait AsyncToString {
async_to_string(&self) -> String388         async fn async_to_string(&self) -> String;
389     }
390 
391     #[async_trait]
392     impl AsyncToString for String {
async_to_string(&self) -> String393         async fn async_to_string(&self) -> String {
394             "special".to_owned()
395         }
396     }
397 
398     macro_rules! hide_from_stable_parser {
399         ($($tt:tt)*) => {
400             $($tt)*
401         };
402     }
403 
404     hide_from_stable_parser! {
405         #[async_trait]
406         impl<T: ?Sized + Display + Sync> AsyncToString for T {
407             default async fn async_to_string(&self) -> String {
408                 let mut buf = String::new();
409                 buf.write_fmt(format_args!("{}", self)).unwrap();
410                 buf
411             }
412         }
413     }
414 
415     #[test]
test()416     fn test() {
417         let fut = true.async_to_string();
418         assert_eq!(executor::block_on_simple(fut), "true");
419 
420         let string = String::new();
421         let fut = string.async_to_string();
422         assert_eq!(executor::block_on_simple(fut), "special");
423     }
424 }
425 
426 // https://github.com/dtolnay/async-trait/issues/28
427 pub mod issue28 {
428     use async_trait::async_trait;
429 
430     pub struct Str<'a>(&'a str);
431 
432     #[async_trait]
433     pub trait Trait1<'a> {
f(x: Str<'a>) -> &'a str434         async fn f(x: Str<'a>) -> &'a str;
g(x: Str<'a>) -> &'a str435         async fn g(x: Str<'a>) -> &'a str {
436             x.0
437         }
438     }
439 
440     #[async_trait]
441     impl<'a> Trait1<'a> for str {
f(x: Str<'a>) -> &'a str442         async fn f(x: Str<'a>) -> &'a str {
443             x.0
444         }
445     }
446 
447     #[async_trait]
448     pub trait Trait2 {
f()449         async fn f();
450     }
451 
452     #[async_trait]
453     impl<'a> Trait2 for &'a () {
f()454         async fn f() {}
455     }
456 
457     #[async_trait]
458     pub trait Trait3<'a, 'b> {
f(_: &'a &'b ())459         async fn f(_: &'a &'b ()); // chain 'a and 'b
g(_: &'b ())460         async fn g(_: &'b ()); // chain 'b only
h()461         async fn h(); // do not chain
462     }
463 }
464 
465 // https://github.com/dtolnay/async-trait/issues/31
466 pub mod issue31 {
467     use async_trait::async_trait;
468 
469     pub struct Struct<'a> {
470         pub name: &'a str,
471     }
472 
473     #[async_trait]
474     pub trait Trait<'a> {
hello(thing: Struct<'a>) -> String475         async fn hello(thing: Struct<'a>) -> String;
hello_twice(one: Struct<'a>, two: Struct<'a>) -> String476         async fn hello_twice(one: Struct<'a>, two: Struct<'a>) -> String {
477             let str1 = Self::hello(one).await;
478             let str2 = Self::hello(two).await;
479             str1 + &str2
480         }
481     }
482 }
483 
484 // https://github.com/dtolnay/async-trait/issues/42
485 pub mod issue42 {
486     use async_trait::async_trait;
487 
488     #[async_trait]
489     pub trait Context: Sized {
from_parts() -> Self490         async fn from_parts() -> Self;
491     }
492 
493     pub struct TokenContext;
494 
495     #[async_trait]
496     impl Context for TokenContext {
from_parts() -> TokenContext497         async fn from_parts() -> TokenContext {
498             TokenContext
499         }
500     }
501 }
502 
503 // https://github.com/dtolnay/async-trait/issues/44
504 pub mod issue44 {
505     use async_trait::async_trait;
506 
507     #[async_trait]
508     pub trait StaticWithWhereSelf
509     where
510         Box<Self>: Sized,
511         Self: Sized + Send,
512     {
get_one() -> u8513         async fn get_one() -> u8 {
514             1
515         }
516     }
517 
518     pub struct Struct;
519 
520     #[async_trait]
521     impl StaticWithWhereSelf for Struct {}
522 }
523 
524 // https://github.com/dtolnay/async-trait/issues/45
525 pub mod issue45 {
526     use crate::executor;
527     use async_trait::async_trait;
528     use std::fmt::Debug;
529     use std::sync::atomic::{AtomicU64, Ordering};
530     use std::sync::{Arc, Mutex};
531     use tracing::event::Event;
532     use tracing::field::{Field, Visit};
533     use tracing::span::{Attributes, Id, Record};
534     use tracing::{info, instrument, subscriber, Metadata, Subscriber};
535 
536     #[async_trait]
537     pub trait Parent {
foo(&mut self, v: usize)538         async fn foo(&mut self, v: usize);
539     }
540 
541     #[async_trait]
542     pub trait Child {
bar(&self)543         async fn bar(&self);
544     }
545 
546     #[derive(Debug)]
547     struct Impl(usize);
548 
549     #[async_trait]
550     impl Parent for Impl {
551         #[instrument]
foo(&mut self, v: usize)552         async fn foo(&mut self, v: usize) {
553             self.0 = v;
554             self.bar().await;
555         }
556     }
557 
558     #[async_trait]
559     impl Child for Impl {
560         // Let's check that tracing detects the renaming of the `self` variable
561         // too, as tracing::instrument is not going to be able to skip the
562         // `self` argument if it can't find it in the function signature.
563         #[instrument(skip(self))]
bar(&self)564         async fn bar(&self) {
565             info!(val = self.0);
566         }
567     }
568 
569     // A simple subscriber implementation to test the behavior of async-trait
570     // with tokio-rs/tracing. This implementation is not robust against race
571     // conditions, but it's not an issue here as we are only polling on a single
572     // future at a time.
573     #[derive(Debug)]
574     struct SubscriberInner {
575         current_depth: AtomicU64,
576         // We assert that nested functions work. If the fix were to break, we
577         // would see two top-level functions instead of `bar` nested in `foo`.
578         max_depth: AtomicU64,
579         max_span_id: AtomicU64,
580         // Name of the variable / value / depth when the event was recorded.
581         value: Mutex<Option<(&'static str, u64, u64)>>,
582     }
583 
584     #[derive(Debug, Clone)]
585     struct TestSubscriber {
586         inner: Arc<SubscriberInner>,
587     }
588 
589     impl TestSubscriber {
new() -> Self590         fn new() -> Self {
591             TestSubscriber {
592                 inner: Arc::new(SubscriberInner {
593                     current_depth: AtomicU64::new(0),
594                     max_depth: AtomicU64::new(0),
595                     max_span_id: AtomicU64::new(1),
596                     value: Mutex::new(None),
597                 }),
598             }
599         }
600     }
601 
602     struct U64Visitor(Option<(&'static str, u64)>);
603 
604     impl Visit for U64Visitor {
record_debug(&mut self, _field: &Field, _value: &dyn Debug)605         fn record_debug(&mut self, _field: &Field, _value: &dyn Debug) {}
606 
record_u64(&mut self, field: &Field, value: u64)607         fn record_u64(&mut self, field: &Field, value: u64) {
608             self.0 = Some((field.name(), value));
609         }
610     }
611 
612     impl Subscriber for TestSubscriber {
enabled(&self, _metadata: &Metadata) -> bool613         fn enabled(&self, _metadata: &Metadata) -> bool {
614             true
615         }
new_span(&self, _span: &Attributes) -> Id616         fn new_span(&self, _span: &Attributes) -> Id {
617             Id::from_u64(self.inner.max_span_id.fetch_add(1, Ordering::AcqRel))
618         }
record(&self, _span: &Id, _values: &Record)619         fn record(&self, _span: &Id, _values: &Record) {}
record_follows_from(&self, _span: &Id, _follows: &Id)620         fn record_follows_from(&self, _span: &Id, _follows: &Id) {}
event(&self, event: &Event)621         fn event(&self, event: &Event) {
622             let mut visitor = U64Visitor(None);
623             event.record(&mut visitor);
624             if let Some((s, v)) = visitor.0 {
625                 let current_depth = self.inner.current_depth.load(Ordering::Acquire);
626                 *self.inner.value.lock().unwrap() = Some((s, v, current_depth));
627             }
628         }
enter(&self, _span: &Id)629         fn enter(&self, _span: &Id) {
630             let old_depth = self.inner.current_depth.fetch_add(1, Ordering::AcqRel);
631             if old_depth + 1 > self.inner.max_depth.load(Ordering::Acquire) {
632                 self.inner.max_depth.fetch_add(1, Ordering::AcqRel);
633             }
634         }
exit(&self, _span: &Id)635         fn exit(&self, _span: &Id) {
636             self.inner.current_depth.fetch_sub(1, Ordering::AcqRel);
637         }
638     }
639 
640     #[test]
tracing()641     fn tracing() {
642         // Create the future outside of the subscriber, as no call to tracing
643         // should be made until the future is polled.
644         let mut struct_impl = Impl(0);
645         let fut = struct_impl.foo(5);
646         let subscriber = TestSubscriber::new();
647         subscriber::with_default(subscriber.clone(), || executor::block_on_simple(fut));
648         // Did we enter bar inside of foo?
649         assert_eq!(subscriber.inner.max_depth.load(Ordering::Acquire), 2);
650         // Have we exited all spans?
651         assert_eq!(subscriber.inner.current_depth.load(Ordering::Acquire), 0);
652         // Did we create only two spans? Note: spans start at 1, hence the -1.
653         assert_eq!(subscriber.inner.max_span_id.load(Ordering::Acquire) - 1, 2);
654         // Was the value recorded at the right depth i.e. in the right function?
655         // If so, was it the expected value?
656         assert_eq!(*subscriber.inner.value.lock().unwrap(), Some(("val", 5, 2)));
657     }
658 }
659 
660 // https://github.com/dtolnay/async-trait/issues/46
661 pub mod issue46 {
662     use async_trait::async_trait;
663 
664     macro_rules! implement_commands_workaround {
665         ($tyargs:tt : $ty:tt) => {
666             #[async_trait]
667             pub trait AsyncCommands1: Sized {
668                 async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
669                     self.f(x).await
670                 }
671             }
672         };
673     }
674 
675     implement_commands_workaround!(K: Send);
676 
677     macro_rules! implement_commands {
678         ($tyargs:ident : $ty:ident) => {
679             #[async_trait]
680             pub trait AsyncCommands2: Sized {
681                 async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
682                     self.f(x).await
683                 }
684             }
685         };
686     }
687 
688     implement_commands!(K: Send);
689 }
690 
691 // https://github.com/dtolnay/async-trait/issues/53
692 pub mod issue53 {
693     use async_trait::async_trait;
694 
695     pub struct Unit;
696     pub struct Tuple(pub u8);
697     pub struct Struct {
698         pub x: u8,
699     }
700 
701     #[async_trait]
702     pub trait Trait {
method()703         async fn method();
704     }
705 
706     #[async_trait]
707     impl Trait for Unit {
method()708         async fn method() {
709             let _ = Self;
710         }
711     }
712 
713     #[async_trait]
714     impl Trait for Tuple {
method()715         async fn method() {
716             let _ = Self(0);
717         }
718     }
719 
720     #[async_trait]
721     impl Trait for Struct {
method()722         async fn method() {
723             let _ = Self { x: 0 };
724         }
725     }
726 
727     #[async_trait]
728     impl Trait for std::marker::PhantomData<Struct> {
method()729         async fn method() {
730             let _ = Self;
731         }
732     }
733 }
734 
735 // https://github.com/dtolnay/async-trait/issues/57
736 pub mod issue57 {
737     use crate::executor;
738     use async_trait::async_trait;
739 
740     #[async_trait]
741     trait Trait {
const_generic<T: Send, const C: usize>(_: [T; C])742         async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
743     }
744 
745     struct Struct;
746 
747     #[async_trait]
748     impl Trait for Struct {
const_generic<T: Send, const C: usize>(_: [T; C])749         async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
750     }
751 
752     #[test]
test()753     fn test() {
754         let fut = Struct::const_generic([0; 10]);
755         executor::block_on_simple(fut);
756     }
757 }
758 
759 // https://github.com/dtolnay/async-trait/issues/68
760 pub mod issue68 {
761     #[async_trait::async_trait]
762     pub trait Example {
method(&self)763         async fn method(&self) {
764             macro_rules! t {
765                 () => {{
766                     let _: &Self = self;
767                 }};
768             }
769             t!();
770         }
771     }
772 }
773 
774 // https://github.com/dtolnay/async-trait/issues/73
775 pub mod issue73 {
776     use async_trait::async_trait;
777 
778     #[async_trait]
779     pub trait Example {
780         const ASSOCIATED: &'static str;
781 
associated(&self)782         async fn associated(&self) {
783             println!("Associated:{}", Self::ASSOCIATED);
784         }
785     }
786 }
787 
788 // https://github.com/dtolnay/async-trait/issues/81
789 pub mod issue81 {
790     use async_trait::async_trait;
791 
792     #[async_trait]
793     pub trait Trait {
handle(&self)794         async fn handle(&self);
795     }
796 
797     pub enum Enum {
798         Variant,
799     }
800 
801     #[async_trait]
802     impl Trait for Enum {
handle(&self)803         async fn handle(&self) {
804             let Enum::Variant = self;
805             let Self::Variant = self;
806         }
807     }
808 }
809 
810 // https://github.com/dtolnay/async-trait/issues/83
811 pub mod issue83 {
812     #![allow(clippy::needless_arbitrary_self_type)]
813 
814     use async_trait::async_trait;
815 
816     #[async_trait]
817     pub trait Trait {
f(&self)818         async fn f(&self) {}
g(self: &Self)819         async fn g(self: &Self) {}
820     }
821 }
822 
823 // https://github.com/dtolnay/async-trait/issues/85
824 pub mod issue85 {
825     #![deny(non_snake_case)]
826 
827     use async_trait::async_trait;
828 
829     #[async_trait]
830     pub trait Trait {
831         #[allow(non_snake_case)]
camelCase()832         async fn camelCase();
833     }
834 
835     pub struct Struct;
836 
837     #[async_trait]
838     impl Trait for Struct {
camelCase()839         async fn camelCase() {}
840     }
841 }
842 
843 // https://github.com/dtolnay/async-trait/issues/87
844 pub mod issue87 {
845     use async_trait::async_trait;
846 
847     #[async_trait]
848     pub trait Trait {
f(&self)849         async fn f(&self);
850     }
851 
852     pub enum Tuple {
853         V(),
854     }
855 
856     pub enum Struct {
857         V {},
858     }
859 
860     #[async_trait]
861     impl Trait for Tuple {
f(&self)862         async fn f(&self) {
863             let Tuple::V() = self;
864             let Self::V() = self;
865             let _ = Self::V;
866             let _ = Self::V();
867         }
868     }
869 
870     #[async_trait]
871     impl Trait for Struct {
f(&self)872         async fn f(&self) {
873             let Struct::V {} = self;
874             let Self::V {} = self;
875             let _ = Self::V {};
876         }
877     }
878 }
879 
880 // https://github.com/dtolnay/async-trait/issues/89
881 pub mod issue89 {
882     #![allow(bare_trait_objects)]
883 
884     use async_trait::async_trait;
885 
886     #[async_trait]
887     pub trait Trait {
f(&self)888         async fn f(&self);
889     }
890 
891     #[async_trait]
892     impl Trait for dyn Send + Sync {
f(&self)893         async fn f(&self) {}
894     }
895 
896     #[async_trait]
897     impl Trait for dyn Fn(i8) + Send + Sync {
f(&self)898         async fn f(&self) {}
899     }
900 
901     #[async_trait]
902     impl Trait for (dyn Fn(u8) + Send + Sync) {
f(&self)903         async fn f(&self) {}
904     }
905 }
906 
907 // https://github.com/dtolnay/async-trait/issues/92
908 pub mod issue92 {
909     use async_trait::async_trait;
910 
911     macro_rules! mac {
912         ($($tt:tt)*) => {
913             $($tt)*
914         };
915     }
916 
917     pub struct Struct<T> {
918         _x: T,
919     }
920 
921     impl<T> Struct<T> {
922         const ASSOCIATED1: &'static str = "1";
associated1()923         async fn associated1() {}
924     }
925 
926     #[async_trait]
927     pub trait Trait
928     where
929         mac!(Self): Send,
930     {
931         const ASSOCIATED2: &'static str;
932         type Associated2;
933 
934         #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)]
associated2(&self)935         async fn associated2(&self) {
936             // trait items
937             mac!(let _: Self::Associated2;);
938             mac!(let _: <Self>::Associated2;);
939             mac!(let _: <Self as Trait>::Associated2;);
940             mac!(Self::ASSOCIATED2;);
941             mac!(<Self>::ASSOCIATED2;);
942             mac!(<Self as Trait>::ASSOCIATED2;);
943             mac!(let _ = Self::associated2(self););
944             mac!(let _ = <Self>::associated2(self););
945             mac!(let _ = <Self as Trait>::associated2(self););
946         }
947     }
948 
949     #[async_trait]
950     impl<T: Send + Sync> Trait for Struct<T>
951     where
952         mac!(Self): Send,
953     {
954         const ASSOCIATED2: &'static str = "2";
955         type Associated2 = ();
956 
957         #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)]
associated2(&self)958         async fn associated2(&self) {
959             // inherent items
960             mac!(Self::ASSOCIATED1;);
961             mac!(<Self>::ASSOCIATED1;);
962             mac!(let _ = Self::associated1(););
963             mac!(let _ = <Self>::associated1(););
964 
965             // trait items
966             mac!(let (): <Self as Trait>::Associated2;);
967             mac!(Self::ASSOCIATED2;);
968             mac!(<Self>::ASSOCIATED2;);
969             mac!(<Self as Trait>::ASSOCIATED2;);
970             mac!(let _ = Self::associated2(self););
971             mac!(let _ = <Self>::associated2(self););
972             mac!(let _ = <Self as Trait>::associated2(self););
973         }
974     }
975 
976     pub struct Unit;
977 
978     #[async_trait]
979     impl Trait for Unit {
980         const ASSOCIATED2: &'static str = "2";
981         type Associated2 = ();
982 
associated2(&self)983         async fn associated2(&self) {
984             mac!(let Self: Self = *self;);
985         }
986     }
987 }
988 
989 // https://github.com/dtolnay/async-trait/issues/92#issuecomment-683370136
990 pub mod issue92_2 {
991     use async_trait::async_trait;
992 
993     macro_rules! mac {
994         ($($tt:tt)*) => {
995             $($tt)*
996         };
997     }
998 
999     pub trait Trait1 {
func1()1000         fn func1();
1001     }
1002 
1003     #[async_trait]
1004     pub trait Trait2: Trait1 {
func2()1005         async fn func2() {
1006             mac!(Self::func1());
1007 
1008             macro_rules! mac2 {
1009                 ($($tt:tt)*) => {
1010                     Self::func1();
1011                 };
1012             }
1013             mac2!();
1014         }
1015     }
1016 }
1017 
1018 // https://github.com/dtolnay/async-trait/issues/104
1019 pub mod issue104 {
1020     use async_trait::async_trait;
1021 
1022     #[async_trait]
1023     pub trait T1 {
id(&self) -> i321024         async fn id(&self) -> i32;
1025     }
1026 
1027     macro_rules! impl_t1 {
1028         ($ty:ty, $id:expr) => {
1029             #[async_trait]
1030             impl T1 for $ty {
1031                 async fn id(&self) -> i32 {
1032                     $id
1033                 }
1034             }
1035         };
1036     }
1037 
1038     pub struct Foo;
1039 
1040     impl_t1!(Foo, 1);
1041 }
1042 
1043 // https://github.com/dtolnay/async-trait/issues/106
1044 pub mod issue106 {
1045     use async_trait::async_trait;
1046     use std::future::Future;
1047 
1048     #[async_trait]
1049     pub trait ProcessPool: Send + Sync {
1050         type ThreadPool;
1051 
spawn<F, Fut, T>(&self, work: F) -> T where F: FnOnce(&Self::ThreadPool) -> Fut + Send, Fut: Future<Output = T> + 'static1052         async fn spawn<F, Fut, T>(&self, work: F) -> T
1053         where
1054             F: FnOnce(&Self::ThreadPool) -> Fut + Send,
1055             Fut: Future<Output = T> + 'static;
1056     }
1057 
1058     #[async_trait]
1059     impl<P> ProcessPool for &P
1060     where
1061         P: ?Sized + ProcessPool,
1062     {
1063         type ThreadPool = P::ThreadPool;
1064 
spawn<F, Fut, T>(&self, work: F) -> T where F: FnOnce(&Self::ThreadPool) -> Fut + Send, Fut: Future<Output = T> + 'static,1065         async fn spawn<F, Fut, T>(&self, work: F) -> T
1066         where
1067             F: FnOnce(&Self::ThreadPool) -> Fut + Send,
1068             Fut: Future<Output = T> + 'static,
1069         {
1070             (**self).spawn(work).await
1071         }
1072     }
1073 }
1074 
1075 // https://github.com/dtolnay/async-trait/issues/110
1076 pub mod issue110 {
1077     use async_trait::async_trait;
1078     use std::marker::PhantomData;
1079 
1080     #[async_trait]
1081     pub trait Loader {
load(&self, key: &str)1082         async fn load(&self, key: &str);
1083     }
1084 
1085     pub struct AwsEc2MetadataLoader<'a> {
1086         marker: PhantomData<&'a ()>,
1087     }
1088 
1089     #[async_trait]
1090     impl Loader for AwsEc2MetadataLoader<'_> {
load(&self, _key: &str)1091         async fn load(&self, _key: &str) {}
1092     }
1093 }
1094 
1095 // https://github.com/dtolnay/async-trait/issues/120
1096 pub mod issue120 {
1097     #![deny(clippy::trivially_copy_pass_by_ref)]
1098 
1099     use async_trait::async_trait;
1100 
1101     #[async_trait]
1102     pub trait Trait {
f(&self)1103         async fn f(&self);
1104     }
1105 
1106     #[async_trait]
1107     impl Trait for () {
f(&self)1108         async fn f(&self) {}
1109     }
1110 }
1111 
1112 // https://github.com/dtolnay/async-trait/issues/123
1113 pub mod issue123 {
1114     use async_trait::async_trait;
1115 
1116     #[async_trait]
1117     pub trait Trait<T = ()> {
f(&self) -> &str where T: 'async_trait,1118         async fn f(&self) -> &str
1119         where
1120             T: 'async_trait,
1121         {
1122             "default"
1123         }
1124     }
1125 
1126     #[async_trait]
1127     impl<T> Trait<T> for () {}
1128 }
1129 
1130 // https://github.com/dtolnay/async-trait/issues/129
1131 pub mod issue129 {
1132     use async_trait::async_trait;
1133 
1134     #[async_trait]
1135     pub trait TestTrait {
a(_b: u8, c: u8) -> u81136         async fn a(_b: u8, c: u8) -> u8 {
1137             c
1138         }
1139     }
1140 
1141     pub struct TestStruct;
1142 
1143     #[async_trait]
1144     impl TestTrait for TestStruct {
a(_b: u8, c: u8) -> u81145         async fn a(_b: u8, c: u8) -> u8 {
1146             c
1147         }
1148     }
1149 }
1150 
1151 // https://github.com/dtolnay/async-trait/issues/134
1152 pub mod issue134 {
1153     use async_trait::async_trait;
1154 
1155     #[async_trait]
1156     pub trait TestTrait {
run<const DUMMY: bool>(self) where Self: Sized,1157         async fn run<const DUMMY: bool>(self)
1158         where
1159             Self: Sized,
1160         {
1161         }
1162     }
1163 
1164     pub struct TestStruct;
1165 
1166     #[async_trait]
1167     impl TestTrait for TestStruct {
run<const DUMMY: bool>(self) where Self: Sized,1168         async fn run<const DUMMY: bool>(self)
1169         where
1170             Self: Sized,
1171         {
1172         }
1173     }
1174 }
1175 
1176 // https://github.com/dtolnay/async-trait/pull/125#pullrequestreview-491880881
1177 pub mod drop_order {
1178     use crate::executor;
1179     use async_trait::async_trait;
1180     use std::sync::atomic::{AtomicBool, Ordering};
1181 
1182     struct Flagger<'a>(&'a AtomicBool);
1183 
1184     impl Drop for Flagger<'_> {
drop(&mut self)1185         fn drop(&mut self) {
1186             self.0.fetch_xor(true, Ordering::AcqRel);
1187         }
1188     }
1189 
1190     #[async_trait]
1191     trait Trait {
async_trait(_: Flagger<'_>, flag: &AtomicBool)1192         async fn async_trait(_: Flagger<'_>, flag: &AtomicBool);
1193     }
1194 
1195     struct Struct;
1196 
1197     #[async_trait]
1198     impl Trait for Struct {
async_trait(_: Flagger<'_>, flag: &AtomicBool)1199         async fn async_trait(_: Flagger<'_>, flag: &AtomicBool) {
1200             flag.fetch_or(true, Ordering::AcqRel);
1201         }
1202     }
1203 
standalone(_: Flagger<'_>, flag: &AtomicBool)1204     async fn standalone(_: Flagger<'_>, flag: &AtomicBool) {
1205         flag.fetch_or(true, Ordering::AcqRel);
1206     }
1207 
1208     #[async_trait]
1209     trait SelfTrait {
async_trait(self, flag: &AtomicBool)1210         async fn async_trait(self, flag: &AtomicBool);
1211     }
1212 
1213     #[async_trait]
1214     impl SelfTrait for Flagger<'_> {
async_trait(self, flag: &AtomicBool)1215         async fn async_trait(self, flag: &AtomicBool) {
1216             flag.fetch_or(true, Ordering::AcqRel);
1217         }
1218     }
1219 
1220     #[test]
test_drop_order()1221     fn test_drop_order() {
1222         // 0 : 0 ^ 1 = 1 | 1 = 1 (if flagger then block)
1223         // 0 : 0 | 1 = 1 ^ 1 = 0 (if block then flagger)
1224 
1225         let flag = AtomicBool::new(false);
1226         executor::block_on_simple(standalone(Flagger(&flag), &flag));
1227         assert!(!flag.load(Ordering::Acquire));
1228 
1229         executor::block_on_simple(Struct::async_trait(Flagger(&flag), &flag));
1230         assert!(!flag.load(Ordering::Acquire));
1231 
1232         executor::block_on_simple(Flagger(&flag).async_trait(&flag));
1233         assert!(!flag.load(Ordering::Acquire));
1234     }
1235 }
1236 
1237 // https://github.com/dtolnay/async-trait/issues/145
1238 pub mod issue145 {
1239     #![deny(clippy::type_complexity)]
1240 
1241     use async_trait::async_trait;
1242 
1243     #[async_trait]
1244     pub trait ManageConnection: Sized + Send + Sync + 'static {
1245         type Connection: Send + 'static;
1246         type Error: Send + 'static;
1247 
connect(&self) -> Result<Self::Connection, Self::Error>1248         async fn connect(&self) -> Result<Self::Connection, Self::Error>;
1249     }
1250 }
1251 
1252 // https://github.com/dtolnay/async-trait/issues/147
1253 pub mod issue147 {
1254     #![deny(clippy::let_unit_value)]
1255 
1256     use async_trait::async_trait;
1257 
1258     pub struct MyType;
1259 
1260     #[async_trait]
1261     pub trait MyTrait {
x()1262         async fn x();
y() -> ()1263         async fn y() -> ();
z()1264         async fn z();
1265     }
1266 
1267     #[async_trait]
1268     impl MyTrait for MyType {
x()1269         async fn x() {}
y() -> ()1270         async fn y() -> () {}
z()1271         async fn z() {
1272             unimplemented!()
1273         }
1274     }
1275 }
1276 
1277 // https://github.com/dtolnay/async-trait/issues/149
1278 pub mod issue149 {
1279     use async_trait::async_trait;
1280 
1281     pub struct Thing;
1282     pub trait Ret {}
1283     impl Ret for Thing {}
1284 
ok() -> &'static dyn Ret1285     pub async fn ok() -> &'static dyn Ret {
1286         return &Thing;
1287     }
1288 
1289     #[async_trait]
1290     pub trait Trait {
fail() -> &'static dyn Ret1291         async fn fail() -> &'static dyn Ret {
1292             return &Thing;
1293         }
1294     }
1295 }
1296 
1297 // https://github.com/dtolnay/async-trait/issues/152
1298 #[cfg(async_trait_nightly_testing)]
1299 pub mod issue152 {
1300     use async_trait::async_trait;
1301 
1302     #[async_trait]
1303     pub trait Trait {
1304         type Assoc;
1305 
f(&self) -> Self::Assoc1306         async fn f(&self) -> Self::Assoc;
1307     }
1308 
1309     pub struct Struct;
1310 
1311     #[async_trait]
1312     impl Trait for Struct {
1313         type Assoc = impl Sized;
1314 
1315         async fn f(&self) -> Self::Assoc {}
1316     }
1317 }
1318 
1319 // https://github.com/dtolnay/async-trait/issues/154
1320 pub mod issue154 {
1321     #![deny(clippy::items_after_statements)]
1322 
1323     use async_trait::async_trait;
1324 
1325     #[async_trait]
1326     pub trait MyTrait {
f(&self)1327         async fn f(&self);
1328     }
1329 
1330     pub struct Struct;
1331 
1332     #[async_trait]
1333     impl MyTrait for Struct {
f(&self)1334         async fn f(&self) {
1335             const MAX: u16 = 128;
1336             println!("{}", MAX);
1337         }
1338     }
1339 }
1340 
1341 // https://github.com/dtolnay/async-trait/issues/158
1342 pub mod issue158 {
1343     use async_trait::async_trait;
1344 
f()1345     fn f() {}
1346 
1347     #[async_trait]
1348     #[allow(unused_qualifications)]
1349     pub trait Trait {
f(&self)1350         async fn f(&self) {
1351             self::f();
1352         }
1353     }
1354 }
1355 
1356 // https://github.com/dtolnay/async-trait/issues/161
1357 #[allow(clippy::mut_mut)]
1358 pub mod issue161 {
1359     use async_trait::async_trait;
1360     use futures::future::FutureExt;
1361     use std::sync::Arc;
1362 
1363     #[async_trait]
1364     pub trait Trait {
f(self: Arc<Self>)1365         async fn f(self: Arc<Self>);
1366     }
1367 
1368     pub struct MyStruct(bool);
1369 
1370     #[async_trait]
1371     impl Trait for MyStruct {
f(self: Arc<Self>)1372         async fn f(self: Arc<Self>) {
1373             futures::select! {
1374                 () = async {
1375                     println!("{}", self.0);
1376                 }.fuse() => {}
1377             }
1378         }
1379     }
1380 }
1381 
1382 // https://github.com/dtolnay/async-trait/issues/169
1383 pub mod issue169 {
1384     use async_trait::async_trait;
1385 
1386     #[async_trait]
1387     #[allow(unused_qualifications)]
1388     pub trait Trait: ::core::marker::Sync {
f(&self)1389         async fn f(&self) {}
1390     }
1391 
test(_t: &dyn Trait)1392     pub fn test(_t: &dyn Trait) {}
1393 }
1394 
1395 // https://github.com/dtolnay/async-trait/issues/177
1396 pub mod issue177 {
1397     use async_trait::async_trait;
1398 
1399     #[async_trait]
1400     pub trait Trait {
foo(&self, _callback: impl FnMut(&str) + Send)1401         async fn foo(&self, _callback: impl FnMut(&str) + Send) {}
1402     }
1403 
1404     pub struct Struct;
1405 
1406     #[async_trait]
1407     impl Trait for Struct {
foo(&self, _callback: impl FnMut(&str) + Send)1408         async fn foo(&self, _callback: impl FnMut(&str) + Send) {}
1409     }
1410 }
1411 
1412 // https://github.com/dtolnay/async-trait/issues/183
1413 pub mod issue183 {
1414     #![deny(clippy::shadow_same)]
1415 
1416     use async_trait::async_trait;
1417 
1418     #[async_trait]
1419     pub trait Foo {
foo(_n: i32)1420         async fn foo(_n: i32) {}
1421     }
1422 }
1423 
1424 // https://github.com/dtolnay/async-trait/issues/199
1425 pub mod issue199 {
1426     use async_trait::async_trait;
1427     use std::cell::Cell;
1428 
1429     struct IncrementOnDrop<'a>(&'a Cell<usize>);
1430 
1431     impl<'a> Drop for IncrementOnDrop<'a> {
drop(&mut self)1432         fn drop(&mut self) {
1433             self.0.set(self.0.get() + 1);
1434         }
1435     }
1436 
1437     #[async_trait(?Send)]
1438     trait Trait {
f(counter: &Cell<usize>, arg: IncrementOnDrop<'_>)1439         async fn f(counter: &Cell<usize>, arg: IncrementOnDrop<'_>);
1440     }
1441 
1442     struct Struct;
1443 
1444     #[async_trait(?Send)]
1445     impl Trait for Struct {
f(counter: &Cell<usize>, _: IncrementOnDrop<'_>)1446         async fn f(counter: &Cell<usize>, _: IncrementOnDrop<'_>) {
1447             assert_eq!(counter.get(), 0); // second arg not dropped yet
1448         }
1449     }
1450 
1451     #[test]
test()1452     fn test() {
1453         let counter = Cell::new(0);
1454         let future = Struct::f(&counter, IncrementOnDrop(&counter));
1455         assert_eq!(counter.get(), 0);
1456         drop(future);
1457         assert_eq!(counter.get(), 1);
1458     }
1459 }
1460 
1461 // https://github.com/dtolnay/async-trait/issues/204
1462 pub mod issue204 {
1463     use async_trait::async_trait;
1464 
1465     #[async_trait]
1466     pub trait Trait {
f(arg: &impl Trait)1467         async fn f(arg: &impl Trait);
g(arg: *const impl Trait)1468         async fn g(arg: *const impl Trait);
1469     }
1470 }
1471 
1472 // https://github.com/dtolnay/async-trait/issues/210
1473 pub mod issue210 {
1474     use async_trait::async_trait;
1475     use std::sync::Arc;
1476 
1477     #[async_trait]
1478     pub trait Trait {
f(self: Arc<Self>)1479         async fn f(self: Arc<Self>) {}
1480     }
1481 }
1482 
1483 // https://github.com/dtolnay/async-trait/issues/226
1484 pub mod issue226 {
1485     use async_trait::async_trait;
1486 
1487     #[async_trait]
1488     pub trait Trait {
cfg_param(&self, param: u8)1489         async fn cfg_param(&self, param: u8);
cfg_param_wildcard(&self, _: u8)1490         async fn cfg_param_wildcard(&self, _: u8);
cfg_param_tuple(&self, (left, right): (u8, u8))1491         async fn cfg_param_tuple(&self, (left, right): (u8, u8));
1492     }
1493 
1494     #[allow(dead_code)]
1495     struct Struct;
1496 
1497     #[async_trait]
1498     impl Trait for Struct {
cfg_param(&self, #[cfg(any())] param: u8, #[cfg(all())] _unused: u8)1499         async fn cfg_param(&self, #[cfg(any())] param: u8, #[cfg(all())] _unused: u8) {}
1500 
cfg_param_wildcard(&self, #[cfg(any())] _: u8, #[cfg(all())] _: u8)1501         async fn cfg_param_wildcard(&self, #[cfg(any())] _: u8, #[cfg(all())] _: u8) {}
1502 
cfg_param_tuple( &self, #[cfg(any())] (left, right): (u8, u8), #[cfg(all())] (_left, _right): (u8, u8), )1503         async fn cfg_param_tuple(
1504             &self,
1505             #[cfg(any())] (left, right): (u8, u8),
1506             #[cfg(all())] (_left, _right): (u8, u8),
1507         ) {
1508         }
1509     }
1510 }
1511 
1512 // https://github.com/dtolnay/async-trait/issues/232
1513 pub mod issue232 {
1514     use async_trait::async_trait;
1515 
1516     #[async_trait]
1517     pub trait Generic<T> {
take_ref(&self, thing: &T)1518         async fn take_ref(&self, thing: &T);
1519     }
1520 
1521     pub struct One;
1522 
1523     #[async_trait]
1524     impl<T> Generic<T> for One {
take_ref(&self, _: &T)1525         async fn take_ref(&self, _: &T) {}
1526     }
1527 
1528     pub struct Two;
1529 
1530     #[async_trait]
1531     impl<T: Sync> Generic<(T, T)> for Two {
take_ref(&self, (a, b): &(T, T))1532         async fn take_ref(&self, (a, b): &(T, T)) {
1533             let _ = a;
1534             let _ = b;
1535         }
1536     }
1537 
1538     pub struct Three;
1539 
1540     #[async_trait]
1541     impl<T> Generic<(T, T, T)> for Three {
take_ref(&self, (_a, _b, _c): &(T, T, T))1542         async fn take_ref(&self, (_a, _b, _c): &(T, T, T)) {}
1543     }
1544 }
1545 
1546 // https://github.com/dtolnay/async-trait/issues/234
1547 pub mod issue234 {
1548     use async_trait::async_trait;
1549 
1550     pub struct Droppable;
1551 
1552     impl Drop for Droppable {
drop(&mut self)1553         fn drop(&mut self) {}
1554     }
1555 
1556     pub struct Tuple<T, U>(T, U);
1557 
1558     #[async_trait]
1559     pub trait Trait {
f(arg: Tuple<Droppable, i32>)1560         async fn f(arg: Tuple<Droppable, i32>);
1561     }
1562 
1563     pub struct UnderscorePattern;
1564 
1565     #[async_trait]
1566     impl Trait for UnderscorePattern {
f(Tuple(_, _int): Tuple<Droppable, i32>)1567         async fn f(Tuple(_, _int): Tuple<Droppable, i32>) {}
1568     }
1569 
1570     pub struct DotDotPattern;
1571 
1572     #[async_trait]
1573     impl Trait for DotDotPattern {
1574         async fn f(Tuple { 1: _int, .. }: Tuple<Droppable, i32>) {}
1575     }
1576 }
1577 
1578 // https://github.com/dtolnay/async-trait/issues/236
1579 pub mod issue236 {
1580     #![deny(clippy::async_yields_async)]
1581     #![allow(clippy::manual_async_fn)]
1582 
1583     use async_trait::async_trait;
1584     use std::future::{self, Future, Ready};
1585 
1586     // Does not trigger the lint.
async_fn() -> Ready<()>1587     pub async fn async_fn() -> Ready<()> {
1588         future::ready(())
1589     }
1590 
1591     #[allow(clippy::async_yields_async)]
impl_future_fn() -> impl Future<Output = Ready<()>>1592     pub fn impl_future_fn() -> impl Future<Output = Ready<()>> {
1593         async { future::ready(()) }
1594     }
1595 
1596     // The async_trait attribute turns the former into the latter, so we make it
1597     // put its own allow(async_yeilds_async) to remain consistent with async fn.
1598     #[async_trait]
1599     pub trait Trait {
f() -> Ready<()>1600         async fn f() -> Ready<()> {
1601             future::ready(())
1602         }
1603     }
1604 }
1605 
1606 // https://github.com/dtolnay/async-trait/issues/238
1607 pub mod issue238 {
1608     #![deny(single_use_lifetimes)]
1609 
1610     use async_trait::async_trait;
1611 
1612     #[async_trait]
1613     pub trait Trait {
f()1614         async fn f();
1615     }
1616 
1617     pub struct Struct;
1618 
1619     #[async_trait]
1620     impl Trait for &Struct {
f()1621         async fn f() {}
1622     }
1623 }
1624 
1625 // https://github.com/dtolnay/async-trait/issues/266
1626 #[cfg(async_trait_nightly_testing)]
1627 pub mod issue266 {
1628     use async_trait::async_trait;
1629 
1630     #[async_trait]
1631     pub trait Trait {
f() -> !1632         async fn f() -> !;
1633     }
1634 
1635     #[async_trait]
1636     impl Trait for () {
f() -> !1637         async fn f() -> ! {
1638             loop {
1639                 std::thread::sleep(std::time::Duration::from_millis(1));
1640             }
1641         }
1642     }
1643 }
1644 
1645 // https://github.com/dtolnay/async-trait/issues/277
1646 pub mod issue277 {
1647     use async_trait::async_trait;
1648 
1649     #[async_trait]
1650     pub trait Trait {
f(&self)1651         async fn f(&self);
1652     }
1653 
1654     #[async_trait]
1655     impl Trait for () {
f(mut self: &Self)1656         async fn f(mut self: &Self) {
1657             g(&mut self);
1658         }
1659     }
1660 
g(_: &mut &())1661     fn g(_: &mut &()) {}
1662 }
1663