about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-02-17 13:28:06 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-03-28 16:57:45 +0000
commit1163aa7e72bc69b76cb68177fa4f83a66a6034cc (patch)
treec3ffe7ad686652f0fb9643350bd3c2d1fc1d803e
parent86e1860495403ee0154608e51fe4b4d81203e15f (diff)
downloadrust-1163aa7e72bc69b76cb68177fa4f83a66a6034cc.tar.gz
rust-1163aa7e72bc69b76cb68177fa4f83a66a6034cc.zip
Remove opaque type obligation and just register opaque types as they are encountered.
This also registers obligations for the hidden type immediately.
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs21
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs23
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs18
-rw-r--r--compiler/rustc_infer/src/infer/lattice.rs12
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs112
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs12
-rw-r--r--compiler/rustc_infer/src/traits/util.rs3
-rw-r--r--compiler/rustc_lint/src/builtin.rs1
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs3
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs6
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs4
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs4
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs1
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs1
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs13
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs1
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs1
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs1
-rw-r--r--compiler/rustc_typeck/src/outlives/explicit.rs1
-rw-r--r--src/librustdoc/clean/mod.rs1
-rw-r--r--src/test/ui/async-await/suggest-missing-await.rs1
-rw-r--r--src/test/ui/async-await/suggest-missing-await.stderr27
-rw-r--r--src/test/ui/cast/casts-differing-anon.rs2
-rw-r--r--src/test/ui/cast/casts-differing-anon.stderr16
-rw-r--r--src/test/ui/conservative_impl_trait.rs1
-rw-r--r--src/test/ui/conservative_impl_trait.stderr14
-rw-r--r--src/test/ui/impl-trait/autoderef.rs19
-rw-r--r--src/test/ui/impl-trait/cross-return-site-inference.rs2
-rw-r--r--src/test/ui/impl-trait/equality2.stderr4
-rw-r--r--src/test/ui/impl-trait/issues/issue-70877.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-70877.stderr11
-rw-r--r--src/test/ui/impl-trait/projection.rs2
-rw-r--r--src/test/ui/impl-trait/question_mark.rs2
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs1
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr9
-rw-r--r--src/test/ui/impl-trait/two_tait_defining_each_other2.rs2
-rw-r--r--src/test/ui/impl-trait/two_tait_defining_each_other2.stderr10
-rw-r--r--src/test/ui/issues-71798.rs1
-rw-r--r--src/test/ui/issues-71798.stderr18
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.rs2
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr82
-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.stderr14
-rw-r--r--src/test/ui/suggestions/match-prev-arm-needing-semi.rs9
-rw-r--r--src/test/ui/suggestions/match-prev-arm-needing-semi.stderr27
-rw-r--r--src/test/ui/suggestions/opaque-type-error.stderr7
-rw-r--r--src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr8
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs1
60 files changed, 290 insertions, 311 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 3ee0aafebfd..9d7dcc5379c 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2646,7 +2646,7 @@ impl NormalizeLocation for Location {
 pub(super) struct InstantiateOpaqueType<'tcx> {
     pub base_universe: Option<ty::UniverseIndex>,
     pub region_constraints: Option<RegionConstraintData<'tcx>>,
-    pub obligation: PredicateObligation<'tcx>,
+    pub obligations: Vec<PredicateObligation<'tcx>>,
 }
 
 impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
@@ -2660,7 +2660,7 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
 
     fn fully_perform(mut self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
         let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
-            Ok(InferOk { value: (), obligations: vec![self.obligation.clone()] })
+            Ok(InferOk { value: (), obligations: self.obligations.clone() })
         })?;
         self.region_constraints = Some(region_constraints);
         output.error_info = Some(self);
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index a032095bf98..8a757636087 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -2,6 +2,7 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
 use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::mir::ConstraintCategory;
+use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::{self, Const, Ty};
 use rustc_span::Span;
@@ -136,7 +137,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
         true
     }
 
-    fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
+    fn register_opaque_type(
+        &mut self,
+        a: Ty<'tcx>,
+        b: Ty<'tcx>,
+        a_is_expected: bool,
+    ) -> Result<(), TypeError<'tcx>> {
         let param_env = self.param_env();
         let span = self.span();
         let def_id = self.type_checker.body.source.def_id().expect_local();
@@ -147,18 +153,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
                 self.locations,
                 self.category,
                 InstantiateOpaqueType {
-                    obligation: self.type_checker.infcx.opaque_ty_obligation(
-                        a,
-                        b,
-                        a_is_expected,
-                        param_env,
-                        cause,
-                    ),
+                    obligations: self
+                        .type_checker
+                        .infcx
+                        .handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
+                        .obligations,
                     // These fields are filled in during exectuion of the operation
                     base_universe: None,
                     region_constraints: None,
                 },
             )
             .unwrap();
+        Ok(())
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 20f65962db4..750643acdda 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_index::vec::Idx;
 use rustc_index::vec::IndexVec;
 use rustc_middle::arena::ArenaAllocatable;
+use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
@@ -499,7 +500,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
         for &(a, b) in &query_response.value.opaque_types {
             let a = substitute_value(self.tcx, &result_subst, a);
             let b = substitute_value(self.tcx, &result_subst, b);
-            obligations.extend(self.handle_opaque_type(a, b, cause, param_env)?.obligations);
+            obligations.extend(self.handle_opaque_type(a, b, true, cause, param_env)?.obligations);
         }
 
         Ok(InferOk { value: result_subst, obligations })
@@ -718,13 +719,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
         true
     }
 
-    fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
-        self.obligations.push(self.infcx.opaque_ty_obligation(
-            a,
-            b,
-            a_is_expected,
-            self.param_env,
-            self.cause.clone(),
-        ));
+    fn register_opaque_type(
+        &mut self,
+        a: Ty<'tcx>,
+        b: Ty<'tcx>,
+        a_is_expected: bool,
+    ) -> Result<(), TypeError<'tcx>> {
+        self.obligations.extend(
+            self.infcx
+                .handle_opaque_type(a, b, a_is_expected, &self.cause, self.param_env)?
+                .obligations,
+        );
+        Ok(())
     }
 }
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index c1c075e9a4c..65c0eba4b3d 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -98,13 +98,17 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
             (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
                 if self.fields.define_opaque_types && did.is_local() =>
             {
-                self.fields.obligations.push(infcx.opaque_ty_obligation(
-                    a,
-                    b,
-                    self.a_is_expected(),
-                    self.param_env(),
-                    self.fields.trace.cause.clone(),
-                ));
+                self.fields.obligations.extend(
+                    infcx
+                        .handle_opaque_type(
+                            a,
+                            b,
+                            self.a_is_expected(),
+                            &self.fields.trace.cause,
+                            self.param_env(),
+                        )?
+                        .obligations,
+                );
             }
 
             _ => {
diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs
index f4c749492d3..b77245c2592 100644
--- a/compiler/rustc_infer/src/infer/lattice.rs
+++ b/compiler/rustc_infer/src/infer/lattice.rs
@@ -111,13 +111,11 @@ where
         (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
             if this.define_opaque_types() && did.is_local() =>
         {
-            this.add_obligations(vec![infcx.opaque_ty_obligation(
-                a,
-                b,
-                this.a_is_expected(),
-                this.param_env(),
-                this.cause().clone(),
-            )]);
+            this.add_obligations(
+                infcx
+                    .handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
+                    .obligations,
+            );
             Ok(a)
         }
 
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 2c7f3adafdc..cc0114d7538 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -91,7 +91,12 @@ pub trait TypeRelatingDelegate<'tcx> {
     );
 
     fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
-    fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool);
+    fn register_opaque_type(
+        &mut self,
+        a: Ty<'tcx>,
+        b: Ty<'tcx>,
+        a_is_expected: bool,
+    ) -> Result<(), TypeError<'tcx>>;
 
     /// Creates a new universe index. Used when instantiating placeholders.
     fn create_next_universe(&mut self) -> ty::UniverseIndex;
@@ -590,7 +595,7 @@ where
                     (_, &ty::Opaque(..)) => (generalize(a, true)?, b),
                     _ => unreachable!(),
                 };
-                self.delegate.register_opaque_type(a, b, true);
+                self.delegate.register_opaque_type(a, b, true)?;
                 trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
                 Ok(a)
             }
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index ce922bca356..b2f62637cf2 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -1,5 +1,5 @@
 use crate::infer::{InferCtxt, InferOk};
-use crate::traits::{self, PredicateObligation};
+use crate::traits;
 use hir::def_id::{DefId, LocalDefId};
 use hir::OpaqueTyOrigin;
 use rustc_data_structures::sync::Lrc;
@@ -42,25 +42,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         &self,
         a: Ty<'tcx>,
         b: Ty<'tcx>,
+        a_is_expected: bool,
         cause: &ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> InferResult<'tcx, ()> {
         if a.references_error() || b.references_error() {
             return Ok(InferOk { value: (), obligations: vec![] });
         }
-        if self.defining_use_anchor.is_some() {
-            let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
-                ty::Opaque(def_id, substs) => {
-                    if let ty::Opaque(did2, _) = *b.kind() {
-                        // We could accept this, but there are various ways to handle this situation, and we don't
-                        // want to make a decision on it right now. Likely this case is so super rare anyway, that
-                        // no one encounters it in practice.
-                        // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
-                        // where it is of no concern, so we only check for TAITs.
-                        if let Some(OpaqueTyOrigin::TyAlias) =
-                            self.opaque_type_origin(did2, cause.span)
-                        {
-                            self.tcx
+        let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
+        let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
+            ty::Opaque(def_id, substs) => {
+                if let ty::Opaque(did2, _) = *b.kind() {
+                    // We could accept this, but there are various ways to handle this situation, and we don't
+                    // want to make a decision on it right now. Likely this case is so super rare anyway, that
+                    // no one encounters it in practice.
+                    // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
+                    // where it is of no concern, so we only check for TAITs.
+                    if let Some(OpaqueTyOrigin::TyAlias) = self.opaque_type_origin(did2, cause.span)
+                    {
+                        self.tcx
                                 .sess
                                 .struct_span_err(
                                     cause.span,
@@ -76,13 +76,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                     "opaque type being used as hidden type",
                                 )
                                 .emit();
-                        }
                     }
-                    Some(self.register_hidden_type(
-                        OpaqueTypeKey { def_id, substs },
-                        cause.clone(),
-                        param_env,
-                        b,
+                }
+                Some(self.register_hidden_type(
+                    OpaqueTypeKey { def_id, substs },
+                    cause.clone(),
+                    param_env,
+                    b,
+                    if self.defining_use_anchor.is_some() {
                         // Check that this is `impl Trait` type is
                         // declared by `parent_def_id` -- i.e., one whose
                         // value we are inferring.  At present, this is
@@ -117,47 +118,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         //     let x = || foo(); // returns the Opaque assoc with `foo`
                         // }
                         // ```
-                        self.opaque_type_origin(def_id, cause.span)?,
-                    ))
-                }
-                _ => None,
-            };
-            if let Some(res) = process(a, b) {
-                res
-            } else if let Some(res) = process(b, a) {
-                res
-            } else {
-                // Rerun equality check, but this time error out due to
-                // different types.
-                match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
-                    Ok(_) => span_bug!(
-                        cause.span,
-                        "opaque types are never equal to anything but themselves: {:#?}",
-                        (a.kind(), b.kind())
-                    ),
-                    Err(e) => Err(e),
-                }
+                        self.opaque_type_origin(def_id, cause.span)?
+                    } else {
+                        self.opaque_ty_origin_unchecked(def_id, cause.span)
+                    },
+                ))
             }
+            _ => None,
+        };
+        if let Some(res) = process(a, b) {
+            res
+        } else if let Some(res) = process(b, a) {
+            res
         } else {
-            let (opaque_type, hidden_ty) = match (a.kind(), b.kind()) {
-                (ty::Opaque(..), _) => (a, b),
-                (_, ty::Opaque(..)) => (b, a),
-                types => span_bug!(
+            // Rerun equality check, but this time error out due to
+            // different types.
+            match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
+                Ok(_) => span_bug!(
                     cause.span,
-                    "opaque type obligations only work for opaque types: {:#?}",
-                    types
+                    "opaque types are never equal to anything but themselves: {:#?}",
+                    (a.kind(), b.kind())
                 ),
-            };
-            let key = opaque_type.expect_opaque_type();
-            let origin = self.opaque_ty_origin_unchecked(key.def_id, cause.span);
-            let prev = self.inner.borrow_mut().opaque_types().register(
-                key,
-                OpaqueHiddenType { ty: hidden_ty, span: cause.span },
-                origin,
-            );
-            match prev {
-                Some(prev) => self.at(cause, param_env).eq(prev, hidden_ty),
-                None => Ok(InferOk { value: (), obligations: vec![] }),
+                Err(e) => Err(e),
             }
         }
     }
@@ -363,22 +345,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         });
     }
 
-    pub fn opaque_ty_obligation(
-        &self,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-        a_is_expected: bool,
-        param_env: ty::ParamEnv<'tcx>,
-        cause: ObligationCause<'tcx>,
-    ) -> PredicateObligation<'tcx> {
-        let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
-        PredicateObligation::new(
-            cause,
-            param_env,
-            self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::OpaqueType(a, b))),
-        )
-    }
-
     #[instrument(skip(self), level = "trace")]
     pub fn opaque_type_origin(&self, opaque_def_id: DefId, span: Span) -> Option<OpaqueTyOrigin> {
         let def_id = opaque_def_id.as_local()?;
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index b60ffc1878b..03d6c45a653 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -28,7 +28,6 @@ pub fn explicit_outlives_bounds<'tcx>(
             | ty::PredicateKind::TypeOutlives(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..)
-            | ty::PredicateKind::OpaqueType(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
             ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
                 Some(OutlivesBound::RegionSubRegion(r_b, r_a))
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 85bae8b823b..3600b54a271 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -146,13 +146,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
                     (_, &ty::Opaque(..)) => (generalize(a, false)?, b),
                     _ => unreachable!(),
                 };
-                self.fields.obligations.push(infcx.opaque_ty_obligation(
-                    a,
-                    b,
-                    true,
-                    self.param_env(),
-                    self.fields.trace.cause.clone(),
-                ));
+                self.fields.obligations.extend(
+                    infcx
+                        .handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())?
+                        .obligations,
+                );
                 Ok(a)
             }
 
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 6600d5e4d02..674c75fdee5 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -167,9 +167,6 @@ impl<'tcx> Elaborator<'tcx> {
                 // Currently, we do not elaborate WF predicates,
                 // although we easily could.
             }
-            ty::PredicateKind::OpaqueType(..) => {
-                todo!("{:#?}", obligation)
-            }
             ty::PredicateKind::ObjectSafe(..) => {
                 // Currently, we do not elaborate object-safe
                 // predicates.
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index cec32823ee2..50a3df21a3b 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1675,7 +1675,6 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
                     Coerce(..) |
                     ConstEvaluatable(..) |
                     ConstEquate(..) |
-                    OpaqueType(..) |
                     TypeWellFormedFromEnv(..) => continue,
                 };
                 if predicate.is_global() {
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 06ac21e5d57..7a3d615862c 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -265,10 +265,6 @@ impl FlagComputation {
             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
                 self.add_ty(ty);
             }
-            ty::PredicateKind::OpaqueType(opaque, ty) => {
-                self.add_ty(opaque);
-                self.add_ty(ty);
-            }
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 069cf32e515..44c190e459c 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -632,11 +632,6 @@ pub enum PredicateKind<'tcx> {
     ///
     /// Only used for Chalk.
     TypeWellFormedFromEnv(Ty<'tcx>),
-
-    /// Represents a hidden type assignment for an opaque type.
-    /// Such obligations get processed by checking whether the item currently being
-    /// type-checked may acually define it.
-    OpaqueType(Ty<'tcx>, Ty<'tcx>),
 }
 
 /// The crate outlives map is computed during typeck and contains the
@@ -1004,7 +999,6 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::TypeOutlives(..)
             | PredicateKind::ConstEvaluatable(..)
             | PredicateKind::ConstEquate(..)
-            | PredicateKind::OpaqueType(..)
             | PredicateKind::TypeWellFormedFromEnv(..) => None,
         }
     }
@@ -1023,7 +1017,6 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::ClosureKind(..)
             | PredicateKind::ConstEvaluatable(..)
             | PredicateKind::ConstEquate(..)
-            | PredicateKind::OpaqueType(..)
             | PredicateKind::TypeWellFormedFromEnv(..) => None,
         }
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index d5f5a1572b8..fecc5d805fc 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2654,9 +2654,6 @@ define_print_and_forward_display! {
             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
                 p!("the type `", print(ty), "` is found in the environment")
             }
-            ty::PredicateKind::OpaqueType(a, b) => {
-                p!("opaque type assigment with `", print(a), "` == `", print(b) ,"`")
-            }
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 576f4121c42..5c7910db362 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -198,9 +198,6 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
                 write!(f, "TypeWellFormedFromEnv({:?})", ty)
             }
-            ty::PredicateKind::OpaqueType(a, b) => {
-                write!(f, "OpaqueType({:?}, {:?})", a.kind(), b.kind())
-            }
         }
     }
 }
@@ -474,9 +471,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
                 tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv)
             }
-            ty::PredicateKind::OpaqueType(opaque, ty) => {
-                Some(ty::PredicateKind::OpaqueType(tcx.lift(opaque)?, tcx.lift(ty)?))
-            }
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index eb70de48368..06287f00fad 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -352,7 +352,6 @@ crate fn required_region_bounds<'tcx>(
                 | ty::PredicateKind::RegionOutlives(..)
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::ConstEquate(..)
-                | ty::PredicateKind::OpaqueType(..)
                 | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
                 ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
                     // Search for a bound of the form `erased_self_ty
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index ee8b3a62453..ee9983ee8b8 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -865,7 +865,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                 | ty::PredicateKind::Subtype(..)
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::Coerce(..)
-                | ty::PredicateKind::OpaqueType(..)
                 | ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
             };
         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 218abdd573d..468c7a3c55b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -797,10 +797,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         span,
                         "TypeWellFormedFromEnv predicate should only exist in the environment"
                     ),
-
-                    ty::PredicateKind::OpaqueType(..) => {
-                        todo!("{:#?}", obligation);
-                    }
                 }
             }
 
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index d55d06ebbf4..1b862834467 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -413,9 +413,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                 ty::PredicateKind::TypeWellFormedFromEnv(..) => {
                     bug!("TypeWellFormedFromEnv is only used for Chalk")
                 }
-                ty::PredicateKind::OpaqueType(..) => {
-                    todo!("{:#?}", obligation);
-                }
             },
             Some(pred) => match pred {
                 ty::PredicateKind::Trait(data) => {
@@ -665,20 +662,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                 ty::PredicateKind::TypeWellFormedFromEnv(..) => {
                     bug!("TypeWellFormedFromEnv is only used for Chalk")
                 }
-                ty::PredicateKind::OpaqueType(a, b) => {
-                    match self.selcx.infcx().handle_opaque_type(
-                        a,
-                        b,
-                        &obligation.cause,
-                        obligation.param_env,
-                    ) {
-                        Ok(value) => ProcessResult::Changed(mk_pending(value.obligations)),
-                        Err(err) => ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
-                            ExpectedFound::new(true, a, b),
-                            err,
-                        )),
-                    }
-                }
             },
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index eab207600ab..6cceec86213 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -313,7 +313,6 @@ fn predicate_references_self<'tcx>(
         | ty::PredicateKind::Coerce(..)
         | ty::PredicateKind::ConstEvaluatable(..)
         | ty::PredicateKind::ConstEquate(..)
-        | ty::PredicateKind::OpaqueType(..)
         | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
     }
 }
@@ -345,7 +344,6 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
             | ty::PredicateKind::TypeOutlives(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..)
-            | ty::PredicateKind::OpaqueType(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => false,
         }
     })
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 76526df6461..42f17721f9b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -673,19 +673,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ty::PredicateKind::TypeWellFormedFromEnv(..) => {
                     bug!("TypeWellFormedFromEnv is only used for chalk")
                 }
-                ty::PredicateKind::OpaqueType(a, b) => {
-                    match self.infcx().handle_opaque_type(
-                        a,
-                        b,
-                        &obligation.cause,
-                        obligation.param_env,
-                    ) {
-                        Ok(res) => {
-                            self.evaluate_predicates_recursively(previous_stack, res.obligations)
-                        }
-                        Err(_) => Ok(EvaluatedToErr),
-                    }
-                }
             }
         });
 
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 2ac68cea544..b4ed5b95b10 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -148,10 +148,6 @@ pub fn predicate_obligations<'a, 'tcx>(
             wf.compute(c1.into());
             wf.compute(c2.into());
         }
-        ty::PredicateKind::OpaqueType(opaque, ty) => {
-            wf.compute(opaque.into());
-            wf.compute(ty.into());
-        }
         ty::PredicateKind::TypeWellFormedFromEnv(..) => {
             bug!("TypeWellFormedFromEnv is only used for Chalk")
         }
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 1d5b5c6c3cd..e3c865ce9e6 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -110,7 +110,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                 | ty::PredicateKind::ClosureKind(..)
                 | ty::PredicateKind::Subtype(..)
                 | ty::PredicateKind::Coerce(..)
-                | ty::PredicateKind::OpaqueType(..)
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
             };
@@ -203,7 +202,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
             ty::PredicateKind::ClosureKind(..)
             | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::ConstEvaluatable(..)
-            | ty::PredicateKind::OpaqueType(..)
             | ty::PredicateKind::ConstEquate(..) => {
                 chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
             }
@@ -623,7 +621,6 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
             | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..)
-            | ty::PredicateKind::OpaqueType(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => {
                 bug!("unexpected predicate {}", &self)
             }
@@ -753,7 +750,6 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
             | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..)
-            | ty::PredicateKind::OpaqueType(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => {
                 bug!("unexpected predicate {}", &self)
             }
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 1535a46a01b..90c698db8fb 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -105,7 +105,6 @@ fn compute_implied_outlives_bounds<'tcx>(
                     | ty::PredicateKind::ObjectSafe(..)
                     | ty::PredicateKind::ConstEvaluatable(..)
                     | ty::PredicateKind::ConstEquate(..)
-                    | ty::PredicateKind::OpaqueType(..)
                     | ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![],
                     ty::PredicateKind::WellFormed(arg) => {
                         wf_args.push(arg);
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 1d26f6a12a3..a4aa965ec95 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -69,7 +69,6 @@ fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {
         | ty::PredicateKind::Coerce(..)
         | ty::PredicateKind::ConstEvaluatable(..)
         | ty::PredicateKind::ConstEquate(..)
-        | ty::PredicateKind::OpaqueType(..)
         | ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
     }
 }
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 83ef76a48cd..709622edb76 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -661,13 +661,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         span,
                     });
                     let cause = ObligationCause::misc(span, body_id);
-                    self.register_predicates(vec![self.infcx.opaque_ty_obligation(
-                        ty,
-                        ty_var,
-                        true,
-                        self.param_env,
-                        cause,
-                    )]);
+                    self.register_predicates(
+                        self.infcx
+                            .handle_opaque_type(ty, ty_var, true, &cause, self.param_env)
+                            .unwrap()
+                            .obligations,
+                    );
                     ty_var
                 }
                 _ => ty,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 83587951f25..6e3013cde7b 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -732,7 +732,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // inference variable.
                     ty::PredicateKind::ClosureKind(..) => None,
                     ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
-                    ty::PredicateKind::OpaqueType(..) => None,
                 }
             })
             .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 26119e5a064..abdce9f5866 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -858,7 +858,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 | ty::PredicateKind::TypeOutlives(..)
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::ConstEquate(..)
-                | ty::PredicateKind::OpaqueType(..)
                 | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
             }
         });
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index 737e6002005..6cef3e9d940 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -425,7 +425,6 @@ fn trait_predicate_kind<'tcx>(
         | ty::PredicateKind::ClosureKind(..)
         | ty::PredicateKind::ConstEvaluatable(..)
         | ty::PredicateKind::ConstEquate(..)
-        | ty::PredicateKind::OpaqueType(..)
         | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
     }
 }
diff --git a/compiler/rustc_typeck/src/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs
index 7839ce5e4ff..bbf31de527e 100644
--- a/compiler/rustc_typeck/src/outlives/explicit.rs
+++ b/compiler/rustc_typeck/src/outlives/explicit.rs
@@ -59,7 +59,6 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
                     | ty::PredicateKind::Coerce(..)
                     | ty::PredicateKind::ConstEvaluatable(..)
                     | ty::PredicateKind::ConstEquate(..)
-                    | ty::PredicateKind::OpaqueType(..)
                     | ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
                 }
             }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5256fe76248..1e3260ce9ae 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -306,7 +306,6 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
             | ty::PredicateKind::ObjectSafe(..)
             | ty::PredicateKind::ClosureKind(..)
             | ty::PredicateKind::ConstEquate(..)
-            | ty::PredicateKind::OpaqueType(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
         }
     }
diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs
index 046f1dfea32..796f82e779c 100644
--- a/src/test/ui/async-await/suggest-missing-await.rs
+++ b/src/test/ui/async-await/suggest-missing-await.rs
@@ -22,6 +22,7 @@ async fn suggest_await_in_async_fn_return() {
     dummy()
     //~^ ERROR mismatched types [E0308]
     //~| HELP consider `await`ing on the `Future`
+    //~| HELP consider using a semicolon here
     //~| SUGGESTION .await
 }
 
diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr
index 07d6f8986fa..76073c4c879 100644
--- a/src/test/ui/async-await/suggest-missing-await.stderr
+++ b/src/test/ui/async-await/suggest-missing-await.stderr
@@ -33,9 +33,13 @@ help: consider `await`ing on the `Future`
    |
 LL |     dummy().await
    |            ++++++
+help: consider using a semicolon here
+   |
+LL |     dummy();
+   |            +
 
 error[E0308]: `if` and `else` have incompatible types
-  --> $DIR/suggest-missing-await.rs:34:9
+  --> $DIR/suggest-missing-await.rs:35:9
    |
 LL |       let _x = if true {
    |  ______________-
@@ -49,20 +53,15 @@ LL | |
 LL | |     };
    | |_____- `if` and `else` have incompatible types
    |
-note: while checking the return type of the `async fn`
-  --> $DIR/suggest-missing-await.rs:18:18
-   |
-LL | async fn dummy() {}
-   |                  ^ checked the `Output` of this `async fn`, expected opaque type
-   = note: expected opaque type `impl Future<Output = ()>`
-                found unit type `()`
+   = note:   expected type `impl Future<Output = ()>`
+           found unit type `()`
 help: consider `await`ing on the `Future`
    |
 LL |         dummy().await
    |                ++++++
 
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/suggest-missing-await.rs:44:14
+  --> $DIR/suggest-missing-await.rs:45:14
    |
 LL |       let _x = match 0usize {
    |  ______________-
@@ -90,7 +89,7 @@ LL ~         1 => dummy().await,
    |
 
 error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await.rs:52:9
+  --> $DIR/suggest-missing-await.rs:53:9
    |
 LL |     let _x = match dummy() {
    |                    ------- this expression has type `impl Future<Output = ()>`
@@ -110,7 +109,7 @@ LL |     let _x = match dummy().await {
    |                           ++++++
 
 error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await.rs:66:9
+  --> $DIR/suggest-missing-await.rs:67:9
    |
 LL |     match dummy_result() {
    |           -------------- this expression has type `impl Future<Output = Result<(), ()>>`
@@ -119,7 +118,7 @@ LL |         Ok(_) => {}
    |         ^^^^^ expected opaque type, found enum `Result`
    |
 note: while checking the return type of the `async fn`
-  --> $DIR/suggest-missing-await.rs:56:28
+  --> $DIR/suggest-missing-await.rs:57:28
    |
 LL | async fn dummy_result() -> Result<(), ()> {
    |                            ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type
@@ -131,7 +130,7 @@ LL |     match dummy_result().await {
    |                         ++++++
 
 error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await.rs:68:9
+  --> $DIR/suggest-missing-await.rs:69:9
    |
 LL |     match dummy_result() {
    |           -------------- this expression has type `impl Future<Output = Result<(), ()>>`
@@ -140,7 +139,7 @@ LL |         Err(_) => {}
    |         ^^^^^^ expected opaque type, found enum `Result`
    |
 note: while checking the return type of the `async fn`
-  --> $DIR/suggest-missing-await.rs:56:28
+  --> $DIR/suggest-missing-await.rs:57:28
    |
 LL | async fn dummy_result() -> Result<(), ()> {
    |                            ^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type
diff --git a/src/test/ui/cast/casts-differing-anon.rs b/src/test/ui/cast/casts-differing-anon.rs
index ccf41adce6b..d4a0f961305 100644
--- a/src/test/ui/cast/casts-differing-anon.rs
+++ b/src/test/ui/cast/casts-differing-anon.rs
@@ -18,5 +18,5 @@ fn main() {
     // this is an `*mut fmt::Debug` in practice
     let mut b_raw = Box::into_raw(b);
     // ... and they should not be mixable
-    b_raw = f_raw as *mut _; //~ ERROR mismatched types
+    b_raw = f_raw as *mut _; //~ ERROR is invalid
 }
diff --git a/src/test/ui/cast/casts-differing-anon.stderr b/src/test/ui/cast/casts-differing-anon.stderr
index 2d08903c5ef..f9abfb5225f 100644
--- a/src/test/ui/cast/casts-differing-anon.stderr
+++ b/src/test/ui/cast/casts-differing-anon.stderr
@@ -1,19 +1,11 @@
-error[E0308]: mismatched types
+error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` is invalid
   --> $DIR/casts-differing-anon.rs:21:13
    |
-LL | fn foo() -> Box<impl fmt::Debug+?Sized> {
-   |                 ---------------------- the found opaque type
-...
-LL | fn bar() -> Box<impl fmt::Debug+?Sized> {
-   |                 ---------------------- the expected opaque type
-...
 LL |     b_raw = f_raw as *mut _;
-   |             ^^^^^ expected opaque type, found a different opaque type
+   |             ^^^^^^^^^^^^^^^
    |
-   = note: expected opaque type `impl Debug + ?Sized` (opaque type at <$DIR/casts-differing-anon.rs:7:17>)
-              found opaque type `impl Debug + ?Sized` (opaque type at <$DIR/casts-differing-anon.rs:3:17>)
-   = note: distinct uses of `impl Trait` result in different opaque types
+   = note: vtable kinds may not match
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0606`.
diff --git a/src/test/ui/conservative_impl_trait.rs b/src/test/ui/conservative_impl_trait.rs
index b7f795eadb7..b8488d83998 100644
--- a/src/test/ui/conservative_impl_trait.rs
+++ b/src/test/ui/conservative_impl_trait.rs
@@ -2,6 +2,7 @@
 
 fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
     //~^ ERROR `()` is not an iterator
+    //~| ERROR `()` is not an iterator
 }
 
 fn main() {}
diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr
index 63a4df242f8..2348f2f5297 100644
--- a/src/test/ui/conservative_impl_trait.stderr
+++ b/src/test/ui/conservative_impl_trait.stderr
@@ -6,6 +6,18 @@ LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error: aborting due to previous error
+error[E0277]: `()` is not an iterator
+  --> $DIR/conservative_impl_trait.rs:3:60
+   |
+LL |   fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
+   |  ____________________________________________________________^
+LL | |
+LL | |
+LL | | }
+   | |_^ `()` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `()`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/autoderef.rs b/src/test/ui/impl-trait/autoderef.rs
new file mode 100644
index 00000000000..5e4f4995447
--- /dev/null
+++ b/src/test/ui/impl-trait/autoderef.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+use std::path::Path;
+use std::ffi::OsStr;
+use std::ops::Deref;
+
+fn frob(path: &str) -> impl Deref<Target = Path> + '_ {
+    OsStr::new(path).as_ref()
+}
+
+fn open_parent<'path>(_path: &'path Path) {
+    todo!()
+}
+
+fn main() {
+    let old_path = frob("hello");
+
+    open_parent(&old_path);
+}
diff --git a/src/test/ui/impl-trait/cross-return-site-inference.rs b/src/test/ui/impl-trait/cross-return-site-inference.rs
index ceb8414650f..c27b5ca9f66 100644
--- a/src/test/ui/impl-trait/cross-return-site-inference.rs
+++ b/src/test/ui/impl-trait/cross-return-site-inference.rs
@@ -42,4 +42,4 @@ fn muh3() -> Result<(), impl std::fmt::Debug> {
     Err(From::from("foo")) //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied
 }
 
-fn main() {}
\ No newline at end of file
+fn main() {}
diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr
index fd33fa7c674..46053c6e7c1 100644
--- a/src/test/ui/impl-trait/equality2.stderr
+++ b/src/test/ui/impl-trait/equality2.stderr
@@ -15,7 +15,9 @@ LL | fn hide<T: Foo>(x: T) -> impl Foo {
    |                          -------- the found opaque type
 ...
 LL |     let _: u32 = hide(0_u32);
-   |                  ^^^^^^^^^^^ expected `u32`, found opaque type
+   |            ---   ^^^^^^^^^^^ expected `u32`, found opaque type
+   |            |
+   |            expected due to this
    |
    = note:     expected type `u32`
            found opaque type `impl Foo`
diff --git a/src/test/ui/impl-trait/issues/issue-70877.rs b/src/test/ui/impl-trait/issues/issue-70877.rs
index 9cbe33aef5b..1a86fa00ed1 100644
--- a/src/test/ui/impl-trait/issues/issue-70877.rs
+++ b/src/test/ui/impl-trait/issues/issue-70877.rs
@@ -28,7 +28,7 @@ fn ham() -> Foo {
 fn oof() -> impl std::fmt::Debug {
     let mut bar = ham();
     let func = bar.next().unwrap();
-    return func(&"oof"); //~^^^ ERROR opaque type's hidden type cannot be another opaque type
+    return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
 }
 
 fn main() {
diff --git a/src/test/ui/impl-trait/issues/issue-70877.stderr b/src/test/ui/impl-trait/issues/issue-70877.stderr
index 2610a198186..7cbd58bdabf 100644
--- a/src/test/ui/impl-trait/issues/issue-70877.stderr
+++ b/src/test/ui/impl-trait/issues/issue-70877.stderr
@@ -13,15 +13,10 @@ LL |         Some(Box::new(quux))
               found enum `Option<Box<for<'r> fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>`
 
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/issue-70877.rs:28:34
+  --> $DIR/issue-70877.rs:31:12
    |
-LL |   fn oof() -> impl std::fmt::Debug {
-   |  __________________________________^
-LL | |     let mut bar = ham();
-LL | |     let func = bar.next().unwrap();
-LL | |     return func(&"oof");
-LL | | }
-   | |_^ one of the two opaque types used here has to be outside its defining scope
+LL |     return func(&"oof");
+   |            ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
    |
 note: opaque type whose hidden type is being assigned
   --> $DIR/issue-70877.rs:28:13
diff --git a/src/test/ui/impl-trait/projection.rs b/src/test/ui/impl-trait/projection.rs
index 21fc6591e97..b33802e2bc8 100644
--- a/src/test/ui/impl-trait/projection.rs
+++ b/src/test/ui/impl-trait/projection.rs
@@ -26,4 +26,4 @@ fn run<F>(f: F)
 
 fn main() {
     run(|_| {});
-}
\ No newline at end of file
+}
diff --git a/src/test/ui/impl-trait/question_mark.rs b/src/test/ui/impl-trait/question_mark.rs
index 495bf5c1d64..7bd5cff31bb 100644
--- a/src/test/ui/impl-trait/question_mark.rs
+++ b/src/test/ui/impl-trait/question_mark.rs
@@ -27,4 +27,4 @@ pub fn direct() -> Result<(), impl Debug> {
     Err(Target)
 }
 
-fn main() {}
\ No newline at end of file
+fn main() {}
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
index a60e34c17b6..6aa832cde71 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
@@ -21,6 +21,7 @@ mod b {
 
     impl PartialEq<(Foo, i32)> for Bar {
         fn eq(&self, _other: &(Bar, i32)) -> bool {
+            //~^ ERROR impl has stricter requirements than trait
             true
         }
     }
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index eae7d38d116..19d5cdb9d0a 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -14,5 +14,12 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |
    = note: `Foo` must be used in combination with a concrete type within the same module
 
-error: aborting due to 2 previous errors
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:23:9
+   |
+LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `b::Bar: PartialEq<(b::Bar, i32)>`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other2.rs b/src/test/ui/impl-trait/two_tait_defining_each_other2.rs
index 3b16d0f5e04..05b09668016 100644
--- a/src/test/ui/impl-trait/two_tait_defining_each_other2.rs
+++ b/src/test/ui/impl-trait/two_tait_defining_each_other2.rs
@@ -1,6 +1,6 @@
 #![feature(type_alias_impl_trait)]
 
-type A = impl Foo;
+type A = impl Foo; //~ ERROR unconstrained opaque type
 type B = impl Foo;
 
 trait Foo {}
diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr
index ef2089a6c5b..4d8f96de162 100644
--- a/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr
+++ b/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr
@@ -1,3 +1,11 @@
+error: unconstrained opaque type
+  --> $DIR/two_tait_defining_each_other2.rs:3:10
+   |
+LL | type A = impl Foo;
+   |          ^^^^^^^^
+   |
+   = note: `A` must be used in combination with a concrete type within the same module
+
 error: opaque type's hidden type cannot be another opaque type from the same scope
   --> $DIR/two_tait_defining_each_other2.rs:9:5
    |
@@ -15,5 +23,5 @@ note: opaque type being used as hidden type
 LL | type A = impl Foo;
    |          ^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs
index 14b6c0f3581..fde59f39b1c 100644
--- a/src/test/ui/issues-71798.rs
+++ b/src/test/ui/issues-71798.rs
@@ -1,5 +1,6 @@
 fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
     //~^ ERROR `u32` is not a future
+    //~| ERROR `u32` is not a future
     *x
 }
 
diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr
index ab72c3e41af..63669c0513d 100644
--- a/src/test/ui/issues-71798.stderr
+++ b/src/test/ui/issues-71798.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `u` in this scope
-  --> $DIR/issues-71798.rs:7:24
+  --> $DIR/issues-71798.rs:8:24
    |
 LL |     let _ = test_ref & u;
    |                        ^ not found in this scope
@@ -13,7 +13,21 @@ LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
    = help: the trait `Future` is not implemented for `u32`
    = note: u32 must be a future or must implement `IntoFuture` to be awaited
 
-error: aborting due to 2 previous errors
+error[E0277]: `u32` is not a future
+  --> $DIR/issues-71798.rs:1:69
+   |
+LL |   fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
+   |  _____________________________________________________________________^
+LL | |
+LL | |
+LL | |     *x
+LL | | }
+   | |_^ `u32` is not a future
+   |
+   = help: the trait `Future` is not implemented for `u32`
+   = note: u32 must be a future or must implement `IntoFuture` to be awaited
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0425.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs
index cf5d3dab4aa..c2954868f78 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.rs
+++ b/src/test/ui/parser/fn-header-semantic-fail.rs
@@ -27,6 +27,7 @@ fn main() {
     struct Y;
     impl X for Y {
         async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
+        //~^ ERROR impl has stricter requirements than trait
         unsafe fn ft2() {} // OK.
         const fn ft3() {} //~ ERROR functions in traits cannot be declared const
         extern "C" fn ft4() {}
@@ -35,6 +36,7 @@ fn main() {
         //~| ERROR functions in traits cannot be declared const
         //~| ERROR functions cannot be both `const` and `async`
         //~| ERROR cycle detected
+        //~| ERROR impl has stricter requirements than 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 1d7460b8d36..bd3b9181123 100644
--- a/src/test/ui/parser/fn-header-semantic-fail.stderr
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -62,19 +62,19 @@ LL |         async fn ft1() {}
    = 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:31:9
+  --> $DIR/fn-header-semantic-fail.rs:32: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:33:9
+  --> $DIR/fn-header-semantic-fail.rs:34: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:33:9
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL |         const async unsafe extern "C" fn ft5() {}
    = 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:33:9
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^-^^^^^------------------------------
@@ -94,7 +94,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:45:9
+  --> $DIR/fn-header-semantic-fail.rs:47:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^-^^^^^------------------------------
@@ -103,7 +103,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:51:18
+  --> $DIR/fn-header-semantic-fail.rs:53:18
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -116,7 +116,7 @@ LL |         fn fe1();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:52:19
+  --> $DIR/fn-header-semantic-fail.rs:54:19
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -130,7 +130,7 @@ LL |         fn fe2();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:53:18
+  --> $DIR/fn-header-semantic-fail.rs:55:18
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -144,7 +144,7 @@ LL |         fn fe3();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:54:23
+  --> $DIR/fn-header-semantic-fail.rs:56:23
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -158,7 +158,7 @@ LL |         fn fe4();
    |         ~~
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:55:42
+  --> $DIR/fn-header-semantic-fail.rs:57:42
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
@@ -172,7 +172,7 @@ LL |         fn fe5();
    |         ~~
 
 error: functions cannot be both `const` and `async`
-  --> $DIR/fn-header-semantic-fail.rs:55:9
+  --> $DIR/fn-header-semantic-fail.rs:57:9
    |
 LL |         const async unsafe extern "C" fn fe5();
    |         ^^^^^-^^^^^----------------------------
@@ -216,30 +216,48 @@ LL | |     }
 LL | | }
    | |_^
 
-error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5::{opaque#0}`
-  --> $DIR/fn-header-semantic-fail.rs:33:48
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/fn-header-semantic-fail.rs:29:9
+   |
+LL |         async fn ft1();
+   |         --------------- definition of `ft1` from trait
+...
+LL |         async fn ft1() {}
+   |         ^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/fn-header-semantic-fail.rs:34:9
+   |
+LL |         const async unsafe extern "C" fn ft5();
+   |         --------------------------------------- definition of `ft5` from trait
+...
+LL |         const async unsafe extern "C" fn ft5() {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
+
+error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5::{opaque#0}`
+  --> $DIR/fn-header-semantic-fail.rs:34: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: 38:6>::ft5`...
-  --> $DIR/fn-header-semantic-fail.rs:33:9
+note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 38:6>::ft5`...
-  --> $DIR/fn-header-semantic-fail.rs:33:9
+note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
+  --> $DIR/fn-header-semantic-fail.rs:34: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: 38:6>::ft5`...
-  --> $DIR/fn-header-semantic-fail.rs:33:9
+note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5`...
+  --> $DIR/fn-header-semantic-fail.rs:34:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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:28:5: 38:6>::ft5::{opaque#0}`, completing the cycle
+   = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 40:6>::ft5::{opaque#0}`, completing the cycle
 note: cycle used when checking item types in top-level module
   --> $DIR/fn-header-semantic-fail.rs:5:1
    |
@@ -252,30 +270,30 @@ LL | |     }
 LL | | }
    | |_^
 
-error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5::{opaque#0}`
-  --> $DIR/fn-header-semantic-fail.rs:45:48
+error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5::{opaque#0}`
+  --> $DIR/fn-header-semantic-fail.rs:47:48
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |                                                ^
    |
-note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5`...
-  --> $DIR/fn-header-semantic-fail.rs:45:9
+note: ...which requires borrow-checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
+  --> $DIR/fn-header-semantic-fail.rs:47:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5`...
-  --> $DIR/fn-header-semantic-fail.rs:45:9
+note: ...which requires processing `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
+  --> $DIR/fn-header-semantic-fail.rs:47:9
    |
 LL |         const async unsafe extern "C" fn fi5() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 48:6>::fi5`...
-  --> $DIR/fn-header-semantic-fail.rs:45:9
+note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::fi5`...
+  --> $DIR/fn-header-semantic-fail.rs:47: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:40:5: 48:6>::fi5::{opaque#0}`, completing the cycle
+   = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:42:5: 50:6>::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
    |
@@ -288,7 +306,7 @@ LL | |     }
 LL | | }
    | |_^
 
-error: aborting due to 21 previous errors
+error: aborting due to 23 previous errors
 
-Some errors have detailed explanations: E0379, E0391, E0706.
-For more information about an error, try `rustc --explain E0379`.
+Some errors have detailed explanations: E0276, E0379, E0391, E0706.
+For more information about an error, try `rustc --explain E0276`.
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 49462f52fb4..6facc467f7a 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,6 +14,7 @@ trait B {
 impl B for A {
     async fn associated(); //~ ERROR without body
     //~^ ERROR cannot be declared `async`
+    //~| ERROR impl has stricter requirements than 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 a473f42fc2c..c144060a859 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
@@ -44,6 +44,16 @@ 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
 
-error: aborting due to 5 previous errors
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
+   |
+LL |     async fn associated();
+   |     ---------------------- definition of `associated` from trait
+...
+LL |     async fn associated();
+   |     ^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0706`.
+Some errors have detailed explanations: E0276, E0706.
+For more information about an error, try `rustc --explain E0276`.
diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs
index a02664ad7ca..6aa93a24d2f 100644
--- a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs
+++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs
@@ -16,9 +16,6 @@ fn extra_semicolon() {
 async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
 //~| NOTE while checking the return type of the `async fn`
 //~| NOTE in this expansion of desugaring of `async` block or function
-//~| NOTE while checking the return type of the `async fn`
-//~| NOTE in this expansion of desugaring of `async` block or function
-//~| NOTE checked the `Output` of this `async fn`, expected opaque type
 async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
 //~| NOTE checked the `Output` of this `async fn`, found opaque type
 //~| NOTE while checking the return type of the `async fn`
@@ -34,7 +31,7 @@ async fn async_extra_semicolon_same() {
         }
         false => async_dummy(), //~ ERROR `match` arms have incompatible types
         //~^ NOTE expected `()`, found opaque type
-        //~| NOTE expected unit type `()`
+        //~| NOTE expected type `()`
         //~| HELP consider `await`ing on the `Future`
     };
 }
@@ -47,7 +44,7 @@ async fn async_extra_semicolon_different() {
         }
         false => async_dummy2(), //~ ERROR `match` arms have incompatible types
         //~^ NOTE expected `()`, found opaque type
-        //~| NOTE expected unit type `()`
+        //~| NOTE expected type `()`
         //~| HELP consider `await`ing on the `Future`
     };
 }
@@ -58,7 +55,7 @@ async fn async_different_futures() {
         //~| HELP consider `await`ing on both `Future`s
         false => async_dummy2(), //~ ERROR `match` arms have incompatible types
         //~^ NOTE expected opaque type, found a different opaque type
-        //~| NOTE expected opaque type `impl Future<Output = ()>`
+        //~| NOTE expected type `impl Future<Output = ()>`
         //~| NOTE distinct uses of `impl Trait` result in different opaque types
     };
 }
diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
index 4c4b782bd6f..b55c51b9280 100644
--- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
+++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
@@ -1,5 +1,5 @@
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/match-prev-arm-needing-semi.rs:35:18
+  --> $DIR/match-prev-arm-needing-semi.rs:32:18
    |
 LL |       let _ = match true {
    |  _____________-
@@ -20,8 +20,8 @@ note: while checking the return type of the `async fn`
    |
 LL | async fn async_dummy() {}
    |                        ^ checked the `Output` of this `async fn`, found opaque type
-   = note: expected unit type `()`
-            found opaque type `impl Future<Output = ()>`
+   = note:     expected type `()`
+           found opaque type `impl Future<Output = ()>`
 help: consider `await`ing on the `Future`
    |
 LL |         false => async_dummy().await,
@@ -33,7 +33,7 @@ LL +             async_dummy()
    | 
 
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/match-prev-arm-needing-semi.rs:48:18
+  --> $DIR/match-prev-arm-needing-semi.rs:45:18
    |
 LL |       let _ = match true {
    |  _____________-
@@ -50,12 +50,12 @@ LL | |     };
    | |_____- `match` arms have incompatible types
    |
 note: while checking the return type of the `async fn`
-  --> $DIR/match-prev-arm-needing-semi.rs:22:25
+  --> $DIR/match-prev-arm-needing-semi.rs:19:25
    |
 LL | async fn async_dummy2() {}
    |                         ^ checked the `Output` of this `async fn`, found opaque type
-   = note: expected unit type `()`
-            found opaque type `impl Future<Output = ()>`
+   = note:     expected type `()`
+           found opaque type `impl Future<Output = ()>`
 help: consider `await`ing on the `Future`
    |
 LL |         false => async_dummy2().await,
@@ -69,7 +69,7 @@ LL ~         false => Box::new(async_dummy2()),
    |
 
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/match-prev-arm-needing-semi.rs:59:18
+  --> $DIR/match-prev-arm-needing-semi.rs:56:18
    |
 LL |       let _ = match true {
    |  _____________-
@@ -84,17 +84,12 @@ LL | |     };
    | |_____- `match` arms have incompatible types
    |
 note: while checking the return type of the `async fn`
-  --> $DIR/match-prev-arm-needing-semi.rs:16:24
-   |
-LL | async fn async_dummy() {}
-   |                        ^ checked the `Output` of this `async fn`, expected opaque type
-note: while checking the return type of the `async fn`
-  --> $DIR/match-prev-arm-needing-semi.rs:22:25
+  --> $DIR/match-prev-arm-needing-semi.rs:19:25
    |
 LL | async fn async_dummy2() {}
    |                         ^ checked the `Output` of this `async fn`, found opaque type
-   = note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>)
-              found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:22:25>)
+   = note:     expected type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>)
+           found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>)
    = note: distinct uses of `impl Trait` result in different opaque types
 help: consider `await`ing on both `Future`s
    |
diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr
index 133ffb05873..e065e0aaa8e 100644
--- a/src/test/ui/suggestions/opaque-type-error.stderr
+++ b/src/test/ui/suggestions/opaque-type-error.stderr
@@ -1,9 +1,6 @@
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/opaque-type-error.rs:20:9
    |
-LL |   fn thing_one() -> impl Future<Output = Result<(), ()>> {
-   |                     ------------------------------------ the expected opaque type
-...
 LL |   fn thing_two() -> impl Future<Output = Result<(), ()>> {
    |                     ------------------------------------ the found opaque type
 ...
@@ -16,8 +13,8 @@ LL | |         thing_two()
 LL | |     }.await
    | |_____- `if` and `else` have incompatible types
    |
-   = note: expected opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
-              found opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
+   = note:     expected type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
+           found opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
    = note: distinct uses of `impl Trait` result in different opaque types
 help: consider `await`ing on both `Future`s
    |
diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
index 26308c6ff6b..fbfa0ccf1e8 100644
--- a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
+++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
@@ -12,11 +12,13 @@ error[E0308]: mismatched types
 LL |     pub type Boo = impl ::std::fmt::Debug;
    |                    ---------------------- the expected opaque type
 ...
+LL | fn bomp() -> boo::Boo {
+   |              -------- expected `Boo` because of return type
 LL |     ""
    |     ^^ expected opaque type, found `&str`
    |
    = note: expected opaque type `Boo`
-                found reference `&str`
+                found reference `&'static str`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
index e691d8781c0..ae03a5b3e37 100644
--- a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
+++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
@@ -5,7 +5,9 @@ LL |     pub type Boo = impl ::std::fmt::Debug;
    |                    ---------------------- the found opaque type
 ...
 LL |     let _: &str = bomp();
-   |                   ^^^^^^ expected `&str`, found opaque type
+   |            ----   ^^^^^^ expected `&str`, found opaque type
+   |            |
+   |            expected due to this
    |
    = note: expected reference `&str`
             found opaque type `Boo`
@@ -16,11 +18,13 @@ error[E0308]: mismatched types
 LL |     pub type Boo = impl ::std::fmt::Debug;
    |                    ---------------------- the expected opaque type
 ...
+LL | fn bomp() -> boo::Boo {
+   |              -------- expected `Boo` because of return type
 LL |     ""
    |     ^^ expected opaque type, found `&str`
    |
    = note: expected opaque type `Boo`
-                found reference `&str`
+                found reference `&'static str`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index f099d2c07d1..891531951c1 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -33,7 +33,6 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::ConstEquate(..)
                 | ty::PredicateKind::Trait(..)
-                | ty::PredicateKind::OpaqueType(..)
                 | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
                 ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
                 ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),