about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-12 21:03:47 +0000
committerbors <bors@rust-lang.org>2022-10-12 21:03:47 +0000
commit0938e1680daf66ca6aad428aedf9a920a0dab5ad (patch)
tree0635a662adb77e43b06a945a6a25ac4aefece490
parentc0983a9aac889d16722a12602ac678051e62c3fb (diff)
parent0eeeea9414d0ee5b22f6a33601282b46eca67bd6 (diff)
downloadrust-0938e1680daf66ca6aad428aedf9a920a0dab5ad.tar.gz
rust-0938e1680daf66ca6aad428aedf9a920a0dab5ad.zip
Auto merge of #101679 - compiler-errors:rpitit-default-body, r=nikomatsakis
Support default-body trait functions with return-position `impl Trait` in traits

Introduce a new `Trait` candidate kind for the `ImplTraitInTrait` projection candidate, which just projects an RPITIT down to its opaque type form.

This is a hack until we lower RPITITs to regular associated types, after which we will need to rework how these default bodies are type-checked, so comments are left in a few places for us to clean up later.

Fixes #101665
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs56
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs5
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs1
-rw-r--r--compiler/rustc_privacy/src/lib.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs48
-rw-r--r--src/test/ui/async-await/async-trait-fn.rs3
-rw-r--r--src/test/ui/async-await/async-trait-fn.stderr56
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.rs1
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr26
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs21
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr12
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body.rs21
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs1
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr22
14 files changed, 163 insertions, 126 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index f6f25603581..7cee9779c5f 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -522,23 +522,33 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
 
 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
 /// projections that would result in "inheriting lifetimes".
-pub(super) fn check_opaque<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    def_id: LocalDefId,
-    substs: SubstsRef<'tcx>,
-    origin: &hir::OpaqueTyOrigin,
-) {
-    let span = tcx.def_span(def_id);
-    check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
-    if tcx.type_of(def_id).references_error() {
+fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
+    let item = tcx.hir().item(id);
+    let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
+        tcx.sess.delay_span_bug(tcx.hir().span(id.hir_id()), "expected opaque item");
+        return;
+    };
+
+    // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
+    // `async-std` (and `pub async fn` in general).
+    // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
+    // See https://github.com/rust-lang/rust/issues/75100
+    if tcx.sess.opts.actually_rustdoc {
         return;
     }
-    if check_opaque_for_cycles(tcx, def_id, substs, span, origin).is_err() {
+
+    let substs = InternalSubsts::identity_for_item(tcx, item.def_id.to_def_id());
+    let span = tcx.def_span(item.def_id.def_id);
+
+    check_opaque_for_inheriting_lifetimes(tcx, item.def_id.def_id, span);
+    if tcx.type_of(item.def_id.def_id).references_error() {
+        return;
+    }
+    if check_opaque_for_cycles(tcx, item.def_id.def_id, substs, span, &origin).is_err() {
         return;
     }
-    check_opaque_meets_bounds(tcx, def_id, substs, span, origin);
+    check_opaque_meets_bounds(tcx, item.def_id.def_id, substs, span, &origin);
 }
-
 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
 /// in "inheriting lifetimes".
 #[instrument(level = "debug", skip(tcx, span))]
@@ -857,17 +867,17 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
             check_union(tcx, id.def_id.def_id);
         }
         DefKind::OpaqueTy => {
-            let item = tcx.hir().item(id);
-            let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
-                return;
-            };
-            // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
-            // `async-std` (and `pub async fn` in general).
-            // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
-            // See https://github.com/rust-lang/rust/issues/75100
-            if !tcx.sess.opts.actually_rustdoc {
-                let substs = InternalSubsts::identity_for_item(tcx, item.def_id.to_def_id());
-                check_opaque(tcx, item.def_id.def_id, substs, &origin);
+            check_opaque(tcx, id);
+        }
+        DefKind::ImplTraitPlaceholder => {
+            let parent = tcx.impl_trait_in_trait_parent(id.def_id.to_def_id());
+            // Only check the validity of this opaque type if the function has a default body
+            if let hir::Node::TraitItem(hir::TraitItem {
+                kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
+                ..
+            }) = tcx.hir().get_by_def_id(parent.expect_local())
+            {
+                check_opaque(tcx, id);
             }
         }
         DefKind::TyAlias => {
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 1b7ed60929d..0aa44431c79 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -340,10 +340,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     ..
                 }) => {
                     if in_trait {
-                        span_bug!(item.span, "impl-trait in trait has no default")
-                    } else {
-                        find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+                        assert!(tcx.impl_defaultness(owner).has_value());
                     }
+                    find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
                 }
                 ItemKind::Trait(..)
                 | ItemKind::TraitAlias(..)
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 2f6ec836c3c..64636963313 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1161,6 +1161,7 @@ impl<'tcx> ProjectionTy<'tcx> {
         tcx: TyCtxt<'tcx>,
     ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
         let def_id = tcx.parent(self.item_def_id);
+        assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
         let trait_generics = tcx.generics_of(def_id);
         (
             ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, trait_generics) },
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 0983c3148f2..e904fab4d76 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -122,8 +122,20 @@ where
         &mut self,
         projection: ty::ProjectionTy<'tcx>,
     ) -> ControlFlow<V::BreakTy> {
-        let (trait_ref, assoc_substs) =
-            projection.trait_ref_and_own_substs(self.def_id_visitor.tcx());
+        let tcx = self.def_id_visitor.tcx();
+        let (trait_ref, assoc_substs) = if tcx.def_kind(projection.item_def_id)
+            != DefKind::ImplTraitPlaceholder
+        {
+            projection.trait_ref_and_own_substs(tcx)
+        } else {
+            // HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
+            let def_id = tcx.impl_trait_in_trait_parent(projection.item_def_id);
+            let trait_generics = tcx.generics_of(def_id);
+            (
+                ty::TraitRef { def_id, substs: projection.substs.truncate_to(tcx, trait_generics) },
+                &projection.substs[trait_generics.count()..],
+            )
+        };
         self.visit_trait(trait_ref)?;
         if self.def_id_visitor.shallow() {
             ControlFlow::CONTINUE
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 511646b0eaf..cd1e9a97731 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -72,7 +72,15 @@ enum ProjectionCandidate<'tcx> {
     /// From an "impl" (or a "pseudo-impl" returned by select)
     Select(Selection<'tcx>),
 
-    ImplTraitInTrait(ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>),
+    ImplTraitInTrait(ImplTraitInTraitCandidate<'tcx>),
+}
+
+#[derive(PartialEq, Eq, Debug)]
+enum ImplTraitInTraitCandidate<'tcx> {
+    // The `impl Trait` from a trait function's default body
+    Trait,
+    // A concrete type provided from a trait's `impl Trait` from an impl
+    Impl(ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>),
 }
 
 enum ProjectionCandidateSet<'tcx> {
@@ -1319,6 +1327,19 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
     let tcx = selcx.tcx();
     if tcx.def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
         let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
+        // If we are trying to project an RPITIT with trait's default `Self` parameter,
+        // then we must be within a default trait body.
+        if obligation.predicate.self_ty()
+            == ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.item_def_id)
+                .type_at(0)
+            && tcx.associated_item(trait_fn_def_id).defaultness(tcx).has_value()
+        {
+            candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(
+                ImplTraitInTraitCandidate::Trait,
+            ));
+            return;
+        }
+
         let trait_def_id = tcx.parent(trait_fn_def_id);
         let trait_substs =
             obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
@@ -1330,7 +1351,9 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
         let _ =
             selcx.infcx().commit_if_ok(|_| match selcx.select(&obligation.with(trait_predicate)) {
                 Ok(Some(super::ImplSource::UserDefined(data))) => {
-                    candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data));
+                    candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(
+                        ImplTraitInTraitCandidate::Impl(data),
+                    ));
                     Ok(())
                 }
                 Ok(None) => {
@@ -1792,9 +1815,18 @@ fn confirm_candidate<'cx, 'tcx>(
         ProjectionCandidate::Select(impl_source) => {
             confirm_select_candidate(selcx, obligation, impl_source)
         }
-        ProjectionCandidate::ImplTraitInTrait(data) => {
+        ProjectionCandidate::ImplTraitInTrait(ImplTraitInTraitCandidate::Impl(data)) => {
             confirm_impl_trait_in_trait_candidate(selcx, obligation, data)
         }
+        // If we're projecting an RPITIT for a default trait body, that's just
+        // the same def-id, but as an opaque type (with regular RPIT semantics).
+        ProjectionCandidate::ImplTraitInTrait(ImplTraitInTraitCandidate::Trait) => Progress {
+            term: selcx
+                .tcx()
+                .mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
+                .into(),
+            obligations: vec![],
+        },
     };
 
     // When checking for cycle during evaluation, we compare predicates with
@@ -2211,6 +2243,16 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
         return Progress { term: tcx.ty_error().into(), obligations };
     }
 
+    // Use the default `impl Trait` for the trait, e.g., for a default trait body
+    if leaf_def.item.container == ty::AssocItemContainer::TraitContainer {
+        return Progress {
+            term: tcx
+                .mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
+                .into(),
+            obligations,
+        };
+    }
+
     let impl_fn_def_id = leaf_def.item.def_id;
     let impl_fn_substs = obligation.predicate.substs.rebase_onto(tcx, trait_fn_def_id, data.substs);
 
diff --git a/src/test/ui/async-await/async-trait-fn.rs b/src/test/ui/async-await/async-trait-fn.rs
index 0ea685986db..e2062e82725 100644
--- a/src/test/ui/async-await/async-trait-fn.rs
+++ b/src/test/ui/async-await/async-trait-fn.rs
@@ -1,11 +1,8 @@
 // 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 4fa54c6e369..afbe25cf7ab 100644
--- a/src/test/ui/async-await/async-trait-fn.stderr
+++ b/src/test/ui/async-await/async-trait-fn.stderr
@@ -12,7 +12,7 @@ LL |     async fn foo() {}
    = 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
+  --> $DIR/async-trait-fn.rs:4:5
    |
 LL |     async fn bar(&self) {}
    |     -----^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     async fn bar(&self) {}
    = 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
+  --> $DIR/async-trait-fn.rs:5:5
    |
 LL |     async fn baz() {
    |     -----^^^^^^^^^
@@ -37,54 +37,6 @@ LL |     async fn baz() {
    = 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[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() {
-   |  ____________________^
-LL | |
-LL | |         // Nested item must not ICE.
-LL | |         fn a() {}
-LL | |     }
-   | |_____^ 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:7:20>)
-                  found opaque type `impl Future<Output = ()>` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
-
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0308, E0706.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0706`.
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 22a61dcd25f..6bd6d879a4a 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
@@ -17,7 +17,6 @@ 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 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 62a243e69e7..ba918eb28de 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:37:9
+  --> $DIR/edition-deny-async-fns-2015.rs:36: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:27:9
+  --> $DIR/edition-deny-async-fns-2015.rs:26: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:32:13
+  --> $DIR/edition-deny-async-fns-2015.rs:31:13
    |
 LL |             async fn bar() {}
    |             ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -92,21 +92,7 @@ LL |     async fn foo() {}
    = 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[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
+error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0308, E0670, E0706.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0670, E0706.
+For more information about an error, try `rustc --explain E0670`.
diff --git a/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
new file mode 100644
index 00000000000..f0d407cd527
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
@@ -0,0 +1,21 @@
+// known-bug: #102688
+// edition:2021
+
+#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {
+    async fn baz(&self) -> impl Debug {
+        ""
+    }
+}
+
+struct Bar;
+
+impl Foo for Bar {}
+
+fn main() {
+    let _ = Bar.baz();
+}
diff --git a/src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr
new file mode 100644
index 00000000000..4529d301f9e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr
@@ -0,0 +1,12 @@
+error[E0720]: cannot resolve opaque type
+  --> $DIR/default-body-with-rpit.rs:10:28
+   |
+LL |     async fn baz(&self) -> impl Debug {
+   |                            ^^^^^^^^^^ cannot resolve opaque type
+   |
+   = note: these returned values have a concrete "never" type
+   = help: this error will resolve once the item's body returns a concrete type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/in-trait/default-body.rs b/src/test/ui/impl-trait/in-trait/default-body.rs
new file mode 100644
index 00000000000..b0baf5bb10d
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body.rs
@@ -0,0 +1,21 @@
+// check-pass
+// edition:2021
+
+#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {
+    async fn baz(&self) -> &str {
+        ""
+    }
+}
+
+struct Bar;
+
+impl Foo for Bar {}
+
+fn main() {
+    let _ = Bar.baz();
+}
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 94f578af209..4559da91e47 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,6 @@ 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 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]
 
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 386385165f6..df1cafdb7d3 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:19:53
+  --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.rs:18:53
    |
 LL | trait C{async fn new(val: T) {}
    |        - unclosed delimiter
@@ -74,20 +74,6 @@ 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
    |
@@ -103,7 +89,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 7 previous errors; 2 warnings emitted
+error: aborting due to 6 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0308, E0412, E0423, E0670, E0706.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0412, E0423, E0670, E0706.
+For more information about an error, try `rustc --explain E0412`.