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