• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg_attr(
2     async_trait_nightly_testing,
3     feature(min_specialization, type_alias_impl_trait)
4 )]
5 #![deny(rust_2021_compatibility)]
6 #![allow(
7     clippy::let_unit_value,
8     clippy::missing_panics_doc,
9     clippy::missing_safety_doc,
10     clippy::needless_return,
11     clippy::trivially_copy_pass_by_ref,
12     clippy::unused_async
13 )]
14 
15 use async_trait::async_trait;
16 
17 pub mod executor;
18 
19 // Dummy module to check that the expansion refer to rust's core crate
20 mod core {}
21 
22 #[async_trait]
23 trait Trait {
24     type Assoc;
25 
selfvalue(self) where Self: Sized,26     async fn selfvalue(self)
27     where
28         Self: Sized,
29     {
30     }
31 
selfref(&self)32     async fn selfref(&self) {}
33 
selfmut(&mut self)34     async fn selfmut(&mut self) {}
35 
required() -> Self::Assoc36     async fn required() -> Self::Assoc;
37 
elided_lifetime(_x: &str)38     async fn elided_lifetime(_x: &str) {}
39 
explicit_lifetime<'a>(_x: &'a str)40     async fn explicit_lifetime<'a>(_x: &'a str) {}
41 
generic_type_param<T: Send>(x: Box<T>) -> T42     async fn generic_type_param<T: Send>(x: Box<T>) -> T {
43         *x
44     }
45 
calls(&self)46     async fn calls(&self) {
47         self.selfref().await;
48         Self::elided_lifetime("").await;
49         <Self>::elided_lifetime("").await;
50     }
51 
calls_mut(&mut self)52     async fn calls_mut(&mut self) {
53         self.selfmut().await;
54     }
55 }
56 
57 struct Struct;
58 
59 #[async_trait]
60 impl Trait for Struct {
61     type Assoc = ();
62 
selfvalue(self)63     async fn selfvalue(self) {}
64 
selfref(&self)65     async fn selfref(&self) {}
66 
selfmut(&mut self)67     async fn selfmut(&mut self) {}
68 
required() -> Self::Assoc69     async fn required() -> Self::Assoc {}
70 
elided_lifetime(_x: &str)71     async fn elided_lifetime(_x: &str) {}
72 
explicit_lifetime<'a>(_x: &'a str)73     async fn explicit_lifetime<'a>(_x: &'a str) {}
74 
generic_type_param<T: Send>(x: Box<T>) -> T75     async fn generic_type_param<T: Send>(x: Box<T>) -> T {
76         *x
77     }
78 
calls(&self)79     async fn calls(&self) {
80         self.selfref().await;
81         Self::elided_lifetime("").await;
82         <Self>::elided_lifetime("").await;
83     }
84 
calls_mut(&mut self)85     async fn calls_mut(&mut self) {
86         self.selfmut().await;
87     }
88 }
89 
test()90 pub async fn test() {
91     let mut s = Struct;
92     s.selfref().await;
93     s.selfmut().await;
94     s.selfvalue().await;
95 
96     Struct::required().await;
97     Struct::elided_lifetime("").await;
98     Struct::explicit_lifetime("").await;
99     Struct::generic_type_param(Box::new("")).await;
100 
101     let mut s = Struct;
102     s.calls().await;
103     s.calls_mut().await;
104 }
105 
test_object_safe_without_default()106 pub async fn test_object_safe_without_default() {
107     #[async_trait]
108     trait ObjectSafe {
109         async fn f(&self);
110     }
111 
112     #[async_trait]
113     impl ObjectSafe for Struct {
114         async fn f(&self) {}
115     }
116 
117     let object = &Struct as &dyn ObjectSafe;
118     object.f().await;
119 }
120 
test_object_safe_with_default()121 pub async fn test_object_safe_with_default() {
122     #[async_trait]
123     trait ObjectSafe: Sync {
124         async fn f(&self) {}
125     }
126 
127     #[async_trait]
128     impl ObjectSafe for Struct {
129         async fn f(&self) {}
130     }
131 
132     let object = &Struct as &dyn ObjectSafe;
133     object.f().await;
134 }
135 
test_object_no_send()136 pub async fn test_object_no_send() {
137     #[async_trait(?Send)]
138     trait ObjectSafe: Sync {
139         async fn f(&self) {}
140     }
141 
142     #[async_trait(?Send)]
143     impl ObjectSafe for Struct {
144         async fn f(&self) {}
145     }
146 
147     let object = &Struct as &dyn ObjectSafe;
148     object.f().await;
149 }
150 
151 #[async_trait]
152 pub unsafe trait UnsafeTrait {}
153 
154 #[async_trait]
155 unsafe impl UnsafeTrait for () {}
156 
157 #[async_trait]
158 pub(crate) unsafe trait UnsafeTraitPubCrate {}
159 
160 #[async_trait]
161 unsafe trait UnsafeTraitPrivate {}
162 
test_can_destruct()163 pub async fn test_can_destruct() {
164     #[async_trait]
165     trait CanDestruct {
166         async fn f(&self, foos: (u8, u8, u8, u8));
167     }
168 
169     #[async_trait]
170     impl CanDestruct for Struct {
171         async fn f(&self, (a, ref mut b, ref c, d): (u8, u8, u8, u8)) {
172             let _a: u8 = a;
173             let _b: &mut u8 = b;
174             let _c: &u8 = c;
175             let _d: u8 = d;
176         }
177     }
178 }
179 
test_self_in_macro()180 pub async fn test_self_in_macro() {
181     #[async_trait]
182     trait Trait {
183         async fn a(self);
184         async fn b(&mut self);
185         async fn c(&self);
186     }
187 
188     #[async_trait]
189     impl Trait for String {
190         async fn a(self) {
191             println!("{}", self);
192         }
193         async fn b(&mut self) {
194             println!("{}", self);
195         }
196         async fn c(&self) {
197             println!("{}", self);
198         }
199     }
200 }
201 
test_inference()202 pub async fn test_inference() {
203     #[async_trait]
204     pub trait Trait {
205         async fn f() -> Box<dyn Iterator<Item = ()>> {
206             Box::new(std::iter::empty())
207         }
208     }
209 }
210 
test_internal_items()211 pub async fn test_internal_items() {
212     #[async_trait]
213     #[allow(dead_code, clippy::items_after_statements)]
214     pub trait Trait: Sized {
215         async fn f(self) {
216             struct Struct;
217 
218             impl Struct {
219                 fn f(self) {
220                     let _ = self;
221                 }
222             }
223         }
224     }
225 }
226 
test_unimplemented()227 pub async fn test_unimplemented() {
228     #[async_trait]
229     pub trait Trait {
230         async fn f() {
231             unimplemented!()
232         }
233     }
234 }
235 
236 // https://github.com/dtolnay/async-trait/issues/1
237 pub mod issue1 {
238     use async_trait::async_trait;
239 
240     #[async_trait]
241     trait Issue1 {
f<U>(&self)242         async fn f<U>(&self);
243     }
244 
245     #[async_trait]
246     impl<T: Sync> Issue1 for Vec<T> {
f<U>(&self)247         async fn f<U>(&self) {}
248     }
249 }
250 
251 // https://github.com/dtolnay/async-trait/issues/2
252 pub mod issue2 {
253     use async_trait::async_trait;
254     use std::future::Future;
255 
256     #[async_trait]
257     pub trait Issue2: Future {
flatten(self) -> <Self::Output as Future>::Output where Self::Output: Future + Send, Self: Sized,258         async fn flatten(self) -> <Self::Output as Future>::Output
259         where
260             Self::Output: Future + Send,
261             Self: Sized,
262         {
263             let nested_future = self.await;
264             nested_future.await
265         }
266     }
267 }
268 
269 // https://github.com/dtolnay/async-trait/issues/9
270 pub mod issue9 {
271     use async_trait::async_trait;
272 
273     #[async_trait]
274     pub trait Issue9: Sized + Send {
f(_x: Self)275         async fn f(_x: Self) {}
276     }
277 }
278 
279 // https://github.com/dtolnay/async-trait/issues/11
280 pub mod issue11 {
281     use async_trait::async_trait;
282     use std::sync::Arc;
283 
284     #[async_trait]
285     trait Issue11 {
example(self: Arc<Self>)286         async fn example(self: Arc<Self>);
287     }
288 
289     struct Struct;
290 
291     #[async_trait]
292     impl Issue11 for Struct {
example(self: Arc<Self>)293         async fn example(self: Arc<Self>) {}
294     }
295 }
296 
297 // https://github.com/dtolnay/async-trait/issues/15
298 pub mod issue15 {
299     use async_trait::async_trait;
300     use std::marker::PhantomData;
301 
302     trait Trait {}
303 
304     #[async_trait]
305     trait Issue15 {
myfn(&self, _: PhantomData<dyn Trait + Send>)306         async fn myfn(&self, _: PhantomData<dyn Trait + Send>) {}
307     }
308 }
309 
310 // https://github.com/dtolnay/async-trait/issues/17
311 pub mod issue17 {
312     use async_trait::async_trait;
313 
314     #[async_trait]
315     trait Issue17 {
f(&self)316         async fn f(&self);
317     }
318 
319     struct Struct {
320         string: String,
321     }
322 
323     #[async_trait]
324     impl Issue17 for Struct {
f(&self)325         async fn f(&self) {
326             println!("{}", self.string);
327         }
328     }
329 }
330 
331 // https://github.com/dtolnay/async-trait/issues/23
332 pub mod issue23 {
333     use async_trait::async_trait;
334 
335     #[async_trait]
336     pub trait Issue23 {
f(self)337         async fn f(self);
338 
g(mut self) where Self: Sized,339         async fn g(mut self)
340         where
341             Self: Sized,
342         {
343             do_something(&mut self);
344         }
345     }
346 
347     struct S {}
348 
349     #[async_trait]
350     impl Issue23 for S {
f(mut self)351         async fn f(mut self) {
352             do_something(&mut self);
353         }
354     }
355 
do_something<T>(_: &mut T)356     fn do_something<T>(_: &mut T) {}
357 }
358 
359 // https://github.com/dtolnay/async-trait/issues/25
360 #[cfg(async_trait_nightly_testing)]
361 pub mod issue25 {
362     use crate::executor;
363     use async_trait::async_trait;
364     use std::fmt::{Display, Write};
365 
366     #[async_trait]
367     trait AsyncToString {
async_to_string(&self) -> String368         async fn async_to_string(&self) -> String;
369     }
370 
371     #[async_trait]
372     impl AsyncToString for String {
async_to_string(&self) -> String373         async fn async_to_string(&self) -> String {
374             "special".to_owned()
375         }
376     }
377 
378     macro_rules! hide_from_stable_parser {
379         ($($tt:tt)*) => {
380             $($tt)*
381         };
382     }
383 
384     hide_from_stable_parser! {
385         #[async_trait]
386         impl<T: ?Sized + Display + Sync> AsyncToString for T {
387             default async fn async_to_string(&self) -> String {
388                 let mut buf = String::new();
389                 buf.write_fmt(format_args!("{}", self)).unwrap();
390                 buf
391             }
392         }
393     }
394 
395     #[test]
test()396     fn test() {
397         let fut = true.async_to_string();
398         assert_eq!(executor::block_on_simple(fut), "true");
399 
400         let string = String::new();
401         let fut = string.async_to_string();
402         assert_eq!(executor::block_on_simple(fut), "special");
403     }
404 }
405 
406 // https://github.com/dtolnay/async-trait/issues/28
407 pub mod issue28 {
408     use async_trait::async_trait;
409 
410     struct Str<'a>(&'a str);
411 
412     #[async_trait]
413     trait Trait1<'a> {
f(x: Str<'a>) -> &'a str414         async fn f(x: Str<'a>) -> &'a str;
g(x: Str<'a>) -> &'a str415         async fn g(x: Str<'a>) -> &'a str {
416             x.0
417         }
418     }
419 
420     #[async_trait]
421     impl<'a> Trait1<'a> for str {
f(x: Str<'a>) -> &'a str422         async fn f(x: Str<'a>) -> &'a str {
423             x.0
424         }
425     }
426 
427     #[async_trait]
428     trait Trait2 {
f()429         async fn f();
430     }
431 
432     #[async_trait]
433     impl<'a> Trait2 for &'a () {
f()434         async fn f() {}
435     }
436 
437     #[async_trait]
438     trait Trait3<'a, 'b> {
f(_: &'a &'b ())439         async fn f(_: &'a &'b ()); // chain 'a and 'b
g(_: &'b ())440         async fn g(_: &'b ()); // chain 'b only
h()441         async fn h(); // do not chain
442     }
443 }
444 
445 // https://github.com/dtolnay/async-trait/issues/31
446 pub mod issue31 {
447     use async_trait::async_trait;
448 
449     pub struct Struct<'a> {
450         pub name: &'a str,
451     }
452 
453     #[async_trait]
454     pub trait Trait<'a> {
hello(thing: Struct<'a>) -> String455         async fn hello(thing: Struct<'a>) -> String;
hello_twice(one: Struct<'a>, two: Struct<'a>) -> String456         async fn hello_twice(one: Struct<'a>, two: Struct<'a>) -> String {
457             let str1 = Self::hello(one).await;
458             let str2 = Self::hello(two).await;
459             str1 + &str2
460         }
461     }
462 }
463 
464 // https://github.com/dtolnay/async-trait/issues/42
465 pub mod issue42 {
466     use async_trait::async_trait;
467 
468     #[async_trait]
469     pub trait Context: Sized {
from_parts() -> Self470         async fn from_parts() -> Self;
471     }
472 
473     pub struct TokenContext;
474 
475     #[async_trait]
476     impl Context for TokenContext {
from_parts() -> TokenContext477         async fn from_parts() -> TokenContext {
478             TokenContext
479         }
480     }
481 }
482 
483 // https://github.com/dtolnay/async-trait/issues/44
484 pub mod issue44 {
485     use async_trait::async_trait;
486 
487     #[async_trait]
488     pub trait StaticWithWhereSelf
489     where
490         Box<Self>: Sized,
491         Self: Sized + Send,
492     {
get_one() -> u8493         async fn get_one() -> u8 {
494             1
495         }
496     }
497 
498     pub struct Struct;
499 
500     #[async_trait]
501     impl StaticWithWhereSelf for Struct {}
502 }
503 
504 // https://github.com/dtolnay/async-trait/issues/45
505 pub mod issue45 {
506     use crate::executor;
507     use async_trait::async_trait;
508     use std::fmt::Debug;
509     use std::sync::atomic::{AtomicU64, Ordering};
510     use std::sync::{Arc, Mutex};
511     use tracing::event::Event;
512     use tracing::field::{Field, Visit};
513     use tracing::span::{Attributes, Id, Record};
514     use tracing::{info, instrument, subscriber, Metadata, Subscriber};
515 
516     #[async_trait]
517     pub trait Parent {
foo(&mut self, v: usize)518         async fn foo(&mut self, v: usize);
519     }
520 
521     #[async_trait]
522     pub trait Child {
bar(&self)523         async fn bar(&self);
524     }
525 
526     #[derive(Debug)]
527     struct Impl(usize);
528 
529     #[async_trait]
530     impl Parent for Impl {
531         #[instrument]
foo(&mut self, v: usize)532         async fn foo(&mut self, v: usize) {
533             self.0 = v;
534             self.bar().await;
535         }
536     }
537 
538     #[async_trait]
539     impl Child for Impl {
540         // Let's check that tracing detects the renaming of the `self` variable
541         // too, as tracing::instrument is not going to be able to skip the
542         // `self` argument if it can't find it in the function signature.
543         #[instrument(skip(self))]
bar(&self)544         async fn bar(&self) {
545             info!(val = self.0);
546         }
547     }
548 
549     // A simple subscriber implementation to test the behavior of async-trait
550     // with tokio-rs/tracing. This implementation is not robust against race
551     // conditions, but it's not an issue here as we are only polling on a single
552     // future at a time.
553     #[derive(Debug)]
554     struct SubscriberInner {
555         current_depth: AtomicU64,
556         // We assert that nested functions work. If the fix were to break, we
557         // would see two top-level functions instead of `bar` nested in `foo`.
558         max_depth: AtomicU64,
559         max_span_id: AtomicU64,
560         // Name of the variable / value / depth when the event was recorded.
561         value: Mutex<Option<(&'static str, u64, u64)>>,
562     }
563 
564     #[derive(Debug, Clone)]
565     struct TestSubscriber {
566         inner: Arc<SubscriberInner>,
567     }
568 
569     impl TestSubscriber {
new() -> Self570         fn new() -> Self {
571             TestSubscriber {
572                 inner: Arc::new(SubscriberInner {
573                     current_depth: AtomicU64::new(0),
574                     max_depth: AtomicU64::new(0),
575                     max_span_id: AtomicU64::new(1),
576                     value: Mutex::new(None),
577                 }),
578             }
579         }
580     }
581 
582     struct U64Visitor(Option<(&'static str, u64)>);
583 
584     impl Visit for U64Visitor {
record_debug(&mut self, _field: &Field, _value: &dyn Debug)585         fn record_debug(&mut self, _field: &Field, _value: &dyn Debug) {}
586 
record_u64(&mut self, field: &Field, value: u64)587         fn record_u64(&mut self, field: &Field, value: u64) {
588             self.0 = Some((field.name(), value));
589         }
590     }
591 
592     impl Subscriber for TestSubscriber {
enabled(&self, _metadata: &Metadata) -> bool593         fn enabled(&self, _metadata: &Metadata) -> bool {
594             true
595         }
new_span(&self, _span: &Attributes) -> Id596         fn new_span(&self, _span: &Attributes) -> Id {
597             Id::from_u64(self.inner.max_span_id.fetch_add(1, Ordering::AcqRel))
598         }
record(&self, _span: &Id, _values: &Record)599         fn record(&self, _span: &Id, _values: &Record) {}
record_follows_from(&self, _span: &Id, _follows: &Id)600         fn record_follows_from(&self, _span: &Id, _follows: &Id) {}
event(&self, event: &Event)601         fn event(&self, event: &Event) {
602             let mut visitor = U64Visitor(None);
603             event.record(&mut visitor);
604             if let Some((s, v)) = visitor.0 {
605                 let current_depth = self.inner.current_depth.load(Ordering::Acquire);
606                 *self.inner.value.lock().unwrap() = Some((s, v, current_depth));
607             }
608         }
enter(&self, _span: &Id)609         fn enter(&self, _span: &Id) {
610             let old_depth = self.inner.current_depth.fetch_add(1, Ordering::AcqRel);
611             if old_depth + 1 > self.inner.max_depth.load(Ordering::Acquire) {
612                 self.inner.max_depth.fetch_add(1, Ordering::AcqRel);
613             }
614         }
exit(&self, _span: &Id)615         fn exit(&self, _span: &Id) {
616             self.inner.current_depth.fetch_sub(1, Ordering::AcqRel);
617         }
618     }
619 
620     #[test]
621     #[cfg_attr(miri, ignore)] // https://github.com/matklad/once_cell/pull/185
tracing()622     fn tracing() {
623         // Create the future outside of the subscriber, as no call to tracing
624         // should be made until the future is polled.
625         let mut struct_impl = Impl(0);
626         let fut = struct_impl.foo(5);
627         let subscriber = TestSubscriber::new();
628         subscriber::with_default(subscriber.clone(), || executor::block_on_simple(fut));
629         // Did we enter bar inside of foo?
630         assert_eq!(subscriber.inner.max_depth.load(Ordering::Acquire), 2);
631         // Have we exited all spans?
632         assert_eq!(subscriber.inner.current_depth.load(Ordering::Acquire), 0);
633         // Did we create only two spans? Note: spans start at 1, hence the -1.
634         assert_eq!(subscriber.inner.max_span_id.load(Ordering::Acquire) - 1, 2);
635         // Was the value recorded at the right depth i.e. in the right function?
636         // If so, was it the expected value?
637         assert_eq!(*subscriber.inner.value.lock().unwrap(), Some(("val", 5, 2)));
638     }
639 }
640 
641 // https://github.com/dtolnay/async-trait/issues/46
642 pub mod issue46 {
643     use async_trait::async_trait;
644 
645     macro_rules! implement_commands_workaround {
646         ($tyargs:tt : $ty:tt) => {
647             #[async_trait]
648             pub trait AsyncCommands1: Sized {
649                 async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
650                     self.f(x).await
651                 }
652             }
653         };
654     }
655 
656     implement_commands_workaround!(K: Send);
657 
658     macro_rules! implement_commands {
659         ($tyargs:ident : $ty:ident) => {
660             #[async_trait]
661             pub trait AsyncCommands2: Sized {
662                 async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
663                     self.f(x).await
664                 }
665             }
666         };
667     }
668 
669     implement_commands!(K: Send);
670 }
671 
672 // https://github.com/dtolnay/async-trait/issues/53
673 pub mod issue53 {
674     use async_trait::async_trait;
675 
676     pub struct Unit;
677     pub struct Tuple(u8);
678     pub struct Struct {
679         pub x: u8,
680     }
681 
682     #[async_trait]
683     pub trait Trait {
method()684         async fn method();
685     }
686 
687     #[async_trait]
688     impl Trait for Unit {
method()689         async fn method() {
690             let _ = Self;
691         }
692     }
693 
694     #[async_trait]
695     impl Trait for Tuple {
method()696         async fn method() {
697             let _ = Self(0);
698         }
699     }
700 
701     #[async_trait]
702     impl Trait for Struct {
method()703         async fn method() {
704             let _ = Self { x: 0 };
705         }
706     }
707 
708     #[async_trait]
709     impl Trait for std::marker::PhantomData<Struct> {
method()710         async fn method() {
711             let _ = Self;
712         }
713     }
714 }
715 
716 // https://github.com/dtolnay/async-trait/issues/57
717 #[cfg(async_trait_nightly_testing)]
718 pub mod issue57 {
719     use crate::executor;
720     use async_trait::async_trait;
721 
722     #[async_trait]
723     trait Trait {
const_generic<T: Send, const C: usize>(_: [T; C])724         async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
725     }
726 
727     struct Struct;
728 
729     #[async_trait]
730     impl Trait for Struct {
const_generic<T: Send, const C: usize>(_: [T; C])731         async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
732     }
733 
734     #[test]
test()735     fn test() {
736         let fut = Struct::const_generic([0; 10]);
737         executor::block_on_simple(fut);
738     }
739 }
740 
741 // https://github.com/dtolnay/async-trait/issues/68
742 pub mod issue68 {
743     #[rustversion::since(1.40)] // procedural macros cannot expand to macro definitions in 1.39.
744     #[async_trait::async_trait]
745     pub trait Example {
method(&self)746         async fn method(&self) {
747             macro_rules! t {
748                 () => {{
749                     let _: &Self = self;
750                 }};
751             }
752             t!();
753         }
754     }
755 }
756 
757 // https://github.com/dtolnay/async-trait/issues/73
758 pub mod issue73 {
759     use async_trait::async_trait;
760 
761     #[async_trait]
762     pub trait Example {
763         const ASSOCIATED: &'static str;
764 
associated(&self)765         async fn associated(&self) {
766             println!("Associated:{}", Self::ASSOCIATED);
767         }
768     }
769 }
770 
771 // https://github.com/dtolnay/async-trait/issues/81
772 pub mod issue81 {
773     use async_trait::async_trait;
774 
775     #[async_trait]
776     pub trait Trait {
handle(&self)777         async fn handle(&self);
778     }
779 
780     pub enum Enum {
781         Variant,
782     }
783 
784     #[async_trait]
785     impl Trait for Enum {
handle(&self)786         async fn handle(&self) {
787             let Enum::Variant = self;
788             let Self::Variant = self;
789         }
790     }
791 }
792 
793 // https://github.com/dtolnay/async-trait/issues/83
794 pub mod issue83 {
795     #![allow(clippy::needless_arbitrary_self_type)]
796 
797     use async_trait::async_trait;
798 
799     #[async_trait]
800     pub trait Trait {
f(&self)801         async fn f(&self) {}
g(self: &Self)802         async fn g(self: &Self) {}
803     }
804 }
805 
806 // https://github.com/dtolnay/async-trait/issues/85
807 pub mod issue85 {
808     #![deny(non_snake_case)]
809 
810     use async_trait::async_trait;
811 
812     #[async_trait]
813     pub trait Trait {
814         #[allow(non_snake_case)]
camelCase()815         async fn camelCase();
816     }
817 
818     pub struct Struct;
819 
820     #[async_trait]
821     impl Trait for Struct {
camelCase()822         async fn camelCase() {}
823     }
824 }
825 
826 // https://github.com/dtolnay/async-trait/issues/87
827 pub mod issue87 {
828     use async_trait::async_trait;
829 
830     #[async_trait]
831     pub trait Trait {
f(&self)832         async fn f(&self);
833     }
834 
835     pub enum Tuple {
836         V(),
837     }
838 
839     pub enum Struct {
840         V {},
841     }
842 
843     #[async_trait]
844     impl Trait for Tuple {
f(&self)845         async fn f(&self) {
846             let Tuple::V() = self;
847             let Self::V() = self;
848             let _ = Self::V;
849             let _ = Self::V();
850         }
851     }
852 
853     #[async_trait]
854     impl Trait for Struct {
f(&self)855         async fn f(&self) {
856             let Struct::V {} = self;
857             let Self::V {} = self;
858             let _ = Self::V {};
859         }
860     }
861 }
862 
863 // https://github.com/dtolnay/async-trait/issues/89
864 pub mod issue89 {
865     #![allow(bare_trait_objects)]
866 
867     use async_trait::async_trait;
868 
869     #[async_trait]
870     trait Trait {
f(&self)871         async fn f(&self);
872     }
873 
874     #[async_trait]
875     impl Trait for Send + Sync {
f(&self)876         async fn f(&self) {}
877     }
878 
879     #[async_trait]
880     impl Trait for dyn Fn(i8) + Send + Sync {
f(&self)881         async fn f(&self) {}
882     }
883 
884     #[async_trait]
885     impl Trait for (dyn Fn(u8) + Send + Sync) {
f(&self)886         async fn f(&self) {}
887     }
888 }
889 
890 // https://github.com/dtolnay/async-trait/issues/92
891 pub mod issue92 {
892     use async_trait::async_trait;
893 
894     macro_rules! mac {
895         ($($tt:tt)*) => {
896             $($tt)*
897         };
898     }
899 
900     pub struct Struct<T> {
901         _x: T,
902     }
903 
904     impl<T> Struct<T> {
905         const ASSOCIATED1: &'static str = "1";
associated1()906         async fn associated1() {}
907     }
908 
909     #[async_trait]
910     pub trait Trait
911     where
912         mac!(Self): Send,
913     {
914         const ASSOCIATED2: &'static str;
915         type Associated2;
916 
917         #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)]
associated2(&self)918         async fn associated2(&self) {
919             // trait items
920             mac!(let _: Self::Associated2;);
921             mac!(let _: <Self>::Associated2;);
922             mac!(let _: <Self as Trait>::Associated2;);
923             mac!(Self::ASSOCIATED2;);
924             mac!(<Self>::ASSOCIATED2;);
925             mac!(<Self as Trait>::ASSOCIATED2;);
926             mac!(let _ = Self::associated2(self););
927             mac!(let _ = <Self>::associated2(self););
928             mac!(let _ = <Self as Trait>::associated2(self););
929         }
930     }
931 
932     #[async_trait]
933     impl<T: Send + Sync> Trait for Struct<T>
934     where
935         mac!(Self): Send,
936     {
937         const ASSOCIATED2: &'static str = "2";
938         type Associated2 = ();
939 
940         #[allow(path_statements, clippy::let_underscore_future, clippy::no_effect)]
associated2(&self)941         async fn associated2(&self) {
942             // inherent items
943             mac!(Self::ASSOCIATED1;);
944             mac!(<Self>::ASSOCIATED1;);
945             mac!(let _ = Self::associated1(););
946             mac!(let _ = <Self>::associated1(););
947 
948             // trait items
949             mac!(let _: <Self as Trait>::Associated2;);
950             mac!(Self::ASSOCIATED2;);
951             mac!(<Self>::ASSOCIATED2;);
952             mac!(<Self as Trait>::ASSOCIATED2;);
953             mac!(let _ = Self::associated2(self););
954             mac!(let _ = <Self>::associated2(self););
955             mac!(let _ = <Self as Trait>::associated2(self););
956         }
957     }
958 
959     pub struct Unit;
960 
961     #[async_trait]
962     impl Trait for Unit {
963         const ASSOCIATED2: &'static str = "2";
964         type Associated2 = ();
965 
associated2(&self)966         async fn associated2(&self) {
967             mac!(let Self: Self = *self;);
968         }
969     }
970 }
971 
972 // https://github.com/dtolnay/async-trait/issues/92#issuecomment-683370136
973 pub mod issue92_2 {
974     use async_trait::async_trait;
975 
976     macro_rules! mac {
977         ($($tt:tt)*) => {
978             $($tt)*
979         };
980     }
981 
982     pub trait Trait1 {
func1()983         fn func1();
984     }
985 
986     #[async_trait]
987     pub trait Trait2: Trait1 {
func2()988         async fn func2() {
989             mac!(Self::func1());
990 
991             macro_rules! mac2 {
992                 ($($tt:tt)*) => {
993                     Self::func1();
994                 };
995             }
996             mac2!();
997         }
998     }
999 }
1000 
1001 // https://github.com/dtolnay/async-trait/issues/104
1002 pub mod issue104 {
1003     use async_trait::async_trait;
1004 
1005     #[async_trait]
1006     trait T1 {
id(&self) -> i321007         async fn id(&self) -> i32;
1008     }
1009 
1010     macro_rules! impl_t1 {
1011         ($ty:ty, $id:expr) => {
1012             #[async_trait]
1013             impl T1 for $ty {
1014                 async fn id(&self) -> i32 {
1015                     $id
1016                 }
1017             }
1018         };
1019     }
1020 
1021     struct Foo;
1022 
1023     impl_t1!(Foo, 1);
1024 }
1025 
1026 // https://github.com/dtolnay/async-trait/issues/106
1027 pub mod issue106 {
1028     use async_trait::async_trait;
1029     use std::future::Future;
1030 
1031     #[async_trait]
1032     pub trait ProcessPool: Send + Sync {
1033         type ThreadPool;
1034 
spawn<F, Fut, T>(&self, work: F) -> T where F: FnOnce(&Self::ThreadPool) -> Fut + Send, Fut: Future<Output = T> + 'static1035         async fn spawn<F, Fut, T>(&self, work: F) -> T
1036         where
1037             F: FnOnce(&Self::ThreadPool) -> Fut + Send,
1038             Fut: Future<Output = T> + 'static;
1039     }
1040 
1041     #[async_trait]
1042     impl<P> ProcessPool for &P
1043     where
1044         P: ?Sized + ProcessPool,
1045     {
1046         type ThreadPool = P::ThreadPool;
1047 
spawn<F, Fut, T>(&self, work: F) -> T where F: FnOnce(&Self::ThreadPool) -> Fut + Send, Fut: Future<Output = T> + 'static,1048         async fn spawn<F, Fut, T>(&self, work: F) -> T
1049         where
1050             F: FnOnce(&Self::ThreadPool) -> Fut + Send,
1051             Fut: Future<Output = T> + 'static,
1052         {
1053             (**self).spawn(work).await
1054         }
1055     }
1056 }
1057 
1058 // https://github.com/dtolnay/async-trait/issues/110
1059 pub mod issue110 {
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     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 
1365 // https://github.com/dtolnay/async-trait/issues/169
1366 #[deny(where_clauses_object_safety)]
1367 pub mod issue169 {
1368     use async_trait::async_trait;
1369 
1370     #[async_trait]
1371     pub trait Trait: ::core::marker::Sync {
f(&self)1372         async fn f(&self) {}
1373     }
1374 
test(_t: &dyn Trait)1375     pub fn test(_t: &dyn Trait) {}
1376 }
1377 
1378 // https://github.com/dtolnay/async-trait/issues/177
1379 pub mod issue177 {
1380     use async_trait::async_trait;
1381 
1382     #[async_trait]
1383     pub trait Trait {
foo(&self, _callback: impl FnMut(&str) + Send)1384         async fn foo(&self, _callback: impl FnMut(&str) + Send) {}
1385     }
1386 
1387     pub struct Struct;
1388 
1389     #[async_trait]
1390     impl Trait for Struct {
foo(&self, _callback: impl FnMut(&str) + Send)1391         async fn foo(&self, _callback: impl FnMut(&str) + Send) {}
1392     }
1393 }
1394 
1395 // https://github.com/dtolnay/async-trait/issues/183
1396 pub mod issue183 {
1397     #![deny(clippy::shadow_same)]
1398 
1399     use async_trait::async_trait;
1400 
1401     #[async_trait]
1402     trait Foo {
foo(_n: i32)1403         async fn foo(_n: i32) {}
1404     }
1405 }
1406 
1407 // https://github.com/dtolnay/async-trait/issues/199
1408 pub mod issue199 {
1409     use async_trait::async_trait;
1410     use std::cell::Cell;
1411 
1412     struct IncrementOnDrop<'a>(&'a Cell<usize>);
1413 
1414     impl<'a> Drop for IncrementOnDrop<'a> {
drop(&mut self)1415         fn drop(&mut self) {
1416             self.0.set(self.0.get() + 1);
1417         }
1418     }
1419 
1420     #[async_trait(?Send)]
1421     trait Trait {
f(counter: &Cell<usize>, arg: IncrementOnDrop<'_>)1422         async fn f(counter: &Cell<usize>, arg: IncrementOnDrop<'_>);
1423     }
1424 
1425     struct Struct;
1426 
1427     #[async_trait(?Send)]
1428     impl Trait for Struct {
f(counter: &Cell<usize>, _: IncrementOnDrop<'_>)1429         async fn f(counter: &Cell<usize>, _: IncrementOnDrop<'_>) {
1430             assert_eq!(counter.get(), 0); // second arg not dropped yet
1431         }
1432     }
1433 
1434     #[test]
test()1435     fn test() {
1436         let counter = Cell::new(0);
1437         let future = Struct::f(&counter, IncrementOnDrop(&counter));
1438         assert_eq!(counter.get(), 0);
1439         drop(future);
1440         assert_eq!(counter.get(), 1);
1441     }
1442 }
1443 
1444 // https://github.com/dtolnay/async-trait/issues/204
1445 pub mod issue204 {
1446     use async_trait::async_trait;
1447 
1448     #[async_trait]
1449     pub trait Trait {
f(arg: &impl Trait)1450         async fn f(arg: &impl Trait);
g(arg: *const impl Trait)1451         async fn g(arg: *const impl Trait);
1452     }
1453 }
1454 
1455 // https://github.com/dtolnay/async-trait/issues/210
1456 pub mod issue210 {
1457     use async_trait::async_trait;
1458     use std::sync::Arc;
1459 
1460     #[async_trait]
1461     pub trait Trait {
f(self: Arc<Self>)1462         async fn f(self: Arc<Self>) {}
1463     }
1464 }
1465 
1466 // https://github.com/dtolnay/async-trait/issues/226
1467 pub mod issue226 {
1468     use async_trait::async_trait;
1469 
1470     #[async_trait]
1471     pub trait Trait {
cfg_param(&self, param: u8)1472         async fn cfg_param(&self, param: u8);
cfg_param_wildcard(&self, _: u8)1473         async fn cfg_param_wildcard(&self, _: u8);
cfg_param_tuple(&self, (left, right): (u8, u8))1474         async fn cfg_param_tuple(&self, (left, right): (u8, u8));
1475     }
1476 
1477     struct Struct;
1478 
1479     #[async_trait]
1480     impl Trait for Struct {
cfg_param(&self, #[cfg(any())] param: u8, #[cfg(all())] _unused: u8)1481         async fn cfg_param(&self, #[cfg(any())] param: u8, #[cfg(all())] _unused: u8) {}
1482 
cfg_param_wildcard(&self, #[cfg(any())] _: u8, #[cfg(all())] _: u8)1483         async fn cfg_param_wildcard(&self, #[cfg(any())] _: u8, #[cfg(all())] _: u8) {}
1484 
cfg_param_tuple( &self, #[cfg(any())] (left, right): (u8, u8), #[cfg(all())] (_left, _right): (u8, u8), )1485         async fn cfg_param_tuple(
1486             &self,
1487             #[cfg(any())] (left, right): (u8, u8),
1488             #[cfg(all())] (_left, _right): (u8, u8),
1489         ) {
1490         }
1491     }
1492 }
1493 
1494 // https://github.com/dtolnay/async-trait/issues/232
1495 pub mod issue232 {
1496     use async_trait::async_trait;
1497 
1498     #[async_trait]
1499     pub trait Generic<T> {
take_ref(&self, thing: &T)1500         async fn take_ref(&self, thing: &T);
1501     }
1502 
1503     pub struct One;
1504 
1505     #[async_trait]
1506     impl<T> Generic<T> for One {
take_ref(&self, _: &T)1507         async fn take_ref(&self, _: &T) {}
1508     }
1509 
1510     pub struct Two;
1511 
1512     #[async_trait]
1513     impl<T: Sync> Generic<(T, T)> for Two {
take_ref(&self, (a, b): &(T, T))1514         async fn take_ref(&self, (a, b): &(T, T)) {
1515             let _ = a;
1516             let _ = b;
1517         }
1518     }
1519 
1520     pub struct Three;
1521 
1522     #[async_trait]
1523     impl<T> Generic<(T, T, T)> for Three {
take_ref(&self, (_a, _b, _c): &(T, T, T))1524         async fn take_ref(&self, (_a, _b, _c): &(T, T, T)) {}
1525     }
1526 }
1527 
1528 // https://github.com/dtolnay/async-trait/issues/234
1529 pub mod issue234 {
1530     use async_trait::async_trait;
1531 
1532     pub struct Droppable;
1533 
1534     impl Drop for Droppable {
drop(&mut self)1535         fn drop(&mut self) {}
1536     }
1537 
1538     pub struct Tuple<T, U>(T, U);
1539 
1540     #[async_trait]
1541     pub trait Trait {
f(arg: Tuple<Droppable, i32>)1542         async fn f(arg: Tuple<Droppable, i32>);
1543     }
1544 
1545     pub struct UnderscorePattern;
1546 
1547     #[async_trait]
1548     impl Trait for UnderscorePattern {
f(Tuple(_, _int): Tuple<Droppable, i32>)1549         async fn f(Tuple(_, _int): Tuple<Droppable, i32>) {}
1550     }
1551 
1552     pub struct DotDotPattern;
1553 
1554     #[async_trait]
1555     impl Trait for DotDotPattern {
1556         async fn f(Tuple { 1: _int, .. }: Tuple<Droppable, i32>) {}
1557     }
1558 }
1559 
1560 // https://github.com/dtolnay/async-trait/issues/236
1561 pub mod issue236 {
1562     #![deny(clippy::async_yields_async)]
1563     #![allow(clippy::manual_async_fn)]
1564 
1565     use async_trait::async_trait;
1566     use std::future::{self, Future, Ready};
1567 
1568     // Does not trigger the lint.
async_fn() -> Ready<()>1569     pub async fn async_fn() -> Ready<()> {
1570         future::ready(())
1571     }
1572 
1573     #[allow(clippy::async_yields_async)]
impl_future_fn() -> impl Future<Output = Ready<()>>1574     pub fn impl_future_fn() -> impl Future<Output = Ready<()>> {
1575         async { future::ready(()) }
1576     }
1577 
1578     // The async_trait attribute turns the former into the latter, so we make it
1579     // put its own allow(async_yeilds_async) to remain consistent with async fn.
1580     #[async_trait]
1581     pub trait Trait {
f() -> Ready<()>1582         async fn f() -> Ready<()> {
1583             future::ready(())
1584         }
1585     }
1586 }
1587