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