diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index e9c05eb5f455f..a11721ba0213a 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -332,6 +332,15 @@ impl FnDeclKind {
             _ => false,
         }
     }
+
+    fn async_fn_allowed(&self, tcx: TyCtxt<'_>) -> bool {
+        match self {
+            FnDeclKind::Fn | FnDeclKind::Inherent => true,
+            FnDeclKind::Impl if tcx.features().async_fn_in_trait => true,
+            FnDeclKind::Trait if tcx.features().async_fn_in_trait => true,
+            _ => false,
+        }
+    }
 }
 
 #[derive(Copy, Clone)]
@@ -1692,14 +1701,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }));
 
         let output = if let Some((ret_id, span)) = make_ret_async {
-            if !kind.impl_trait_allowed(self.tcx) {
+            if !kind.async_fn_allowed(self.tcx) {
                 match kind {
                     FnDeclKind::Trait | FnDeclKind::Impl => {
                         self.tcx
                             .sess
                             .create_feature_err(
                                 TraitFnAsync { fn_span, span },
-                                sym::return_position_impl_trait_in_trait,
+                                sym::async_fn_in_trait,
                             )
                             .emit();
                     }
@@ -1917,9 +1926,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 let future_bound = this.lower_async_fn_output_type_to_future_bound(
                     output,
                     span,
-                    ImplTraitContext::ReturnPositionOpaqueTy {
-                        origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
-                        in_trait,
+                    if in_trait && !this.tcx.features().return_position_impl_trait_in_trait {
+                        ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn)
+                    } else {
+                        ImplTraitContext::ReturnPositionOpaqueTy {
+                            origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+                            in_trait,
+                        }
                     },
                 );
 
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index ad28595ca82b3..4c891fbf16e94 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -312,6 +312,8 @@ declare_features! (
     (active, associated_type_defaults, "1.2.0", Some(29661), None),
     /// Allows `async || body` closures.
     (active, async_closure, "1.37.0", Some(62290), None),
+    /// Alows async functions to be declared, implemented, and used in traits.
+    (incomplete, async_fn_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None),
     /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
     (active, c_unwind, "1.52.0", Some(74990), None),
     /// Allows using C-variadics.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7785d29c15f2c..502ef67fc6767 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -396,6 +396,7 @@ symbols! {
         assume_init,
         async_await,
         async_closure,
+        async_fn_in_trait,
         atomic,
         atomic_mod,
         atomics,
diff --git a/src/test/ui/async-await/async-trait-fn.stderr b/src/test/ui/async-await/async-trait-fn.stderr
index e5c584e31e815..4fa54c6e36960 100644
--- a/src/test/ui/async-await/async-trait-fn.stderr
+++ b/src/test/ui/async-await/async-trait-fn.stderr
@@ -9,7 +9,7 @@ LL |     async fn foo() {}
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/async-trait-fn.rs:5:5
@@ -22,7 +22,7 @@ LL |     async fn bar(&self) {}
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/async-trait-fn.rs:7:5
@@ -35,7 +35,7 @@ LL |     async fn baz() {
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0308]: mismatched types
   --> $DIR/async-trait-fn.rs:3:20
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index 8c2902d9b00d1..62a243e69e743 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -90,7 +90,7 @@ LL |     async fn foo() {}
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0308]: mismatched types
   --> $DIR/edition-deny-async-fns-2015.rs:18:20
diff --git a/src/test/ui/async-await/feature-gate-async_fn_in_trait.rs b/src/test/ui/async-await/feature-gate-async_fn_in_trait.rs
new file mode 100644
index 0000000000000..792f378cb57f1
--- /dev/null
+++ b/src/test/ui/async-await/feature-gate-async_fn_in_trait.rs
@@ -0,0 +1,25 @@
+// edition:2021
+
+// RPITIT is not enough to allow use of async functions
+#![allow(incomplete_features)]
+#![feature(return_position_impl_trait_in_trait)]
+
+trait T {
+    async fn foo(); //~ ERROR functions in traits cannot be declared `async`
+}
+
+// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also
+// feature-gate-return_position_impl_trait_in_trait.rs)
+trait T2 {
+    async fn foo() -> impl Sized; //~ ERROR functions in traits cannot be declared `async`
+}
+
+trait T3 {
+    fn foo() -> impl std::future::Future<Output = ()>;
+}
+
+impl T3 for () {
+    async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/feature-gate-async_fn_in_trait.stderr b/src/test/ui/async-await/feature-gate-async_fn_in_trait.stderr
new file mode 100644
index 0000000000000..2a5fbd1ecd03d
--- /dev/null
+++ b/src/test/ui/async-await/feature-gate-async_fn_in_trait.stderr
@@ -0,0 +1,42 @@
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/feature-gate-async_fn_in_trait.rs:8:5
+   |
+LL |     async fn foo();
+   |     -----^^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/feature-gate-async_fn_in_trait.rs:14:5
+   |
+LL |     async fn foo() -> impl Sized;
+   |     -----^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/feature-gate-async_fn_in_trait.rs:22:5
+   |
+LL |     async fn foo() {}
+   |     -----^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0706`.
diff --git a/src/test/ui/async-await/issues/issue-95307.stderr b/src/test/ui/async-await/issues/issue-95307.stderr
index 1c12f1e4862e8..a497cebe3c3d8 100644
--- a/src/test/ui/async-await/issues/issue-95307.stderr
+++ b/src/test/ui/async-await/issues/issue-95307.stderr
@@ -9,7 +9,7 @@ LL |     async fn new() -> [u8; _];
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error: in expressions, `_` can only be used on the left-hand side of an assignment
   --> $DIR/issue-95307.rs:7:28
diff --git a/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs
index de7966c66b057..637765fff11e4 100644
--- a/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs
+++ b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs
@@ -1,5 +1,18 @@
+// edition:2021
+
+// async_fn_in_trait is not enough to allow use of RPITIT
+#![allow(incomplete_features)]
+#![feature(async_fn_in_trait)]
+
 trait Foo {
     fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
+    fn baz() -> Box<impl std::fmt::Display>; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
+}
+
+// Both return_position_impl_trait_in_trait and async_fn_in_trait are required for this (see also
+// feature-gate-async_fn_in_trait.rs)
+trait AsyncFoo {
+    async fn bar() -> impl Sized; //~ ERROR `impl Trait` only allowed in function and inherent method return types, not in trait method return
 }
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
index 36177bbe15830..aeabed4a6ab66 100644
--- a/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
+++ b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
@@ -1,5 +1,5 @@
 error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
-  --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:2:17
+  --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17
    |
 LL |     fn bar() -> impl Sized;
    |                 ^^^^^^^^^^
@@ -7,6 +7,24 @@ LL |     fn bar() -> impl Sized;
    = 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
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+  --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21
+   |
+LL |     fn baz() -> Box<impl std::fmt::Display>;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
+  --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23
+   |
+LL |     async fn bar() -> impl Sized;
+   |                       ^^^^^^^^^^
+   |
+   = 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 3 previous errors
 
 For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
index 36304779df36f..800b5a43a0066 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -147,7 +147,7 @@ LL |         async fn ft1();
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:21:9
@@ -160,7 +160,7 @@ LL |         const async unsafe extern "C" fn ft5();
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:29:9
@@ -173,7 +173,7 @@ LL |         async fn ft1() {}
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/fn-header-semantic-fail.rs:33:9
@@ -186,7 +186,7 @@ LL |         const async unsafe extern "C" fn ft5() {}
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0391]: cycle detected when computing type of `main::ff5::{opaque#0}`
   --> $DIR/fn-header-semantic-fail.rs:12:44
diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr
index 55c3b66f1363d..1354abb4f144b 100644
--- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr
+++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr
@@ -33,7 +33,7 @@ LL |     async fn associated();
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
@@ -46,7 +46,7 @@ LL |     async fn associated();
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
index 3814c568e72c1..2c1fa7b36b60e 100644
--- a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
@@ -51,7 +51,7 @@ LL | trait C{async fn new(val: T) {}
    = note: `async` trait functions are not currently supported
    = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
    = 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
+   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
 
 warning: changes to closure capture in Rust 2021 will affect drop order
   --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:6:57