summaryrefslogtreecommitdiffstats
path: root/src/test/ui/async-await/in-trait
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/async-await/in-trait')
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types.rs24
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types.stderr57
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types2.rs30
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr17
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs24
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-example-desugared.rs23
-rw-r--r--src/test/ui/async-await/in-trait/async-example.rs32
-rw-r--r--src/test/ui/async-await/in-trait/async-generics-and-bounds.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr37
-rw-r--r--src/test/ui/async-await/in-trait/async-generics.rs18
-rw-r--r--src/test/ui/async-await/in-trait/async-generics.stderr37
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs20
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.rs18
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive-generic.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive-generic.stderr12
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive.rs21
-rw-r--r--src/test/ui/async-await/in-trait/async-recursive.stderr12
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err.rs17
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err.stderr17
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err2.rs21
-rw-r--r--src/test/ui/async-await/in-trait/fn-not-async-err2.stderr12
-rw-r--r--src/test/ui/async-await/in-trait/issue-102138.rs46
-rw-r--r--src/test/ui/async-await/in-trait/issue-102219.rs10
-rw-r--r--src/test/ui/async-await/in-trait/issue-102310.rs15
28 files changed, 650 insertions, 0 deletions
diff --git a/src/test/ui/async-await/in-trait/async-associated-types.rs b/src/test/ui/async-await/in-trait/async-associated-types.rs
new file mode 100644
index 000000000..a6f928f3b
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-associated-types.rs
@@ -0,0 +1,24 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait MyTrait<'a, 'b, T> where Self: 'a, T: Debug + Sized + 'b {
+ type MyAssoc;
+
+ async fn foo(&'a self, key: &'b T) -> Self::MyAssoc;
+}
+
+impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
+ type MyAssoc = (&'a U, &'b T);
+
+ async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ (self, key)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-associated-types.stderr b/src/test/ui/async-await/in-trait/async-associated-types.stderr
new file mode 100644
index 000000000..0985150ee
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-associated-types.stderr
@@ -0,0 +1,57 @@
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+ --> $DIR/async-associated-types.rs:19:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ | ^^^^^^^^^^^^^^
+ |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
+ --> $DIR/async-associated-types.rs:16:6
+ |
+LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
+ | ^^
+note: ...so that the types are compatible
+ --> $DIR/async-associated-types.rs:19:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ | ^^^^^^^^^^^^^^
+ = note: expected `(&'a U, &'b T)`
+ found `(&U, &T)`
+ = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the types are compatible
+ --> $DIR/async-associated-types.rs:19:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ | ^^^^^^^^^^^^^^
+ = note: expected `MyTrait<'static, 'static, T>`
+ found `MyTrait<'_, '_, T>`
+
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
+ --> $DIR/async-associated-types.rs:19:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ | ^^^^^^^^^^^^^^
+ |
+note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
+ --> $DIR/async-associated-types.rs:16:10
+ |
+LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
+ | ^^
+note: ...so that the types are compatible
+ --> $DIR/async-associated-types.rs:19:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ | ^^^^^^^^^^^^^^
+ = note: expected `(&'a U, &'b T)`
+ found `(&U, &T)`
+ = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the types are compatible
+ --> $DIR/async-associated-types.rs:19:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ | ^^^^^^^^^^^^^^
+ = note: expected `MyTrait<'static, 'static, T>`
+ found `MyTrait<'_, '_, T>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/async-await/in-trait/async-associated-types2.rs b/src/test/ui/async-await/in-trait/async-associated-types2.rs
new file mode 100644
index 000000000..e546a0579
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-associated-types2.rs
@@ -0,0 +1,30 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+ type Fut<'a>: Future<Output = i32>
+ where
+ Self: 'a;
+
+ fn foo<'a>(&'a self) -> Self::Fut<'a>;
+}
+
+impl MyTrait for i32 {
+ type Fut<'a> = impl Future<Output = i32> + 'a
+ where
+ Self: 'a;
+
+ fn foo<'a>(&'a self) -> Self::Fut<'a> {
+ async {
+ *self
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
new file mode 100644
index 000000000..38ba29718
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+use std::pin::Pin;
+
+trait MyTrait {
+ fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
+}
+
+impl MyTrait for i32 {
+ async fn foo(&self) -> i32 {
+ //~^ ERROR method `foo` has an incompatible type for trait
+ *self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr
new file mode 100644
index 000000000..22d2928f2
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr
@@ -0,0 +1,17 @@
+error[E0053]: method `foo` has an incompatible type for trait
+ --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28
+ |
+LL | async fn foo(&self) -> i32 {
+ | ^^^ expected struct `Pin`, found opaque type
+ |
+note: type in trait
+ --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22
+ |
+LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected fn pointer `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
+ found fn pointer `fn(&i32) -> impl Future<Output = i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs b/src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs
new file mode 100644
index 000000000..61d7e2520
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed.rs
@@ -0,0 +1,24 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+use std::pin::Pin;
+
+trait MyTrait {
+ async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+ // This will break once a PR that implements #102745 is merged
+ fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
+ Box::pin(async {
+ *self
+ })
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs b/src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs
new file mode 100644
index 000000000..feeda719e
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared-in-trait.rs
@@ -0,0 +1,21 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+ fn foo(&self) -> impl Future<Output = i32> + '_;
+}
+
+impl MyTrait for i32 {
+ // This will break once a PR that implements #102745 is merged
+ async fn foo(&self) -> i32 {
+ *self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example-desugared.rs b/src/test/ui/async-await/in-trait/async-example-desugared.rs
new file mode 100644
index 000000000..1313c9edd
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example-desugared.rs
@@ -0,0 +1,23 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+ async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+ // This will break once a PR that implements #102745 is merged
+ fn foo(&self) -> impl Future<Output = i32> + '_ {
+ async {
+ *self
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-example.rs b/src/test/ui/async-await/in-trait/async-example.rs
new file mode 100644
index 000000000..abf94ef74
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-example.rs
@@ -0,0 +1,32 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+ async fn foo(&self) -> i32;
+ async fn bar(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+ async fn foo(&self) -> i32 {
+ *self
+ }
+
+ async fn bar(&self) -> i32 {
+ self.foo().await
+ }
+}
+
+fn main() {
+ let x = 5;
+ // Calling from non-async context
+ let _ = x.foo();
+ let _ = x.bar();
+ // Calling from async block in non-async context
+ async {
+ let _: i32 = x.foo().await;
+ let _: i32 = x.bar().await;
+ };
+}
diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs b/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs
new file mode 100644
index 000000000..a73d55adf
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.rs
@@ -0,0 +1,21 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+use std::hash::Hash;
+
+trait MyTrait<T, U> {
+ async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+}
+
+impl<T, U> MyTrait<T, U> for (T, U) {
+ async fn foo(&self) -> &(T, U) {
+ self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
new file mode 100644
index 000000000..5c8d64fc6
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
@@ -0,0 +1,37 @@
+error[E0311]: the parameter type `U` may not live long enough
+ --> $DIR/async-generics-and-bounds.rs:12:28
+ |
+LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+ | ^^^^^^^
+ |
+note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+ --> $DIR/async-generics-and-bounds.rs:12:18
+ |
+LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+ | ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+ --> $DIR/async-generics-and-bounds.rs:12:28
+ |
+LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+ | ^^^^^^^
+
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/async-generics-and-bounds.rs:12:28
+ |
+LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+ | ^^^^^^^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+ --> $DIR/async-generics-and-bounds.rs:12:18
+ |
+LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+ | ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+ --> $DIR/async-generics-and-bounds.rs:12:28
+ |
+LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/async-await/in-trait/async-generics.rs b/src/test/ui/async-await/in-trait/async-generics.rs
new file mode 100644
index 000000000..67000e577
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics.rs
@@ -0,0 +1,18 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait<T, U> {
+ async fn foo(&self) -> &(T, U);
+}
+
+impl<T, U> MyTrait<T, U> for (T, U) {
+ async fn foo(&self) -> &(T, U) {
+ self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr
new file mode 100644
index 000000000..6ae73d9e3
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-generics.stderr
@@ -0,0 +1,37 @@
+error[E0311]: the parameter type `U` may not live long enough
+ --> $DIR/async-generics.rs:9:28
+ |
+LL | async fn foo(&self) -> &(T, U);
+ | ^^^^^^^
+ |
+note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+ --> $DIR/async-generics.rs:9:18
+ |
+LL | async fn foo(&self) -> &(T, U);
+ | ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+ --> $DIR/async-generics.rs:9:28
+ |
+LL | async fn foo(&self) -> &(T, U);
+ | ^^^^^^^
+
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/async-generics.rs:9:28
+ |
+LL | async fn foo(&self) -> &(T, U);
+ | ^^^^^^^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+ --> $DIR/async-generics.rs:9:18
+ |
+LL | async fn foo(&self) -> &(T, U);
+ | ^
+note: ...so that the reference type `&(T, U)` does not outlive the data it points at
+ --> $DIR/async-generics.rs:9:28
+ |
+LL | async fn foo(&self) -> &(T, U);
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
new file mode 100644
index 000000000..3f7448cec
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
@@ -0,0 +1,20 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait MyTrait<'a, 'b, T> {
+ async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
+}
+
+impl<'a, 'b, T, U> MyTrait<'a, 'b, T> for U {
+ async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ (self, key)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
new file mode 100644
index 000000000..0f0242027
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
@@ -0,0 +1,23 @@
+error[E0309]: the parameter type `Self` may not live long enough
+ --> $DIR/async-lifetimes-and-bounds.rs:11:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `Self: 'a`...
+ = note: ...so that the reference type `&'a Self` does not outlive the data it points at
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/async-lifetimes-and-bounds.rs:11:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
+ | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | trait MyTrait<'a, 'b, T: 'b> {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs
new file mode 100644
index 000000000..acbac471c
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs
@@ -0,0 +1,18 @@
+// check-fail
+// known-bug: #102682
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait<'a, 'b, T> {
+ async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
+}
+
+impl<'a, 'b, T, U> MyTrait<'a, 'b, T> for U {
+ async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
+ (self, key)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr
new file mode 100644
index 000000000..9a7d294bb
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-lifetimes.stderr
@@ -0,0 +1,23 @@
+error[E0309]: the parameter type `Self` may not live long enough
+ --> $DIR/async-lifetimes.rs:9:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `Self: 'a`...
+ = note: ...so that the reference type `&'a Self` does not outlive the data it points at
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/async-lifetimes.rs:9:43
+ |
+LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
+ | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | trait MyTrait<'a, 'b, T: 'b> {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/async-recursive-generic.rs b/src/test/ui/async-await/in-trait/async-recursive-generic.rs
new file mode 100644
index 000000000..6839abd38
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive-generic.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait<T> {
+ async fn foo_recursive(&self, n: usize) -> T;
+}
+
+impl<T> MyTrait<T> for T where T: Copy {
+ async fn foo_recursive(&self, n: usize) -> T {
+ //~^ ERROR recursion in an `async fn` requires boxing
+ if n > 0 {
+ self.foo_recursive(n - 1).await
+ } else {
+ *self
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-recursive-generic.stderr b/src/test/ui/async-await/in-trait/async-recursive-generic.stderr
new file mode 100644
index 000000000..cab173bdd
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive-generic.stderr
@@ -0,0 +1,12 @@
+error[E0733]: recursion in an `async fn` requires boxing
+ --> $DIR/async-recursive-generic.rs:11:48
+ |
+LL | async fn foo_recursive(&self, n: usize) -> T {
+ | ^ recursive `async fn`
+ |
+ = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
+ = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/async-await/in-trait/async-recursive.rs b/src/test/ui/async-await/in-trait/async-recursive.rs
new file mode 100644
index 000000000..61119f809
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+ async fn foo_recursive(&self, n: usize) -> i32;
+}
+
+impl MyTrait for i32 {
+ async fn foo_recursive(&self, n: usize) -> i32 {
+ //~^ ERROR recursion in an `async fn` requires boxing
+ if n > 0 {
+ self.foo_recursive(n - 1).await
+ } else {
+ *self
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/async-recursive.stderr b/src/test/ui/async-await/in-trait/async-recursive.stderr
new file mode 100644
index 000000000..9feff37b3
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/async-recursive.stderr
@@ -0,0 +1,12 @@
+error[E0733]: recursion in an `async fn` requires boxing
+ --> $DIR/async-recursive.rs:11:48
+ |
+LL | async fn foo_recursive(&self, n: usize) -> i32 {
+ | ^^^ recursive `async fn`
+ |
+ = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
+ = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err.rs b/src/test/ui/async-await/in-trait/fn-not-async-err.rs
new file mode 100644
index 000000000..f94d32145
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err.rs
@@ -0,0 +1,17 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {
+ async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+ fn foo(&self) -> i32 {
+ //~^ ERROR: `i32` is not a future [E0277]
+ *self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err.stderr b/src/test/ui/async-await/in-trait/fn-not-async-err.stderr
new file mode 100644
index 000000000..03321dc5b
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `i32` is not a future
+ --> $DIR/fn-not-async-err.rs:11:22
+ |
+LL | fn foo(&self) -> i32 {
+ | ^^^ `i32` is not a future
+ |
+ = help: the trait `Future` is not implemented for `i32`
+ = note: i32 must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `MyTrait::foo::{opaque#0}`
+ --> $DIR/fn-not-async-err.rs:7:28
+ |
+LL | async fn foo(&self) -> i32;
+ | ^^^ required by this bound in `MyTrait::foo::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err2.rs b/src/test/ui/async-await/in-trait/fn-not-async-err2.rs
new file mode 100644
index 000000000..594baa91a
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err2.rs
@@ -0,0 +1,21 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait MyTrait {
+ async fn foo(&self) -> i32;
+}
+
+impl MyTrait for i32 {
+ fn foo(&self) -> impl Future<Output = i32> {
+ //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return [E0562]
+ async {
+ *self
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr b/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr
new file mode 100644
index 000000000..f591f1847
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/fn-not-async-err2.stderr
@@ -0,0 +1,12 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
+ --> $DIR/fn-not-async-err2.rs:13:22
+ |
+LL | fn foo(&self) -> impl Future<Output = i32> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/async-await/in-trait/issue-102138.rs b/src/test/ui/async-await/in-trait/issue-102138.rs
new file mode 100644
index 000000000..f61b34ed9
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/issue-102138.rs
@@ -0,0 +1,46 @@
+// check-pass
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+async fn yield_now() {}
+
+trait AsyncIterator {
+ type Item;
+ async fn next(&mut self) -> Option<Self::Item>;
+}
+
+struct YieldingRange {
+ counter: u32,
+ stop: u32,
+}
+
+impl AsyncIterator for YieldingRange {
+ type Item = u32;
+
+ async fn next(&mut self) -> Option<Self::Item> {
+ if self.counter == self.stop {
+ None
+ } else {
+ let c = self.counter;
+ self.counter += 1;
+ yield_now().await;
+ Some(c)
+ }
+ }
+}
+
+async fn async_main() {
+ let mut x = YieldingRange { counter: 0, stop: 10 };
+
+ while let Some(v) = x.next().await {
+ println!("Hi: {v}");
+ }
+}
+
+fn main() {
+ let _ = async_main();
+}
diff --git a/src/test/ui/async-await/in-trait/issue-102219.rs b/src/test/ui/async-await/in-trait/issue-102219.rs
new file mode 100644
index 000000000..9a35f6515
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/issue-102219.rs
@@ -0,0 +1,10 @@
+// compile-flags:--crate-type=lib
+// edition:2021
+// check-pass
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait T {
+ async fn foo();
+}
diff --git a/src/test/ui/async-await/in-trait/issue-102310.rs b/src/test/ui/async-await/in-trait/issue-102310.rs
new file mode 100644
index 000000000..49c3e9fee
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/issue-102310.rs
@@ -0,0 +1,15 @@
+// check-pass
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+pub trait SpiDevice {
+ async fn transaction<F, R>(&mut self);
+}
+
+impl SpiDevice for () {
+ async fn transaction<F, R>(&mut self) {}
+}
+
+fn main() {}