about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-09 03:40:17 +0000
committerbors <bors@rust-lang.org>2022-09-09 03:40:17 +0000
commitab32548539ec38a939c1b58599249f3b54130026 (patch)
treeb7b73cde17986e1f6a2c97093cbadb9b84d3372b /src
parent7200da0217f99e929e58d0b40483097db37270ac (diff)
parent6876c94d800433ad7f2ea72da64d963eb2269589 (diff)
downloadrust-ab32548539ec38a939c1b58599249f3b54130026.tar.gz
rust-ab32548539ec38a939c1b58599249f3b54130026.zip
Auto merge of #101224 - compiler-errors:rpitit, r=oli-obk
Initial implementation of return-position `impl Trait` in traits

* Create a new item kind, called `ImplTraitPlaceholder`, which is used to lower `ast::TyKind::ImplTrait` in trait method returns.
    * This item is the child of the trait method, which simplifies the way we calculate bounds and stuff.
* Use the def-id of this type to construct a projection type that we use during astconv for the return type of the trait method signature.
* Implement logic to normalize this `ImplTraitPlaceholder` projection type when we know its concrete impl (this is pretty limited currently, but really there are no other selection candidates that make sense -- for now!)
* Check that the `impl Trait`'s bounds are satisfied on the concrete type provided in the impl.

This is obviously nowhere near complete, but I wanted to at least get some initial support landed so we can start playing around with it.

What works:
* async fn in trait and RPITIT, including multiple `impl Trait`s and `impl Trait` nested in associated type bindings, like `impl Future<Output = impl Sized>`
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/librustdoc/formats/item_type.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/test/ui/async-await/async-trait-fn.rs3
-rw-r--r--src/test/ui/async-await/async-trait-fn.stderr75
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.rs3
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr30
-rw-r--r--src/test/ui/async-await/issues/issue-95307.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr12
-rw-r--r--src/test/ui/impl-trait/in-trait/deep-match-works.rs16
-rw-r--r--src/test/ui/impl-trait/in-trait/deep-match.rs15
-rw-r--r--src/test/ui/impl-trait/in-trait/deep-match.stderr20
-rw-r--r--src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs13
-rw-r--r--src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr17
-rw-r--r--src/test/ui/impl-trait/in-trait/nested-rpitit.rs32
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs19
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr17
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl.rs48
-rw-r--r--src/test/ui/impl-trait/in-trait/reveal.rs18
-rw-r--r--src/test/ui/impl-trait/in-trait/success.rs40
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr6
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.rs2
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr184
-rw-r--r--src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs1
-rw-r--r--src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr43
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs5
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr46
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs3
32 files changed, 506 insertions, 184 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 66f766bfbe8..08b696e65eb 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1492,7 +1492,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
             Array(Box::new(clean_ty(ty, cx)), length)
         }
         TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
-        TyKind::OpaqueDef(item_id, _) => {
+        TyKind::OpaqueDef(item_id, _, _) => {
             let item = cx.tcx.hir().item(item_id);
             if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
                 ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index a9d511ae11e..395f213ca87 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -511,8 +511,8 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
         | Res::Err => return res.def_id(),
         Res::Def(
             TyParam | ConstParam | Ctor(..) | ExternCrate | Use | ForeignMod | AnonConst
-            | InlineConst | OpaqueTy | Field | LifetimeParam | GlobalAsm | Impl | Closure
-            | Generator,
+            | InlineConst | OpaqueTy | ImplTraitPlaceholder | Field | LifetimeParam | GlobalAsm
+            | Impl | Closure | Generator,
             id,
         ) => return id,
     };
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index 0a7ee200591..f21e60a64e0 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -135,6 +135,7 @@ impl From<DefKind> for ItemType {
             | DefKind::AnonConst
             | DefKind::InlineConst
             | DefKind::OpaqueTy
+            | DefKind::ImplTraitPlaceholder
             | DefKind::Field
             | DefKind::LifetimeParam
             | DefKind::GlobalAsm
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c27f0ce18c1..cfd6ce402c2 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1805,8 +1805,8 @@ fn resolution_failure(
                                 }
                                 return;
                             }
-                            Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
-                            | Static(_) => "associated item",
+                            Trait | TyAlias | ForeignTy | OpaqueTy | ImplTraitPlaceholder
+                            | TraitAlias | TyParam | Static(_) => "associated item",
                             Impl | GlobalAsm => unreachable!("not a path"),
                         }
                     } else {
diff --git a/src/test/ui/async-await/async-trait-fn.rs b/src/test/ui/async-await/async-trait-fn.rs
index e2062e82725..0ea685986db 100644
--- a/src/test/ui/async-await/async-trait-fn.rs
+++ b/src/test/ui/async-await/async-trait-fn.rs
@@ -1,8 +1,11 @@
 // edition:2018
 trait T {
     async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
+    //~^ ERROR mismatched types
     async fn bar(&self) {} //~ ERROR functions in traits cannot be declared `async`
+    //~^ ERROR mismatched types
     async fn baz() { //~ ERROR functions in traits cannot be declared `async`
+        //~^ ERROR mismatched types
         // Nested item must not ICE.
         fn a() {}
     }
diff --git a/src/test/ui/async-await/async-trait-fn.stderr b/src/test/ui/async-await/async-trait-fn.stderr
index 1eb8969a80d..e5c584e31e8 100644
--- a/src/test/ui/async-await/async-trait-fn.stderr
+++ b/src/test/ui/async-await/async-trait-fn.stderr
@@ -2,40 +2,89 @@ error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/async-trait-fn.rs:3: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(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/async-trait-fn.rs:4:5
+  --> $DIR/async-trait-fn.rs:5:5
    |
 LL |     async fn bar(&self) {}
-   |     -----^^^^^^^^^^^^^^^^^
+   |     -----^^^^^^^^^^^^^^
    |     |
    |     `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(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/async-trait-fn.rs:5:5
+  --> $DIR/async-trait-fn.rs:7:5
+   |
+LL |     async fn baz() {
+   |     -----^^^^^^^^^
+   |     |
+   |     `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(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error[E0308]: mismatched types
+  --> $DIR/async-trait-fn.rs:3:20
+   |
+LL |     async fn foo() {}
+   |                    ^^ expected associated type, found opaque type
+   |
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+   |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                           ------------------------------- the found opaque type
+   |
+   = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/async-trait-fn.rs:3:20>)
+                  found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
+error[E0308]: mismatched types
+  --> $DIR/async-trait-fn.rs:5:25
+   |
+LL |     async fn bar(&self) {}
+   |                         ^^ expected associated type, found opaque type
+   |
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+   |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                           ------------------------------- the found opaque type
+   |
+   = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/async-trait-fn.rs:5:25>)
+                  found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
+error[E0308]: mismatched types
+  --> $DIR/async-trait-fn.rs:7:20
    |
 LL |       async fn baz() {
-   |       ^----
-   |       |
-   |  _____`async` because of this
-   | |
+   |  ____________________^
+LL | |
 LL | |         // Nested item must not ICE.
 LL | |         fn a() {}
 LL | |     }
-   | |_____^
+   | |_____^ expected associated type, found opaque type
    |
-   = note: `async` trait functions are not currently supported
-   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+   |
+LL |   pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                             ------------------------------- the found opaque type
+   |
+   = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/async-trait-fn.rs:7:20>)
+                  found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0706`.
+Some errors have detailed explanations: E0308, E0706.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
index e5dc9c8a5fe..22a61dcd25f 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
@@ -16,7 +16,8 @@ impl Foo {
 
 trait Bar {
     async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
-                      //~^ ERROR functions in traits cannot be declared `async`
+    //~^ ERROR functions in traits cannot be declared `async`
+    //~| ERROR mismatched types
 }
 
 fn main() {
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 35f9c581c7b..8c2902d9b00 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
@@ -53,7 +53,7 @@ LL |     async fn foo() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:36:9
+  --> $DIR/edition-deny-async-fns-2015.rs:37:9
    |
 LL |         async fn bar() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -62,7 +62,7 @@ LL |         async fn bar() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:26:9
+  --> $DIR/edition-deny-async-fns-2015.rs:27:9
    |
 LL |         async fn foo() {}
    |         ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -71,7 +71,7 @@ LL |         async fn foo() {}
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
 error[E0670]: `async fn` is not permitted in Rust 2015
-  --> $DIR/edition-deny-async-fns-2015.rs:31:13
+  --> $DIR/edition-deny-async-fns-2015.rs:32:13
    |
 LL |             async fn bar() {}
    |             ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -83,14 +83,30 @@ error[E0706]: functions in traits cannot be declared `async`
   --> $DIR/edition-deny-async-fns-2015.rs:18: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(return_position_impl_trait_in_trait)]` to the crate attributes to enable
 
-error: aborting due to 10 previous errors
+error[E0308]: mismatched types
+  --> $DIR/edition-deny-async-fns-2015.rs:18:20
+   |
+LL |     async fn foo() {}
+   |                    ^^ expected associated type, found opaque type
+   |
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+   |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                           ------------------------------- the found opaque type
+   |
+   = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/edition-deny-async-fns-2015.rs:18:20>)
+                  found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
+error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0670, E0706.
-For more information about an error, try `rustc --explain E0670`.
+Some errors have detailed explanations: E0308, E0670, E0706.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/async-await/issues/issue-95307.stderr b/src/test/ui/async-await/issues/issue-95307.stderr
index 29aebb719d6..1c12f1e4862 100644
--- a/src/test/ui/async-await/issues/issue-95307.stderr
+++ b/src/test/ui/async-await/issues/issue-95307.stderr
@@ -8,6 +8,8 @@ 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
 
 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
new file mode 100644
index 00000000000..de7966c66b0
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.rs
@@ -0,0 +1,5 @@
+trait Foo {
+    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
new file mode 100644
index 00000000000..36177bbe158
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr
@@ -0,0 +1,12 @@
+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
+   |
+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
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/in-trait/deep-match-works.rs b/src/test/ui/impl-trait/in-trait/deep-match-works.rs
new file mode 100644
index 00000000000..772da845ee1
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/deep-match-works.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+struct Wrapper<T>(T);
+
+trait Foo {
+    fn bar() -> Wrapper<impl Sized>;
+}
+
+impl Foo for () {
+    fn bar() -> Wrapper<i32> { Wrapper(0) }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/deep-match.rs b/src/test/ui/impl-trait/in-trait/deep-match.rs
new file mode 100644
index 00000000000..5a220bc3f19
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/deep-match.rs
@@ -0,0 +1,15 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+struct Wrapper<T>(T);
+
+trait Foo {
+    fn bar() -> Wrapper<impl Sized>;
+}
+
+impl Foo for () {
+    fn bar() -> i32 { 0 }
+    //~^ ERROR method `bar` has an incompatible type for trait
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/deep-match.stderr b/src/test/ui/impl-trait/in-trait/deep-match.stderr
new file mode 100644
index 00000000000..af449869cb3
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/deep-match.stderr
@@ -0,0 +1,20 @@
+error[E0053]: method `bar` has an incompatible type for trait
+  --> $DIR/deep-match.rs:11:17
+   |
+LL |     fn bar() -> i32 { 0 }
+   |                 ^^^
+   |                 |
+   |                 expected struct `Wrapper`, found `i32`
+   |                 help: change the output type to match the trait: `Wrapper<_>`
+   |
+note: type in trait
+  --> $DIR/deep-match.rs:7:17
+   |
+LL |     fn bar() -> Wrapper<impl Sized>;
+   |                 ^^^^^^^^^^^^^^^^^^^
+   = note: expected fn pointer `fn() -> Wrapper<_>`
+              found fn pointer `fn() -> i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs
new file mode 100644
index 00000000000..bb4e0d44f3e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs
@@ -0,0 +1,13 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    fn bar() -> impl std::fmt::Display;
+}
+
+impl Foo for () {
+    fn bar() -> () {}
+    //~^ ERROR `()` doesn't implement `std::fmt::Display`
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr
new file mode 100644
index 00000000000..aa5492d285e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `()` doesn't implement `std::fmt::Display`
+  --> $DIR/doesnt-satisfy.rs:9:17
+   |
+LL |     fn bar() -> () {}
+   |                 ^^ `()` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `()`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `Foo::bar::{opaque#0}`
+  --> $DIR/doesnt-satisfy.rs:5:22
+   |
+LL |     fn bar() -> impl std::fmt::Display;
+   |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/in-trait/nested-rpitit.rs b/src/test/ui/impl-trait/in-trait/nested-rpitit.rs
new file mode 100644
index 00000000000..65285e3a3cc
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/nested-rpitit.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+use std::ops::Deref;
+
+trait Foo {
+    fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
+}
+
+struct A;
+
+impl Foo for A {
+    fn bar(self) -> &'static str {
+        "Hello, world"
+    }
+}
+
+struct B;
+
+impl Foo for B {
+    fn bar(self) -> Box<i32> {
+        Box::new(42)
+    }
+}
+
+fn main() {
+    println!("Message for you: {:?}", &*A.bar());
+    println!("Another for you: {:?}", &*B.bar());
+}
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
new file mode 100644
index 00000000000..3ac264e8eba
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
@@ -0,0 +1,19 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+
+trait Foo {
+    fn bar(&self) -> impl Display;
+}
+
+impl Foo for () {
+    fn bar(&self) -> impl Display {
+        "Hello, world"
+    }
+}
+
+fn main() {
+    let x: &str = ().bar();
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr
new file mode 100644
index 00000000000..15edda48340
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/opaque-in-impl-is-opaque.rs:17:19
+   |
+LL |     fn bar(&self) -> impl Display {
+   |                      ------------ the found opaque type
+...
+LL |     let x: &str = ().bar();
+   |            ----   ^^^^^^^^ expected `&str`, found opaque type
+   |            |
+   |            expected due to this
+   |
+   = note: expected reference `&str`
+            found opaque type `impl std::fmt::Display`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
new file mode 100644
index 00000000000..2e06629699a
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
@@ -0,0 +1,48 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {
+    fn foo(&self) -> impl Debug;
+}
+
+impl Foo for () {
+    fn foo(&self) -> impl Debug {
+        "Hello, world"
+    }
+}
+
+impl<T: Default + Debug> Foo for std::marker::PhantomData<T> {
+    fn foo(&self) -> impl Debug {
+        T::default()
+    }
+}
+
+trait Bar {
+    fn bar<T>(&self) -> impl Debug;
+}
+
+impl Bar for () {
+    fn bar<T>(&self) -> impl Debug {
+        format!("Hello with generic {}", std::any::type_name::<T>())
+    }
+}
+
+trait Baz {
+    fn baz(&self) -> impl Debug + '_;
+}
+
+impl Baz for String {
+    fn baz(&self) -> impl Debug + '_ {
+        (self,)
+    }
+}
+
+fn main() {
+    println!("{:?}", ().foo());
+    println!("{:?}", ().bar::<u64>());
+    println!("{:?}", "hi".to_string().baz());
+}
diff --git a/src/test/ui/impl-trait/in-trait/reveal.rs b/src/test/ui/impl-trait/in-trait/reveal.rs
new file mode 100644
index 00000000000..d6ede1cc495
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/reveal.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    fn f() -> Box<impl Sized>;
+}
+
+impl Foo for () {
+    fn f() -> Box<String> {
+        Box::new(String::new())
+    }
+}
+
+fn main() {
+    let x: Box<String> = <() as Foo>::f();
+}
diff --git a/src/test/ui/impl-trait/in-trait/success.rs b/src/test/ui/impl-trait/in-trait/success.rs
new file mode 100644
index 00000000000..4cbe682b46f
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/success.rs
@@ -0,0 +1,40 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+
+trait Foo {
+    fn bar(&self) -> impl Display;
+}
+
+impl Foo for i32 {
+    fn bar(&self) -> i32 {
+        *self
+    }
+}
+
+impl Foo for &'static str {
+    fn bar(&self) -> &'static str {
+        *self
+    }
+}
+
+struct Yay;
+
+impl Foo for Yay {
+    fn bar(&self) -> String {
+        String::from(":^)")
+    }
+}
+
+fn foo_generically<T: Foo>(t: T) {
+    println!("{}", t.bar());
+}
+
+fn main() {
+    println!("{}", "Hello, world.".bar());
+    println!("The answer is {}!", 42.bar());
+    foo_generically(Yay);
+}
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 58a2f79efb4..9b346387d61 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -162,12 +162,18 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
    |
 LL |     fn in_return() -> impl Debug;
    |                       ^^^^^^^^^^
+   |
+   = 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 `impl` method return
   --> $DIR/where-allowed.rs:125:34
    |
 LL |     fn in_trait_impl_return() -> impl Debug { () }
    |                                  ^^^^^^^^^^
+   |
+   = 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 `extern fn` param
   --> $DIR/where-allowed.rs:138:33
diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs
index 8ff14fb1f30..cf5d3dab4aa 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.rs
+++ b/src/test/ui/parser/fn-header-semantic-fail.rs
@@ -27,7 +27,6 @@ fn main() {
     struct Y;
     impl X for Y {
         async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
-        //~^ ERROR has an incompatible type for trait
         unsafe fn ft2() {} // OK.
         const fn ft3() {} //~ ERROR functions in traits cannot be declared const
         extern "C" fn ft4() {}
@@ -36,7 +35,6 @@ fn main() {
         //~| ERROR functions in traits cannot be declared const
         //~| ERROR functions cannot be both `const` and `async`
         //~| ERROR cycle detected
-        //~| ERROR has an incompatible type for trait
     }
 
     impl Y {
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
index bc51ba8b8c5..36304779df3 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -7,17 +7,6 @@ LL |     const async unsafe extern "C" fn ff5() {}
    |     |     `async` because of this
    |     `const` because of this
 
-error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:17:9
-   |
-LL |         async fn ft1();
-   |         -----^^^^^^^^^^
-   |         |
-   |         `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
-
 error[E0379]: functions in traits cannot be declared const
   --> $DIR/fn-header-semantic-fail.rs:19:9
    |
@@ -30,17 +19,6 @@ error[E0379]: functions in traits cannot be declared const
 LL |         const async unsafe extern "C" fn ft5();
    |         ^^^^^ functions in traits cannot be const
 
-error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:21:9
-   |
-LL |         const async unsafe extern "C" fn ft5();
-   |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |               |
-   |               `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
-
 error: functions cannot be both `const` and `async`
   --> $DIR/fn-header-semantic-fail.rs:21:9
    |
@@ -50,42 +28,20 @@ LL |         const async unsafe extern "C" fn ft5();
    |         |     `async` because of this
    |         `const` because of this
 
-error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:29:9
-   |
-LL |         async fn ft1() {}
-   |         -----^^^^^^^^^^^^
-   |         |
-   |         `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
-
 error[E0379]: functions in traits cannot be declared const
-  --> $DIR/fn-header-semantic-fail.rs:32:9
+  --> $DIR/fn-header-semantic-fail.rs:31:9
    |
 LL |         const fn ft3() {}
    |         ^^^^^ functions in traits cannot be const
 
 error[E0379]: functions in traits cannot be declared const
-  --> $DIR/fn-header-semantic-fail.rs:34:9
+  --> $DIR/fn-header-semantic-fail.rs:33:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^ functions in traits cannot be const
 
-error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/fn-header-semantic-fail.rs:34:9
-   |
-LL |         const async unsafe extern "C" fn ft5() {}
-   |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |               |
-   |               `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
-
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:34:9
+  --> $DIR/fn-header-semantic-fail.rs:33:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^-^^^^^------------------------------
@@ -94,7 +50,7 @@ LL |         const async unsafe extern "C" fn ft5() {}
    |         `const` because of this
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:47:9
+  --> $DIR/fn-header-semantic-fail.rs:45:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^-^^^^^------------------------------
@@ -103,7 +59,7 @@ LL |         const async unsafe extern "C" fn fi5() {}
    |         `const` because of this
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:53:18
+  --> $DIR/fn-header-semantic-fail.rs:51:18
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -116,7 +72,7 @@ LL |         fn fe1();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:54:19
+  --> $DIR/fn-header-semantic-fail.rs:52:19
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -130,7 +86,7 @@ LL |         fn fe2();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:55:18
+  --> $DIR/fn-header-semantic-fail.rs:53:18
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -144,7 +100,7 @@ LL |         fn fe3();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:56:23
+  --> $DIR/fn-header-semantic-fail.rs:54:23
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -158,7 +114,7 @@ LL |         fn fe4();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:57:42
+  --> $DIR/fn-header-semantic-fail.rs:55:42
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -172,7 +128,7 @@ LL |         fn fe5();
    |         ~~
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:57:9
+  --> $DIR/fn-header-semantic-fail.rs:55:9
    |
 LL |         const async unsafe extern "C" fn fe5();
    |         ^^^^^-^^^^^----------------------------
@@ -180,6 +136,58 @@ LL |         const async unsafe extern "C" fn fe5();
    |         |     `async` because of this
    |         `const` because of this
 
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/fn-header-semantic-fail.rs:17:9
+   |
+LL |         async fn ft1();
+   |         -----^^^^^^^^^^
+   |         |
+   |         `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(return_position_impl_trait_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
+   |
+LL |         const async unsafe extern "C" fn ft5();
+   |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               `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(return_position_impl_trait_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
+   |
+LL |         async fn ft1() {}
+   |         -----^^^^^^^^^
+   |         |
+   |         `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(return_position_impl_trait_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
+   |
+LL |         const async unsafe extern "C" fn ft5() {}
+   |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               `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(return_position_impl_trait_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
    |
@@ -216,60 +224,24 @@ LL | |     }
 LL | | }
    | |_^
 
-error[E0053]: method `ft1` has an incompatible type for trait
-  --> $DIR/fn-header-semantic-fail.rs:29:24
-   |
-LL |         async fn ft1() {}
-   |                        ^
-   |                        |
-   |                        checked the `Output` of this `async fn`, found opaque type
-   |                        expected `()`, found opaque type
-   |
-   = note: while checking the return type of the `async fn`
-note: type in trait
-  --> $DIR/fn-header-semantic-fail.rs:17:23
-   |
-LL |         async fn ft1();
-   |                       ^
-   = note: expected fn pointer `fn()`
-              found fn pointer `fn() -> impl Future<Output = ()>`
-
-error[E0053]: method `ft5` has an incompatible type for trait
-  --> $DIR/fn-header-semantic-fail.rs:34:48
-   |
-LL |         const async unsafe extern "C" fn ft5() {}
-   |                                                ^
-   |                                                |
-   |                                                checked the `Output` of this `async fn`, found opaque type
-   |                                                expected `()`, found opaque type
-   |
-   = note: while checking the return type of the `async fn`
-note: type in trait
-  --> $DIR/fn-header-semantic-fail.rs:21:47
-   |
-LL |         const async unsafe extern "C" fn ft5();
-   |                                               ^
-   = note: expected fn pointer `unsafe extern "C" fn()`
-              found fn pointer `unsafe extern "C" fn() -> impl Future<Output = ()>`
-
 error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`
-  --> $DIR/fn-header-semantic-fail.rs:34:48
+  --> $DIR/fn-header-semantic-fail.rs:33:48
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |                                                ^
    |
 note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
-  --> $DIR/fn-header-semantic-fail.rs:34:9
+  --> $DIR/fn-header-semantic-fail.rs:33:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
-  --> $DIR/fn-header-semantic-fail.rs:34:9
+  --> $DIR/fn-header-semantic-fail.rs:33:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5`...
-  --> $DIR/fn-header-semantic-fail.rs:34:9
+  --> $DIR/fn-header-semantic-fail.rs:33:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -288,30 +260,30 @@ LL | |     }
 LL | | }
    | |_^
 
-error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`
-  --> $DIR/fn-header-semantic-fail.rs:47:48
+error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`
+  --> $DIR/fn-header-semantic-fail.rs:45:48
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |                                                ^
    |
-note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
-  --> $DIR/fn-header-semantic-fail.rs:47:9
+note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+  --> $DIR/fn-header-semantic-fail.rs:45:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
-  --> $DIR/fn-header-semantic-fail.rs:47:9
+note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+  --> $DIR/fn-header-semantic-fail.rs:45:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5`...
-  --> $DIR/fn-header-semantic-fail.rs:47:9
+note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5`...
+  --> $DIR/fn-header-semantic-fail.rs:45:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze...
    = note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`...
-   = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 42:11>::fi5::{opaque#0}`, completing the cycle
+   = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`, completing the cycle
 note: cycle used when checking item types in top-level module
   --> $DIR/fn-header-semantic-fail.rs:5:1
    |
@@ -324,7 +296,7 @@ LL | |     }
 LL | | }
    | |_^
 
-error: aborting due to 23 previous errors
+error: aborting due to 21 previous errors
 
-Some errors have detailed explanations: E0053, E0379, E0391, E0706.
-For more information about an error, try `rustc --explain E0053`.
+Some errors have detailed explanations: E0379, E0391, E0706.
+For more information about an error, try `rustc --explain E0379`.
diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
index aaf0f7eaef0..49462f52fb4 100644
--- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
+++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
@@ -14,7 +14,6 @@ trait B {
 impl B for A {
     async fn associated(); //~ ERROR without body
     //~^ ERROR cannot be declared `async`
-    //~| ERROR has an incompatible type for trait
 }
 
 fn main() {}
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 d3214458eac..55c3b66f136 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
@@ -14,17 +14,6 @@ LL |     async fn inherent();
    |                        |
    |                        help: provide a definition for the function: `{ <body> }`
 
-error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:5
-   |
-LL |     async fn associated();
-   |     -----^^^^^^^^^^^^^^^^^
-   |     |
-   |     `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
-
 error: associated function in `impl` without body
   --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
    |
@@ -34,7 +23,7 @@ LL |     async fn associated();
    |                          help: provide a definition for the function: `{ <body> }`
 
 error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
+  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:5
    |
 LL |     async fn associated();
    |     -----^^^^^^^^^^^^^^^^^
@@ -43,26 +32,22 @@ 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
 
-error[E0053]: method `associated` has an incompatible type for trait
-  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:26
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
    |
 LL |     async fn associated();
-   |                          ^
-   |                          |
-   |                          checked the `Output` of this `async fn`, found opaque type
-   |                          expected `()`, found opaque type
-   |
-   = note: while checking the return type of the `async fn`
-note: type in trait
-  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:26
+   |     -----^^^^^^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
    |
-LL |     async fn associated();
-   |                          ^
-   = note: expected fn pointer `fn()`
-              found fn pointer `fn() -> impl Future<Output = ()>`
+   = 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
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0053, E0706.
-For more information about an error, try `rustc --explain E0053`.
+For more information about this error, try `rustc --explain E0706`.
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
index b280c8ab6e2..94f578af209 100644
--- a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs
@@ -12,7 +12,8 @@ impl A {
 
 trait C{async fn new(val: T) {} //~ ERROR  `async fn` is not permitted in Rust 2015
 //~^ ERROR functions in traits cannot be declared `async`
-//~^^ ERROR cannot find type `T` in this scope
-//~^^^ WARN changes to closure capture in Rust 2021 will affect drop order [rust_2021_incompatible_closure_captures]
+//~| ERROR mismatched types
+//~| ERROR cannot find type `T` in this scope
+//~| WARN changes to closure capture in Rust 2021 will affect drop order [rust_2021_incompatible_closure_captures]
 
 //~ ERROR  this file contains an unclosed delimiter
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 50de2322907..3814c568e72 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
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:18:53
+  --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:19:53
    |
 LL | trait C{async fn new(val: T) {}
    |        - unclosed delimiter
@@ -25,17 +25,6 @@ LL | trait C{async fn new(val: T) {}
    = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
-error[E0706]: functions in traits cannot be declared `async`
-  --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:9
-   |
-LL | trait C{async fn new(val: T) {}
-   |         -----^^^^^^^^^^^^^^^^^^
-   |         |
-   |         `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
-
 error[E0423]: expected function, found module `crate`
   --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:9:5
    |
@@ -51,6 +40,19 @@ LL | pub struct A {}
 LL | trait C{async fn new(val: T) {}
    |                           ^ help: a struct with a similar name exists: `A`
 
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:9
+   |
+LL | trait C{async fn new(val: T) {}
+   |         -----^^^^^^^^^^^^^^^
+   |         |
+   |         `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(return_position_impl_trait_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
    |
@@ -72,6 +74,20 @@ help: add a dummy let to cause `path` to be fully captured
 LL |     async fn create(path: impl AsRef<std::path::Path>)  { let _ = &path;
    |                                                           ++++++++++++++
 
+error[E0308]: mismatched types
+  --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30
+   |
+LL | trait C{async fn new(val: T) {}
+   |                              ^^ expected associated type, found opaque type
+   |
+  ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
+   |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |                                           ------------------------------- the found opaque type
+   |
+   = note: expected associated type `impl Future<Output = ()>` (trait associated opaque type at <$DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30>)
+                  found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+
 warning: changes to closure capture in Rust 2021 will affect drop order
   --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:13:30
    |
@@ -87,7 +103,7 @@ help: add a dummy let to cause `val` to be fully captured
 LL | trait C{async fn new(val: T) { let _ = &val;}
    |                                +++++++++++++
 
-error: aborting due to 6 previous errors; 2 warnings emitted
+error: aborting due to 7 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0412, E0423, E0670, E0706.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0308, E0412, E0423, E0670, E0706.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 573a7c016b8..5995675bd96 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -441,7 +441,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
 
     fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
         match ty.kind {
-            TyKind::OpaqueDef(item, bounds) => {
+            TyKind::OpaqueDef(item, bounds, _) => {
                 let map = self.cx.tcx.hir();
                 let item = map.item(item);
                 let len = self.lts.len();
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 2502c8f880d..754b0e78a14 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -103,7 +103,7 @@ fn future_trait_ref<'tcx>(
     ty: &'tcx Ty<'tcx>,
 ) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
     if_chain! {
-        if let TyKind::OpaqueDef(item_id, bounds) = ty.kind;
+        if let TyKind::OpaqueDef(item_id, bounds, false) = ty.kind;
         let item = cx.tcx.hir().item(item_id);
         if let ItemKind::OpaqueTy(opaque) = &item.kind;
         if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index ff23ed5fffa..f45cec9f0b4 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -987,8 +987,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 }
             },
             TyKind::Path(ref qpath) => self.hash_qpath(qpath),
-            TyKind::OpaqueDef(_, arg_list) => {
+            TyKind::OpaqueDef(_, arg_list, in_trait) => {
                 self.hash_generic_args(arg_list);
+                in_trait.hash(&mut self.s);
             },
             TyKind::TraitObject(_, lifetime, _) => {
                 self.hash_lifetime(*lifetime);