about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-03-06 10:21:27 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-04-08 15:00:26 +0000
commit19bd91d128d921522287314925c027ea4aea1e45 (patch)
treeae967187c8e6852719217f645c6decb7cddca4d6
parentea44ce059b9f10394a08e369cd856192984d0ca0 (diff)
downloadrust-19bd91d128d921522287314925c027ea4aea1e45.tar.gz
rust-19bd91d128d921522287314925c027ea4aea1e45.zip
Pass list of defineable opaque types into canonical queries
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs12
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs9
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs16
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs2
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs11
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs8
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs15
-rw-r--r--compiler/rustc_middle/src/traits/solve.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs3
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs1
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs23
-rw-r--r--compiler/rustc_type_ir/src/debug.rs4
-rw-r--r--compiler/rustc_type_ir/src/infcx.rs2
-rw-r--r--compiler/rustc_type_ir/src/interner.rs1
-rw-r--r--tests/ui/impl-trait/equality-in-canonical-query.clone.stderr23
-rw-r--r--tests/ui/impl-trait/equality-in-canonical-query.rs11
-rw-r--r--tests/ui/impl-trait/nested-rpit-hrtb.rs2
-rw-r--r--tests/ui/impl-trait/nested-rpit-hrtb.stderr7
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr23
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr11
30 files changed, 101 insertions, 139 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 63b80445817..1979554332e 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -133,6 +133,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
             let ty =
                 infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type);
+
+            // Sometimes, when the hidden type is an inference variable, it can happen that
+            // the hidden type becomes the opaque type itself. In this case, this was an opaque
+            // usage of the opaque type and we can ignore it. This check is mirrored in typeck's
+            // writeback.
+            // FIXME(-Znext-solver): This should be unnecessary with the new solver.
+            if let ty::Alias(ty::Opaque, alias_ty) = ty.kind()
+                && alias_ty.def_id == opaque_type_key.def_id.to_def_id()
+                && alias_ty.args == opaque_type_key.args
+            {
+                continue;
+            }
             // Sometimes two opaque types are the same only after we remap the generic parameters
             // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
             // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 9f70fee993d..370028db88b 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -45,6 +45,7 @@ impl<'tcx> InferCtxt<'tcx> {
         let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
             self.tcx,
             param_env,
+            self.defining_use_anchor,
             query_state,
             |tcx, param_env, query_state| {
                 // FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
@@ -540,6 +541,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             max_universe: ty::UniverseIndex::ROOT,
             variables: List::empty(),
             value: (),
+            defining_anchor: infcx.map(|i| i.defining_use_anchor).unwrap_or_default(),
         };
         Canonicalizer::canonicalize_with_base(
             base,
@@ -609,7 +611,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             .max()
             .unwrap_or(ty::UniverseIndex::ROOT);
 
-        Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
+        Canonical {
+            max_universe,
+            variables: canonical_variables,
+            value: (base.value, out_value),
+            defining_anchor: base.defining_anchor,
+        }
     }
 
     /// Creates a canonical variable replacing `kind` from the input,
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 6e5ed0a31cb..0a43f7cfa29 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -243,13 +243,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
 pub struct InferCtxt<'tcx> {
     pub tcx: TyCtxt<'tcx>,
 
-    /// The `DefId` of the item in whose context we are performing inference or typeck.
-    /// It is used to check whether an opaque type use is a defining use.
-    ///
-    /// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
-    /// the obligation. This frequently happens for
-    /// short lived InferCtxt within queries. The opaque type obligations are forwarded
-    /// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
+    /// The `DefIds` of the opaque types that may have their hidden types constrained.
     ///
     /// Its default value is `DefiningAnchor::Bind(&[])`, which means no opaque types may be defined.
     /// This way it is easier to catch errors that
@@ -401,6 +395,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
     fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
         self.probe_const_var(vid).ok()
     }
+
+    fn defining_anchor(&self) -> DefiningAnchor<'tcx> {
+        self.defining_use_anchor
+    }
 }
 
 /// See the `error_reporting` module for more details.
@@ -679,14 +677,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     /// the bound values in `C` to their instantiated values in `V`
     /// (in other words, `S(C) = V`).
     pub fn build_with_canonical<T>(
-        &mut self,
+        self,
         span: Span,
         canonical: &Canonical<'tcx, T>,
     ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        let infcx = self.build();
+        let infcx = self.with_opaque_type_inference(canonical.defining_anchor).build();
         let (value, args) = infcx.instantiate_canonical(span, canonical);
         (infcx, value, args)
     }
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 01430e830e5..e199aec2eb6 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -146,7 +146,6 @@ impl<'tcx> InferCtxt<'tcx> {
                             return None;
                         }
                     }
-                    DefiningAnchor::Bubble => {}
                 }
                 if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
                     // We could accept this, but there are various ways to handle this situation, and we don't
@@ -373,7 +372,6 @@ impl<'tcx> InferCtxt<'tcx> {
     #[instrument(skip(self), level = "trace", ret)]
     pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
         let defined_opaque_types = match self.defining_use_anchor {
-            DefiningAnchor::Bubble => return None,
             DefiningAnchor::Bind(bind) => bind,
         };
 
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index acea89e4aab..2a51cfc5e7c 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -33,6 +33,7 @@ use std::ops::Index;
 
 use crate::infer::MemberConstraint;
 use crate::mir::ConstraintCategory;
+use crate::traits::DefiningAnchor;
 use crate::ty::GenericArg;
 use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
 
@@ -153,11 +154,6 @@ pub struct QueryResponse<'tcx, R> {
     pub var_values: CanonicalVarValues<'tcx>,
     pub region_constraints: QueryRegionConstraints<'tcx>,
     pub certainty: Certainty,
-    /// List of opaque types which we tried to compare to another type.
-    /// Inside the query we don't know yet whether the opaque type actually
-    /// should get its hidden type inferred. So we bubble the opaque type
-    /// and the type it was compared against upwards and let the query caller
-    /// handle it.
     pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
     pub value: R,
 }
@@ -316,6 +312,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
         &self,
         tcx: TyCtxt<'tcx>,
         key: ty::ParamEnv<'tcx>,
+        defining_anchor: DefiningAnchor<'tcx>,
         state: &mut OriginalQueryValues<'tcx>,
         canonicalize_op: fn(
             TyCtxt<'tcx>,
@@ -330,6 +327,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
                 max_universe: ty::UniverseIndex::ROOT,
                 variables: List::empty(),
                 value: key,
+                defining_anchor,
             };
         }
 
@@ -344,7 +342,8 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
                 *canonical
             }
             Entry::Vacant(e) => {
-                let canonical = canonicalize_op(tcx, key, state);
+                let mut canonical = canonicalize_op(tcx, key, state);
+                canonical.defining_anchor = defining_anchor;
                 let OriginalQueryValues { var_values, universe_map } = state;
                 assert_eq!(universe_map.len(), 1);
                 e.insert((canonical, tcx.arena.alloc_slice(var_values)));
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 8cb4ee7bd41..b14ecad83cc 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -338,10 +338,10 @@ macro_rules! define_callbacks {
 
                 pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
 
-                // Ensure that keys grow no larger than 64 bytes
+                // Ensure that keys grow no larger than 72 bytes
                 #[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
                 const _: () = {
-                    if mem::size_of::<Key<'static>>() > 64 {
+                    if mem::size_of::<Key<'static>>() > 72 {
                         panic!("{}", concat!(
                             "the query `",
                             stringify!($name),
@@ -352,10 +352,10 @@ macro_rules! define_callbacks {
                     }
                 };
 
-                // Ensure that values grow no larger than 64 bytes
+                // Ensure that values grow no larger than 72 bytes
                 #[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
                 const _: () = {
-                    if mem::size_of::<Value<'static>>() > 64 {
+                    if mem::size_of::<Value<'static>>() > 72 {
                         panic!("{}", concat!(
                             "the query `",
                             stringify!($name),
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index ee816791919..58aff27266d 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -1004,6 +1004,7 @@ pub enum CodegenObligationError {
 /// opaques are replaced with inference vars eagerly in the old solver (e.g.
 /// in projection, and in the signature during function type-checking).
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
+#[derive(TyEncodable, TyDecodable)]
 pub enum DefiningAnchor<'tcx> {
     /// Define opaques which are in-scope of the current item being analyzed.
     /// Also, eagerly replace these opaque types in `replace_opaque_types_with_inference_vars`.
@@ -1012,14 +1013,12 @@ pub enum DefiningAnchor<'tcx> {
     /// errors when handling opaque types, and also should be used when we would
     /// otherwise reveal opaques (such as [`Reveal::All`] reveal mode).
     Bind(&'tcx ty::List<LocalDefId>),
-    /// In contexts where we don't currently know what opaques are allowed to be
-    /// defined, such as (old solver) canonical queries, we will simply allow
-    /// opaques to be defined, but "bubble" them up in the canonical response or
-    /// otherwise treat them to be handled later.
-    ///
-    /// We do not eagerly replace opaque types in `replace_opaque_types_with_inference_vars`,
-    /// which may affect what predicates pass and fail in the old trait solver.
-    Bubble,
+}
+
+impl Default for DefiningAnchor<'_> {
+    fn default() -> Self {
+        Self::Bind(ty::List::empty())
+    }
 }
 
 impl<'tcx> DefiningAnchor<'tcx> {
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index 6dcea2aaff1..13504c6ae93 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -4,7 +4,7 @@ use rustc_span::def_id::DefId;
 
 use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
 use crate::traits::query::NoSolution;
-use crate::traits::{Canonical, DefiningAnchor};
+use crate::traits::Canonical;
 use crate::ty::{
     self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable,
     TypeVisitor,
@@ -114,7 +114,6 @@ impl MaybeCause {
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct QueryInput<'tcx, T> {
     pub goal: Goal<'tcx, T>,
-    pub anchor: DefiningAnchor<'tcx>,
     pub predefined_opaques_in_body: PredefinedOpaques<'tcx>,
 }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 1db9bce73a6..36fad95715c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -84,6 +84,7 @@ use std::ops::{Bound, Deref};
 #[allow(rustc::usage_of_ty_tykind)]
 impl<'tcx> Interner for TyCtxt<'tcx> {
     type DefId = DefId;
+    type DefiningAnchor = traits::DefiningAnchor<'tcx>;
     type AdtDef = ty::AdtDef<'tcx>;
     type GenericArgs = ty::GenericArgsRef<'tcx>;
     type GenericArg = ty::GenericArg<'tcx>;
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 1899517c0e2..2be1db51da1 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -69,7 +69,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
 
         let (max_universe, variables) = canonicalizer.finalize();
 
-        Canonical { max_universe, variables, value }
+        let defining_anchor = infcx.defining_anchor();
+        Canonical { defining_anchor, max_universe, variables, value }
     }
 
     fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVars) {
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 7056288e758..0595e82b39e 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -1,5 +1,5 @@
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
-use crate::traits::{self, DefiningAnchor, ObligationCtxt, SelectionContext};
+use crate::traits::{self, ObligationCtxt, SelectionContext};
 
 use crate::traits::TraitEngineExt as _;
 use rustc_hir::def_id::DefId;
@@ -132,9 +132,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
         R: Debug + TypeFoldable<TyCtxt<'tcx>>,
         Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
     {
-        let (infcx, key, canonical_inference_vars) = self
-            .with_opaque_type_inference(DefiningAnchor::Bubble)
-            .build_with_canonical(DUMMY_SP, canonical_key);
+        let (infcx, key, canonical_inference_vars) =
+            self.build_with_canonical(DUMMY_SP, canonical_key);
         let ocx = ObligationCtxt::new(&infcx);
         let value = operation(&ocx, key)?;
         ocx.make_canonicalized_query_response(canonical_inference_vars, value)
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 4a4efb6884f..0b37163d597 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -68,7 +68,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             &mut orig_values,
             QueryInput {
                 goal,
-                anchor: self.infcx.defining_use_anchor,
                 predefined_opaques_in_body: self
                     .tcx()
                     .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 1739bd70e7b..5efee7a2190 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -230,7 +230,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             .infer_ctxt()
             .intercrate(intercrate)
             .with_next_trait_solver(true)
-            .with_opaque_type_inference(canonical_input.value.anchor)
             .build_with_canonical(DUMMY_SP, &canonical_input);
 
         let mut ecx = EvalCtxt {
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 8294a8a67b1..311deee0dbc 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -316,5 +316,6 @@ fn response_no_constraints_raw<'tcx>(
             external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
             certainty,
         },
+        defining_anchor: Default::default(),
     }
 }
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 3da74f9fe6e..1134935e02d 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -16,6 +16,7 @@ use crate::{Interner, PlaceholderLike, UniverseIndex};
 pub struct Canonical<I: Interner, V> {
     pub value: V,
     pub max_universe: UniverseIndex,
+    pub defining_anchor: I::DefiningAnchor,
     pub variables: I::CanonicalVars,
 }
 
@@ -44,8 +45,8 @@ impl<I: Interner, V> Canonical<I, V> {
     /// let b: Canonical<I, (T, Ty<I>)> = a.unchecked_map(|v| (v, ty));
     /// ```
     pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<I, W> {
-        let Canonical { max_universe, variables, value } = self;
-        Canonical { max_universe, variables, value: map_op(value) }
+        let Canonical { defining_anchor, max_universe, variables, value } = self;
+        Canonical { defining_anchor, max_universe, variables, value: map_op(value) }
     }
 
     /// Allows you to map the `value` of a canonical while keeping the same set of
@@ -54,8 +55,8 @@ impl<I: Interner, V> Canonical<I, V> {
     /// **WARNING:** This function is very easy to mis-use, hence the name! See
     /// the comment of [Canonical::unchecked_map] for more details.
     pub fn unchecked_rebind<W>(self, value: W) -> Canonical<I, W> {
-        let Canonical { max_universe, variables, value: _ } = self;
-        Canonical { max_universe, variables, value }
+        let Canonical { defining_anchor, max_universe, variables, value: _ } = self;
+        Canonical { defining_anchor, max_universe, variables, value }
     }
 }
 
@@ -63,30 +64,32 @@ impl<I: Interner, V: Eq> Eq for Canonical<I, V> {}
 
 impl<I: Interner, V: PartialEq> PartialEq for Canonical<I, V> {
     fn eq(&self, other: &Self) -> bool {
-        let Self { value, max_universe, variables } = self;
+        let Self { value, max_universe, variables, defining_anchor } = self;
         *value == other.value
             && *max_universe == other.max_universe
             && *variables == other.variables
+            && *defining_anchor == other.defining_anchor
     }
 }
 
 impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Self { value, max_universe, variables } = self;
+        let Self { value, max_universe, variables, defining_anchor } = self;
         write!(
             f,
-            "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?} }}",
+            "Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?}, defining_anchor: {defining_anchor:?} }}",
         )
     }
 }
 
 impl<I: Interner, V: fmt::Debug> fmt::Debug for Canonical<I, V> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Self { value, max_universe, variables } = self;
+        let Self { value, max_universe, variables, defining_anchor } = self;
         f.debug_struct("Canonical")
             .field("value", &value)
             .field("max_universe", &max_universe)
             .field("variables", &variables)
+            .field("defining_anchor", &defining_anchor)
             .finish()
     }
 }
@@ -102,6 +105,7 @@ where
             value: self.value.try_fold_with(folder)?,
             max_universe: self.max_universe.try_fold_with(folder)?,
             variables: self.variables.try_fold_with(folder)?,
+            defining_anchor: self.defining_anchor,
         })
     }
 }
@@ -111,9 +115,10 @@ where
     I::CanonicalVars: TypeVisitable<I>,
 {
     fn visit_with<F: TypeVisitor<I>>(&self, folder: &mut F) -> F::Result {
-        let Self { value, max_universe, variables } = self;
+        let Self { value, max_universe, variables, defining_anchor } = self;
         try_visit!(value.visit_with(folder));
         try_visit!(max_universe.visit_with(folder));
+        try_visit!(defining_anchor.visit_with(folder));
         variables.visit_with(folder)
     }
 }
diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs
index 9c8e45b4338..aced3b53fde 100644
--- a/compiler/rustc_type_ir/src/debug.rs
+++ b/compiler/rustc_type_ir/src/debug.rs
@@ -43,6 +43,10 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
     fn probe_ct_var(&self, _vid: ConstVid) -> Option<I::Const> {
         None
     }
+
+    fn defining_anchor(&self) -> <Self::Interner as Interner>::DefiningAnchor {
+        Default::default()
+    }
 }
 
 pub trait DebugWithInfcx<I: Interner>: fmt::Debug {
diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs
index 28b71f0ea13..bdfa010c000 100644
--- a/compiler/rustc_type_ir/src/infcx.rs
+++ b/compiler/rustc_type_ir/src/infcx.rs
@@ -37,4 +37,6 @@ pub trait InferCtxtLike {
 
     /// Resolve `ConstVid` to its inferred type, if it has been equated with a non-infer type.
     fn probe_ct_var(&self, vid: ConstVid) -> Option<<Self::Interner as Interner>::Const>;
+
+    fn defining_anchor(&self) -> <Self::Interner as Interner>::DefiningAnchor;
 }
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 7d6862726f0..c447f65a5aa 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -11,6 +11,7 @@ use crate::{
 
 pub trait Interner: Sized + Copy {
     type DefId: Copy + Debug + Hash + Eq;
+    type DefiningAnchor: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
     type AdtDef: Copy + Debug + Hash + Eq;
 
     type GenericArgs: Copy
diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
deleted file mode 100644
index e4c8aec3973..00000000000
--- a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-note: no errors encountered even though delayed bugs were created
-
-note: those delayed bugs will now be shown as internal compiler errors
-
-error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }}
-   |
-   = 
-           
-
-error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }))), bound_vars: [] } } }
-  --> $DIR/equality-in-canonical-query.rs:21:5
-   |
-LL |     same_output(foo, rpit);
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-   |
-
-  --> $DIR/equality-in-canonical-query.rs:21:5
-   |
-LL |     same_output(foo, rpit);
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-
-query stack during panic:
-end of query stack
diff --git a/tests/ui/impl-trait/equality-in-canonical-query.rs b/tests/ui/impl-trait/equality-in-canonical-query.rs
index 6a32f4bec76..2b8f6ce1b07 100644
--- a/tests/ui/impl-trait/equality-in-canonical-query.rs
+++ b/tests/ui/impl-trait/equality-in-canonical-query.rs
@@ -1,15 +1,6 @@
 // issue: #116877
 //@ revisions: sized clone
-//@[sized] check-pass
-//@[clone] known-bug: #108498
-//@[clone] failure-status: 101
-//@[clone] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
-//@[clone] normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> ""
-//@[clone] normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> ""
-//@[clone] normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> ""
-//@[clone] normalize-stderr-test: "(?m)note: delayed at.*$" -> ""
-//@[clone] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
-//@[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
+//@ check-pass
 
 #[cfg(sized)] fn rpit() -> impl Sized {}
 #[cfg(clone)] fn rpit() -> impl Clone {}
diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs
index a696e1710f0..9b18aceb4a7 100644
--- a/tests/ui/impl-trait/nested-rpit-hrtb.rs
+++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs
@@ -44,7 +44,7 @@ fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized
 
 // This should resolve.
 fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
-//~^ ERROR type annotations needed: cannot satisfy `for<'a> &'a (): Qux<'b>`
+//~^ ERROR the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied
 
 // This should resolve.
 fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr
index 64f801ea685..2fa036f35fa 100644
--- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr
+++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr
@@ -86,13 +86,12 @@ note: lifetime declared here
 LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
    |                                            ^^
 
-error[E0283]: type annotations needed: cannot satisfy `for<'a> &'a (): Qux<'b>`
+error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied
   --> $DIR/nested-rpit-hrtb.rs:46:79
    |
 LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
-   |                                                                               ^^^^^^^^^^^^
+   |                                                                               ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()`
    |
-   = note: cannot satisfy `for<'a> &'a (): Qux<'b>`
    = help: the trait `Qux<'_>` is implemented for `()`
    = help: for that trait implementation, expected `()`, found `&'a ()`
 
@@ -125,5 +124,5 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si
 
 error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0261, E0277, E0283, E0657.
+Some errors have detailed explanations: E0261, E0277, E0657.
 For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
index ae463b6ef5b..9cc8546afbc 100644
--- a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
@@ -1,10 +1,9 @@
 #![feature(type_alias_impl_trait)]
 
-//@ check-pass
-
 type Foo = impl Fn() -> Foo;
 
 fn foo() -> Foo {
+    //~^ ERROR: overflow
     foo
 }
 
diff --git a/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
new file mode 100644
index 00000000000..1358c3e2a98
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == Foo`
+  --> $DIR/issue-53398-cyclic-types.rs:5:13
+   |
+LL | fn foo() -> Foo {
+   |             ^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
deleted file mode 100644
index 1c36fda4ae1..00000000000
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-note: no errors encountered even though delayed bugs were created
-
-note: those delayed bugs will now be shown as internal compiler errors
-
-error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }}
-   |
-   = 
-           
-
-error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } }
-  --> $DIR/rpit_tait_equality_in_canonical_query.rs:32:5
-   |
-LL |     query(get_rpit);
-   |     ^^^^^^^^^^^^^^^
-   |
-
-  --> $DIR/rpit_tait_equality_in_canonical_query.rs:32:5
-   |
-LL |     query(get_rpit);
-   |     ^^^^^^^^^^^^^^^
-
-query stack during panic:
-end of query stack
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
index 7524cebf9e6..6f50703aca2 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
@@ -8,17 +8,7 @@
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
-//@[next] check-pass
-
-//@[current] known-bug: #108498
-//@[current] failure-status: 101
-//@[current] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
-//@[current] normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> ""
-//@[current] normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> ""
-//@[current] normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> ""
-//@[current] normalize-stderr-test: "(?m)note: delayed at.*$" -> ""
-//@[current] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
-//@[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
+//@ check-pass
 
 #![feature(type_alias_impl_trait)]
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs
index e5e7fb677ed..80ab53881a3 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs
@@ -1,12 +1,10 @@
 #![feature(type_alias_impl_trait)]
 
 type Foo = impl Fn() -> Foo;
-//~^ ERROR: unconstrained opaque type
 
 fn crash(x: Foo) -> Foo {
+    //~^ ERROR: overflow
     x
 }
 
-fn main() {
-
-}
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr
index 3d43fbe0dbc..21779c7d128 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12
+error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
+  --> $DIR/type-alias-impl-trait-with-cycle-error.rs:5:21
    |
-LL | type Foo = impl Fn() -> Foo;
-   |            ^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same module
+LL | fn crash(x: Foo) -> Foo {
+   |                     ^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs
index 7c7a1b405bc..87b2d6765f4 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs
@@ -5,9 +5,9 @@ pub trait Bar<T> {
 }
 
 type Foo = impl Bar<Foo, Item = Foo>;
-//~^ ERROR: unconstrained opaque type
 
 fn crash(x: Foo) -> Foo {
+    //~^ ERROR: overflow
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr
index e2dc887989b..d1c620968ba 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12
+error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
+  --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:9:21
    |
-LL | type Foo = impl Bar<Foo, Item = Foo>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same module
+LL | fn crash(x: Foo) -> Foo {
+   |                     ^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.