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