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