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