blob: 5fc238ba456fd57b764f0782cb8fff06d81e4057 [file] [log] [blame]
Haibo Huang7ff84c32020-11-24 20:53:12 -08001#![cfg_attr(
2 async_trait_nightly_testing,
3 feature(min_specialization, min_const_generics)
4)]
Andrew Walbrand1b91c72020-08-11 17:12:08 +01005
6use async_trait::async_trait;
7
8pub mod executor;
9
10// Dummy module to check that the expansion refer to rust's core crate
11mod core {}
12
13#[async_trait]
14trait Trait {
15 type Assoc;
16
17 async fn selfvalue(self)
18 where
19 Self: Sized,
20 {
21 }
22
23 async fn selfref(&self) {}
24
25 async fn selfmut(&mut self) {}
26
27 async fn required() -> Self::Assoc;
28
29 async fn elided_lifetime(_x: &str) {}
30
31 async fn explicit_lifetime<'a>(_x: &'a str) {}
32
33 async fn generic_type_param<T: Send>(x: Box<T>) -> T {
34 *x
35 }
36
37 async fn calls(&self) {
38 self.selfref().await;
39 Self::elided_lifetime("").await;
40 <Self>::elided_lifetime("").await;
41 }
42
43 async fn calls_mut(&mut self) {
44 self.selfmut().await;
45 }
46}
47
48struct Struct;
49
50#[async_trait]
51impl Trait for Struct {
52 type Assoc = ();
53
54 async fn selfvalue(self) {}
55
56 async fn selfref(&self) {}
57
58 async fn selfmut(&mut self) {}
59
60 async fn required() -> Self::Assoc {}
61
62 async fn elided_lifetime(_x: &str) {}
63
64 async fn explicit_lifetime<'a>(_x: &'a str) {}
65
66 async fn generic_type_param<T: Send>(x: Box<T>) -> T {
67 *x
68 }
69
70 async fn calls(&self) {
71 self.selfref().await;
72 Self::elided_lifetime("").await;
73 <Self>::elided_lifetime("").await;
74 }
75
76 async fn calls_mut(&mut self) {
77 self.selfmut().await;
78 }
79}
80
81pub async fn test() {
82 let mut s = Struct;
83 s.selfref().await;
84 s.selfmut().await;
85 s.selfvalue().await;
86
87 Struct::required().await;
88 Struct::elided_lifetime("").await;
89 Struct::explicit_lifetime("").await;
90 Struct::generic_type_param(Box::new("")).await;
91
92 let mut s = Struct;
93 s.calls().await;
94 s.calls_mut().await;
95}
96
97pub async fn test_object_safe_without_default() {
98 #[async_trait]
99 trait ObjectSafe {
100 async fn f(&self);
101 }
102
103 #[async_trait]
104 impl ObjectSafe for Struct {
105 async fn f(&self) {}
106 }
107
108 let object = &Struct as &dyn ObjectSafe;
109 object.f().await;
110}
111
112pub async fn test_object_safe_with_default() {
113 #[async_trait]
114 trait ObjectSafe: Sync {
115 async fn f(&self) {}
116 }
117
118 #[async_trait]
119 impl ObjectSafe for Struct {
120 async fn f(&self) {}
121 }
122
123 let object = &Struct as &dyn ObjectSafe;
124 object.f().await;
125}
126
127pub async fn test_object_no_send() {
128 #[async_trait(?Send)]
129 trait ObjectSafe: Sync {
130 async fn f(&self) {}
131 }
132
133 #[async_trait(?Send)]
134 impl ObjectSafe for Struct {
135 async fn f(&self) {}
136 }
137
138 let object = &Struct as &dyn ObjectSafe;
139 object.f().await;
140}
141
142#[async_trait]
143pub unsafe trait UnsafeTrait {}
144
145#[async_trait]
146unsafe impl UnsafeTrait for () {}
147
148#[async_trait]
149pub(crate) unsafe trait UnsafeTraitPubCrate {}
150
151#[async_trait]
152unsafe trait UnsafeTraitPrivate {}
153
154// https://github.com/dtolnay/async-trait/issues/1
155pub mod issue1 {
156 use async_trait::async_trait;
157
158 #[async_trait]
159 trait Issue1 {
160 async fn f<U>(&self);
161 }
162
163 #[async_trait]
164 impl<T: Sync> Issue1 for Vec<T> {
165 async fn f<U>(&self) {}
166 }
167}
168
169// https://github.com/dtolnay/async-trait/issues/2
170pub mod issue2 {
171 use async_trait::async_trait;
172 use std::future::Future;
173
174 #[async_trait]
175 pub trait Issue2: Future {
176 async fn flatten(self) -> <Self::Output as Future>::Output
177 where
178 Self::Output: Future + Send,
179 Self: Sized,
180 {
181 let nested_future = self.await;
182 nested_future.await
183 }
184 }
185}
186
187// https://github.com/dtolnay/async-trait/issues/9
188pub mod issue9 {
189 use async_trait::async_trait;
190
191 #[async_trait]
192 pub trait Issue9: Sized + Send {
193 async fn f(_x: Self) {}
194 }
195}
196
197// https://github.com/dtolnay/async-trait/issues/11
198pub mod issue11 {
199 use async_trait::async_trait;
200 use std::sync::Arc;
201
202 #[async_trait]
203 trait Issue11 {
204 async fn example(self: Arc<Self>);
205 }
206
207 struct Struct;
208
209 #[async_trait]
210 impl Issue11 for Struct {
211 async fn example(self: Arc<Self>) {}
212 }
213}
214
215// https://github.com/dtolnay/async-trait/issues/15
216pub mod issue15 {
217 use async_trait::async_trait;
218 use std::marker::PhantomData;
219
220 trait Trait {}
221
222 #[async_trait]
223 trait Issue15 {
224 async fn myfn(&self, _: PhantomData<dyn Trait + Send>) {}
225 }
226}
227
228// https://github.com/dtolnay/async-trait/issues/17
229pub mod issue17 {
230 use async_trait::async_trait;
231
232 #[async_trait]
233 trait Issue17 {
234 async fn f(&self);
235 }
236
237 struct Struct {
238 string: String,
239 }
240
241 #[async_trait]
242 impl Issue17 for Struct {
243 async fn f(&self) {
244 println!("{}", self.string);
245 }
246 }
247}
248
249// https://github.com/dtolnay/async-trait/issues/23
250pub mod issue23 {
251 use async_trait::async_trait;
252
253 #[async_trait]
254 pub trait Issue23 {
255 async fn f(self);
256
257 async fn g(mut self)
258 where
259 Self: Sized,
260 {
261 do_something(&mut self);
262 }
263 }
264
265 struct S {}
266
267 #[async_trait]
268 impl Issue23 for S {
269 async fn f(mut self) {
270 do_something(&mut self);
271 }
272 }
273
274 fn do_something<T>(_: &mut T) {}
275}
276
277// https://github.com/dtolnay/async-trait/issues/25
278#[cfg(async_trait_nightly_testing)]
279pub mod issue25 {
280 use crate::executor;
281 use async_trait::async_trait;
282 use std::fmt::{Display, Write};
283
284 #[async_trait]
285 trait AsyncToString {
286 async fn async_to_string(&self) -> String;
287 }
288
289 #[async_trait]
290 impl AsyncToString for String {
291 async fn async_to_string(&self) -> String {
292 "special".to_owned()
293 }
294 }
295
296 macro_rules! hide_from_stable_parser {
297 ($($tt:tt)*) => {
298 $($tt)*
299 };
300 }
301
302 hide_from_stable_parser! {
303 #[async_trait]
304 impl<T: ?Sized + Display + Sync> AsyncToString for T {
305 default async fn async_to_string(&self) -> String {
306 let mut buf = String::new();
307 buf.write_fmt(format_args!("{}", self)).unwrap();
308 buf
309 }
310 }
311 }
312
313 #[test]
314 fn test() {
315 let fut = true.async_to_string();
316 assert_eq!(executor::block_on_simple(fut), "true");
317
318 let string = String::new();
319 let fut = string.async_to_string();
320 assert_eq!(executor::block_on_simple(fut), "special");
321 }
322}
323
324// https://github.com/dtolnay/async-trait/issues/28
325pub mod issue28 {
326 use async_trait::async_trait;
327
328 struct Str<'a>(&'a str);
329
330 #[async_trait]
331 trait Trait1<'a> {
332 async fn f(x: Str<'a>) -> &'a str;
333 async fn g(x: Str<'a>) -> &'a str {
334 x.0
335 }
336 }
337
338 #[async_trait]
339 impl<'a> Trait1<'a> for str {
340 async fn f(x: Str<'a>) -> &'a str {
341 x.0
342 }
343 }
344
345 #[async_trait]
346 trait Trait2 {
347 async fn f();
348 }
349
350 #[async_trait]
351 impl<'a> Trait2 for &'a () {
352 async fn f() {}
353 }
354
355 #[async_trait]
356 trait Trait3<'a, 'b> {
357 async fn f(_: &'a &'b ()); // chain 'a and 'b
358 async fn g(_: &'b ()); // chain 'b only
359 async fn h(); // do not chain
360 }
361}
362
363// https://github.com/dtolnay/async-trait/issues/31
364pub mod issue31 {
365 use async_trait::async_trait;
366
367 pub struct Struct<'a> {
368 pub name: &'a str,
369 }
370
371 #[async_trait]
372 pub trait Trait<'a> {
373 async fn hello(thing: Struct<'a>) -> String;
374 async fn hello_twice(one: Struct<'a>, two: Struct<'a>) -> String {
375 let str1 = Self::hello(one).await;
376 let str2 = Self::hello(two).await;
377 str1 + &str2
378 }
379 }
380}
381
382// https://github.com/dtolnay/async-trait/issues/42
383pub mod issue42 {
384 use async_trait::async_trait;
385
386 #[async_trait]
387 pub trait Context: Sized {
388 async fn from_parts() -> Self;
389 }
390
391 pub struct TokenContext;
392
393 #[async_trait]
394 impl Context for TokenContext {
395 async fn from_parts() -> TokenContext {
396 TokenContext
397 }
398 }
399}
400
401// https://github.com/dtolnay/async-trait/issues/44
402pub mod issue44 {
403 use async_trait::async_trait;
404
405 #[async_trait]
406 pub trait StaticWithWhereSelf
407 where
408 Box<Self>: Sized,
409 Self: Sized + Send,
410 {
411 async fn get_one() -> u8 {
412 1
413 }
414 }
415
416 pub struct Struct;
417
418 #[async_trait]
419 impl StaticWithWhereSelf for Struct {}
420}
421
422// https://github.com/dtolnay/async-trait/issues/45
423pub mod issue45 {
424 use crate::executor;
425 use async_trait::async_trait;
426 use std::fmt::Debug;
427 use std::sync::atomic::{AtomicU64, Ordering};
428 use std::sync::{Arc, Mutex};
429 use tracing::event::Event;
430 use tracing::field::{Field, Visit};
431 use tracing::span::{Attributes, Id, Record};
432 use tracing::{info, instrument, subscriber, Metadata, Subscriber};
433
434 #[async_trait]
435 pub trait Parent {
436 async fn foo(&mut self, v: usize);
437 }
438
439 #[async_trait]
440 pub trait Child {
441 async fn bar(&self);
442 }
443
444 #[derive(Debug)]
445 struct Impl(usize);
446
447 #[async_trait]
448 impl Parent for Impl {
449 #[instrument]
450 async fn foo(&mut self, v: usize) {
451 self.0 = v;
452 self.bar().await;
453 }
454 }
455
456 #[async_trait]
457 impl Child for Impl {
458 // Let's check that tracing detects the renaming of the `self` variable
459 // too, as tracing::instrument is not going to be able to skip the
460 // `self` argument if it can't find it in the function signature.
461 #[instrument(skip(self))]
462 async fn bar(&self) {
463 info!(val = self.0);
464 }
465 }
466
467 // A simple subscriber implementation to test the behavior of async-trait
468 // with tokio-rs/tracing. This implementation is not robust against race
469 // conditions, but it's not an issue here as we are only polling on a single
470 // future at a time.
471 #[derive(Debug)]
472 struct SubscriberInner {
473 current_depth: AtomicU64,
474 // We assert that nested functions work. If the fix were to break, we
475 // would see two top-level functions instead of `bar` nested in `foo`.
476 max_depth: AtomicU64,
477 max_span_id: AtomicU64,
478 // Name of the variable / value / depth when the event was recorded.
479 value: Mutex<Option<(&'static str, u64, u64)>>,
480 }
481
482 #[derive(Debug, Clone)]
483 struct TestSubscriber {
484 inner: Arc<SubscriberInner>,
485 }
486
487 impl TestSubscriber {
488 fn new() -> Self {
489 TestSubscriber {
490 inner: Arc::new(SubscriberInner {
491 current_depth: AtomicU64::new(0),
492 max_depth: AtomicU64::new(0),
493 max_span_id: AtomicU64::new(1),
494 value: Mutex::new(None),
495 }),
496 }
497 }
498 }
499
500 struct U64Visitor(Option<(&'static str, u64)>);
501
502 impl Visit for U64Visitor {
503 fn record_debug(&mut self, _field: &Field, _value: &dyn Debug) {}
504
505 fn record_u64(&mut self, field: &Field, value: u64) {
506 self.0 = Some((field.name(), value));
507 }
508 }
509
510 impl Subscriber for TestSubscriber {
511 fn enabled(&self, _metadata: &Metadata) -> bool {
512 true
513 }
514 fn new_span(&self, _span: &Attributes) -> Id {
515 Id::from_u64(self.inner.max_span_id.fetch_add(1, Ordering::AcqRel))
516 }
517 fn record(&self, _span: &Id, _values: &Record) {}
518 fn record_follows_from(&self, _span: &Id, _follows: &Id) {}
519 fn event(&self, event: &Event) {
520 let mut visitor = U64Visitor(None);
521 event.record(&mut visitor);
522 if let Some((s, v)) = visitor.0 {
523 let current_depth = self.inner.current_depth.load(Ordering::Acquire);
524 *self.inner.value.lock().unwrap() = Some((s, v, current_depth));
525 }
526 }
527 fn enter(&self, _span: &Id) {
528 let old_depth = self.inner.current_depth.fetch_add(1, Ordering::AcqRel);
529 if old_depth + 1 > self.inner.max_depth.load(Ordering::Acquire) {
530 self.inner.max_depth.fetch_add(1, Ordering::AcqRel);
531 }
532 }
533 fn exit(&self, _span: &Id) {
534 self.inner.current_depth.fetch_sub(1, Ordering::AcqRel);
535 }
536 }
537
538 #[test]
539 fn tracing() {
540 // Create the future outside of the subscriber, as no call to tracing
541 // should be made until the future is polled.
542 let mut struct_impl = Impl(0);
543 let fut = struct_impl.foo(5);
544 let subscriber = TestSubscriber::new();
545 subscriber::with_default(subscriber.clone(), || executor::block_on_simple(fut));
546 // Did we enter bar inside of foo?
547 assert_eq!(subscriber.inner.max_depth.load(Ordering::Acquire), 2);
548 // Have we exited all spans?
549 assert_eq!(subscriber.inner.current_depth.load(Ordering::Acquire), 0);
550 // Did we create only two spans? Note: spans start at 1, hence the -1.
551 assert_eq!(subscriber.inner.max_span_id.load(Ordering::Acquire) - 1, 2);
552 // Was the value recorded at the right depth i.e. in the right function?
553 // If so, was it the expected value?
554 assert_eq!(*subscriber.inner.value.lock().unwrap(), Some(("val", 5, 2)));
555 }
556}
557
558// https://github.com/dtolnay/async-trait/issues/46
559pub mod issue46 {
560 use async_trait::async_trait;
561
562 macro_rules! implement_commands_workaround {
563 ($tyargs:tt : $ty:tt) => {
564 #[async_trait]
565 pub trait AsyncCommands1: Sized {
566 async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
567 self.f(x).await
568 }
569 }
570 };
571 }
572
573 implement_commands_workaround!(K: Send);
574
575 macro_rules! implement_commands {
576 ($tyargs:ident : $ty:ident) => {
577 #[async_trait]
578 pub trait AsyncCommands2: Sized {
579 async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
580 self.f(x).await
581 }
582 }
583 };
584 }
585
586 implement_commands!(K: Send);
587}
588
589// https://github.com/dtolnay/async-trait/issues/53
590pub mod issue53 {
591 use async_trait::async_trait;
592
593 pub struct Unit;
594 pub struct Tuple(u8);
595 pub struct Struct {
596 pub x: u8,
597 }
598
599 #[async_trait]
600 pub trait Trait {
601 async fn method();
602 }
603
604 #[async_trait]
605 impl Trait for Unit {
606 async fn method() {
607 let _ = Self;
608 }
609 }
610
611 #[async_trait]
612 impl Trait for Tuple {
613 async fn method() {
614 let _ = Self(0);
615 }
616 }
617
618 #[async_trait]
619 impl Trait for Struct {
620 async fn method() {
621 let _ = Self { x: 0 };
622 }
623 }
624
625 #[async_trait]
626 impl Trait for std::marker::PhantomData<Struct> {
627 async fn method() {
628 let _ = Self;
629 }
630 }
631}
632
633// https://github.com/dtolnay/async-trait/issues/57
634#[cfg(async_trait_nightly_testing)]
635pub mod issue57 {
636 use crate::executor;
637 use async_trait::async_trait;
638
639 #[async_trait]
640 trait Trait {
641 async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
642 }
643
644 struct Struct;
645
646 #[async_trait]
647 impl Trait for Struct {
648 async fn const_generic<T: Send, const C: usize>(_: [T; C]) {}
649 }
650
651 #[test]
652 fn test() {
653 let fut = Struct::const_generic([0; 10]);
654 executor::block_on_simple(fut);
655 }
656}
657
658// https://github.com/dtolnay/async-trait/issues/68
659pub mod issue68 {
660 #[rustversion::since(1.40)] // procedural macros cannot expand to macro definitions in 1.39.
661 #[async_trait::async_trait]
662 pub trait Example {
663 async fn method(&self) {
664 macro_rules! t {
665 () => {{
666 let _: &Self = self;
667 }};
668 }
669 t!();
670 }
671 }
672}
673
674// https://github.com/dtolnay/async-trait/issues/73
675pub mod issue73 {
676 use async_trait::async_trait;
677
678 #[async_trait]
679 pub trait Example {
680 const ASSOCIATED: &'static str;
681
682 async fn associated(&self) {
683 println!("Associated:{}", Self::ASSOCIATED);
684 }
685 }
686}
687
688// https://github.com/dtolnay/async-trait/issues/81
689pub mod issue81 {
690 use async_trait::async_trait;
691
692 #[async_trait]
693 pub trait Trait {
694 async fn handle(&self);
695 }
696
697 pub enum Enum {
698 Variant,
699 }
700
701 #[async_trait]
702 impl Trait for Enum {
703 async fn handle(&self) {
704 let Enum::Variant = self;
705 let Self::Variant = self;
706 }
707 }
708}
709
710// https://github.com/dtolnay/async-trait/issues/83
711pub mod issue83 {
Haibo Huangd8abf3d2020-08-17 15:39:53 -0700712 #![allow(clippy::needless_arbitrary_self_type)]
713
Andrew Walbrand1b91c72020-08-11 17:12:08 +0100714 use async_trait::async_trait;
715
716 #[async_trait]
717 pub trait Trait {
718 async fn f(&self) {}
719 async fn g(self: &Self) {}
720 }
721}
722
723// https://github.com/dtolnay/async-trait/issues/85
724pub mod issue85 {
725 #![deny(non_snake_case)]
726
727 use async_trait::async_trait;
728
729 #[async_trait]
730 pub trait Trait {
731 #[allow(non_snake_case)]
732 async fn camelCase();
733 }
734
735 pub struct Struct;
736
737 #[async_trait]
738 impl Trait for Struct {
739 async fn camelCase() {}
740 }
741}
742
743// https://github.com/dtolnay/async-trait/issues/87
744pub mod issue87 {
745 use async_trait::async_trait;
746
747 #[async_trait]
748 pub trait Trait {
749 async fn f(&self);
750 }
751
752 pub enum Tuple {
753 V(),
754 }
755
756 pub enum Struct {
757 V {},
758 }
759
760 #[async_trait]
761 impl Trait for Tuple {
762 async fn f(&self) {
763 let Tuple::V() = self;
764 let Self::V() = self;
765 let _ = Self::V;
766 let _ = Self::V();
767 }
768 }
769
770 #[async_trait]
771 impl Trait for Struct {
772 async fn f(&self) {
773 let Struct::V {} = self;
774 let Self::V {} = self;
775 let _ = Self::V {};
776 }
777 }
778}
779
780// https://github.com/dtolnay/async-trait/issues/89
781pub mod issue89 {
782 #![allow(bare_trait_objects)]
783
784 use async_trait::async_trait;
785
786 #[async_trait]
787 trait Trait {
788 async fn f(&self);
789 }
790
791 #[async_trait]
792 impl Trait for Send + Sync {
793 async fn f(&self) {}
794 }
795
796 #[async_trait]
797 impl Trait for dyn Fn(i8) + Send + Sync {
798 async fn f(&self) {}
799 }
800
801 #[async_trait]
802 impl Trait for (dyn Fn(u8) + Send + Sync) {
803 async fn f(&self) {}
804 }
805}
806
807// https://github.com/dtolnay/async-trait/issues/92
808pub mod issue92 {
809 use async_trait::async_trait;
810
811 macro_rules! mac {
812 ($($tt:tt)*) => {
813 $($tt)*
814 };
815 }
816
817 pub struct Struct<T> {
818 _x: T,
819 }
820
821 impl<T> Struct<T> {
822 const ASSOCIATED1: &'static str = "1";
823 async fn associated1() {}
824 }
825
826 #[async_trait]
827 pub trait Trait
828 where
829 mac!(Self): Send,
830 {
831 const ASSOCIATED2: &'static str;
832 type Associated2;
833
834 #[allow(path_statements, clippy::no_effect)]
835 async fn associated2(&self) {
836 // trait items
837 mac!(let _: Self::Associated2;);
838 mac!(let _: <Self>::Associated2;);
839 mac!(let _: <Self as Trait>::Associated2;);
840 mac!(Self::ASSOCIATED2;);
841 mac!(<Self>::ASSOCIATED2;);
842 mac!(<Self as Trait>::ASSOCIATED2;);
843 mac!(let _ = Self::associated2(self););
844 mac!(let _ = <Self>::associated2(self););
845 mac!(let _ = <Self as Trait>::associated2(self););
846 }
847 }
848
849 #[async_trait]
850 impl<T: Send + Sync> Trait for Struct<T>
851 where
852 mac!(Self): Send,
853 {
854 const ASSOCIATED2: &'static str = "2";
855 type Associated2 = ();
856
857 #[allow(path_statements, clippy::no_effect)]
858 async fn associated2(&self) {
859 // inherent items
860 mac!(Self::ASSOCIATED1;);
861 mac!(<Self>::ASSOCIATED1;);
862 mac!(let _ = Self::associated1(););
863 mac!(let _ = <Self>::associated1(););
864
865 // trait items
866 mac!(let _: <Self as Trait>::Associated2;);
867 mac!(Self::ASSOCIATED2;);
868 mac!(<Self>::ASSOCIATED2;);
869 mac!(<Self as Trait>::ASSOCIATED2;);
870 mac!(let _ = Self::associated2(self););
871 mac!(let _ = <Self>::associated2(self););
872 mac!(let _ = <Self as Trait>::associated2(self););
873 }
874 }
875
876 pub struct Unit;
877
878 #[async_trait]
879 impl Trait for Unit {
880 const ASSOCIATED2: &'static str = "2";
881 type Associated2 = ();
882
883 async fn associated2(&self) {
884 mac!(let Self: Self = *self;);
885 }
886 }
887}
888
Haibo Huang62e9b292020-09-01 20:28:34 -0700889// https://github.com/dtolnay/async-trait/issues/92#issuecomment-683370136
890pub mod issue92_2 {
891 use async_trait::async_trait;
892
893 macro_rules! mac {
894 ($($tt:tt)*) => {
895 $($tt)*
896 };
897 }
898
899 pub trait Trait1 {
900 fn func1();
901 }
902
903 #[async_trait]
904 pub trait Trait2: Trait1 {
905 async fn func2() {
906 mac!(Self::func1());
907
908 macro_rules! mac2 {
909 ($($tt:tt)*) => {
910 Self::func1();
911 };
912 }
913 mac2!();
914 }
915 }
916}
917
Andrew Walbrand1b91c72020-08-11 17:12:08 +0100918// https://github.com/dtolnay/async-trait/issues/104
Haibo Huang62e9b292020-09-01 20:28:34 -0700919pub mod issue104 {
Andrew Walbrand1b91c72020-08-11 17:12:08 +0100920 use async_trait::async_trait;
921
922 #[async_trait]
923 trait T1 {
924 async fn id(&self) -> i32;
925 }
926
927 macro_rules! impl_t1 {
928 ($ty:ty, $id:expr) => {
929 #[async_trait]
930 impl T1 for $ty {
931 async fn id(&self) -> i32 {
932 $id
933 }
934 }
935 };
936 }
937
938 struct Foo;
939
940 impl_t1!(Foo, 1);
941}
942
943// https://github.com/dtolnay/async-trait/issues/106
Haibo Huang62e9b292020-09-01 20:28:34 -0700944pub mod issue106 {
Andrew Walbrand1b91c72020-08-11 17:12:08 +0100945 use async_trait::async_trait;
946 use std::future::Future;
947
948 #[async_trait]
949 pub trait ProcessPool: Send + Sync {
950 type ThreadPool;
951
952 async fn spawn<F, Fut, T>(&self, work: F) -> T
953 where
954 F: FnOnce(&Self::ThreadPool) -> Fut + Send,
955 Fut: Future<Output = T> + 'static;
956 }
957
958 #[async_trait]
959 impl<P: ?Sized> ProcessPool for &P
960 where
961 P: ProcessPool,
962 {
963 type ThreadPool = P::ThreadPool;
964
965 async fn spawn<F, Fut, T>(&self, work: F) -> T
966 where
967 F: FnOnce(&Self::ThreadPool) -> Fut + Send,
968 Fut: Future<Output = T> + 'static,
969 {
970 (**self).spawn(work).await
971 }
972 }
973}
974
975// https://github.com/dtolnay/async-trait/issues/110
Haibo Huang62e9b292020-09-01 20:28:34 -0700976pub mod issue110 {
Andrew Walbrand1b91c72020-08-11 17:12:08 +0100977 #![deny(clippy::all)]
978
979 use async_trait::async_trait;
980 use std::marker::PhantomData;
981
982 #[async_trait]
983 pub trait Loader {
984 async fn load(&self, key: &str);
985 }
986
987 pub struct AwsEc2MetadataLoader<'a> {
988 marker: PhantomData<&'a ()>,
989 }
990
991 #[async_trait]
992 impl Loader for AwsEc2MetadataLoader<'_> {
993 async fn load(&self, _key: &str) {}
994 }
995}
Haibo Huangd8abf3d2020-08-17 15:39:53 -0700996
997// https://github.com/dtolnay/async-trait/issues/120
Haibo Huang62e9b292020-09-01 20:28:34 -0700998pub mod issue120 {
Haibo Huangd8abf3d2020-08-17 15:39:53 -0700999 #![deny(clippy::trivially_copy_pass_by_ref)]
1000
1001 use async_trait::async_trait;
1002
1003 #[async_trait]
1004 trait Trait {
1005 async fn f(&self);
1006 }
1007
1008 #[async_trait]
1009 impl Trait for () {
1010 async fn f(&self) {}
1011 }
1012}
Haibo Huang62e9b292020-09-01 20:28:34 -07001013
1014// https://github.com/dtolnay/async-trait/issues/123
1015pub mod issue123 {
1016 use async_trait::async_trait;
1017
1018 #[async_trait]
1019 trait Trait<T = ()> {
1020 async fn f(&self) -> &str
1021 where
1022 T: 'async_trait,
1023 {
1024 "default"
1025 }
1026 }
1027
1028 #[async_trait]
1029 impl<T> Trait<T> for () {}
1030}
Chih-Hung Hsiehf8b73ea2020-10-26 13:16:52 -07001031
1032// https://github.com/dtolnay/async-trait/issues/129
1033pub mod issue129 {
1034 #![deny(clippy::pedantic)]
1035
1036 use async_trait::async_trait;
1037
1038 #[async_trait]
1039 pub trait TestTrait {
1040 async fn a(_b: u8, c: u8) -> u8 {
1041 c
1042 }
1043 }
1044
1045 pub struct TestStruct;
1046
1047 #[async_trait]
1048 impl TestTrait for TestStruct {
1049 async fn a(_b: u8, c: u8) -> u8 {
1050 c
1051 }
1052 }
1053}
Haibo Huang7ff84c32020-11-24 20:53:12 -08001054
1055// https://github.com/dtolnay/async-trait/issues/134
1056#[cfg(async_trait_nightly_testing)]
1057pub mod issue134 {
1058 use async_trait::async_trait;
1059
1060 #[async_trait]
1061 trait TestTrait {
1062 async fn run<const DUMMY: bool>(self)
1063 where
1064 Self: Sized,
1065 {
1066 }
1067 }
1068
1069 pub struct TestStruct;
1070
1071 #[async_trait]
1072 impl TestTrait for TestStruct {
1073 async fn run<const DUMMY: bool>(self)
1074 where
1075 Self: Sized,
1076 {
1077 }
1078 }
1079}