diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 8a930ca59a334..78e9e104bdae8 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -5,12 +5,13 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
 use rustc_index::IndexSlice;
 use rustc_infer::infer::NllRegionVariableOrigin;
+use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
 use rustc_middle::mir::{
     Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
     Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
 };
 use rustc_middle::ty::adjustment::PointerCoercion;
-use rustc_middle::ty::{self, RegionVid, TyCtxt};
+use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{sym, DesugaringKind, Span};
 use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
@@ -290,12 +291,69 @@ impl<'tcx> BorrowExplanation<'tcx> {
                     }
                 }
 
+                if let ConstraintCategory::Cast { unsize_to: Some(unsize_ty) } = category {
+                    self.add_object_lifetime_default_note(tcx, err, unsize_ty);
+                }
                 self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
             }
             _ => {}
         }
     }
 
+    fn add_object_lifetime_default_note(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        err: &mut Diagnostic,
+        unsize_ty: Ty<'tcx>,
+    ) {
+        if let ty::Adt(def, args) = unsize_ty.kind() {
+            // We try to elaborate the object lifetime defaults and present those to the user. This should
+            // make it clear where the region constraint is coming from.
+            let generics = tcx.generics_of(def.did());
+
+            let mut has_dyn = false;
+            let mut failed = false;
+
+            let elaborated_args = std::iter::zip(*args, &generics.params).map(|(arg, param)| {
+                if let Some(ty::Dynamic(obj, _, ty::DynKind::Dyn)) = arg.as_type().map(Ty::kind) {
+                    let default = tcx.object_lifetime_default(param.def_id);
+
+                    let re_static = tcx.lifetimes.re_static;
+
+                    let implied_region = match default {
+                        // This is not entirely precise.
+                        ObjectLifetimeDefault::Empty => re_static,
+                        ObjectLifetimeDefault::Ambiguous => {
+                            failed = true;
+                            re_static
+                        }
+                        ObjectLifetimeDefault::Param(param_def_id) => {
+                            let index = generics.param_def_id_to_index[&param_def_id] as usize;
+                            args.get(index).and_then(|arg| arg.as_region()).unwrap_or_else(|| {
+                                failed = true;
+                                re_static
+                            })
+                        }
+                        ObjectLifetimeDefault::Static => re_static,
+                    };
+
+                    has_dyn = true;
+
+                    Ty::new_dynamic(tcx, obj, implied_region, ty::DynKind::Dyn).into()
+                } else {
+                    arg
+                }
+            });
+            let elaborated_ty = Ty::new_adt(tcx, *def, tcx.mk_args_from_iter(elaborated_args));
+
+            if has_dyn && !failed {
+                err.note(format!(
+                    "due to object lifetime defaults, `{unsize_ty}` actually means `{elaborated_ty}`"
+                ));
+            }
+        }
+    }
+
     fn add_lifetime_bound_suggestion_to_diagnostic(
         &self,
         err: &mut Diagnostic,
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 76c5a06c80db2..da1d1c70f0fad 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -53,7 +53,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
             ConstraintCategory::Yield => "yielding this value ",
             ConstraintCategory::UseAsConst => "using this value as a constant ",
             ConstraintCategory::UseAsStatic => "using this value as a static ",
-            ConstraintCategory::Cast => "cast ",
+            ConstraintCategory::Cast { .. } => "cast ",
             ConstraintCategory::CallArgument(_) => "argument ",
             ConstraintCategory::TypeAnnotation => "type annotation ",
             ConstraintCategory::ClosureBounds => "closure body ",
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 5d9fd2647f2cd..bb9ce5daba266 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1934,7 +1934,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             *ty,
                             ty_fn_ptr_from,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         ) {
                             span_mirbug!(
                                 self,
@@ -1959,7 +1959,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             *ty,
                             ty_fn_ptr_from,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         ) {
                             span_mirbug!(
                                 self,
@@ -1988,7 +1988,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             *ty,
                             ty_fn_ptr_from,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         ) {
                             span_mirbug!(
                                 self,
@@ -2013,7 +2013,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         self.prove_trait_ref(
                             trait_ref,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast {
+                                unsize_to: Some(tcx.fold_regions(ty, |r, _| {
+                                    if let ty::ReVar(_) = r.kind() {
+                                        tcx.lifetimes.re_erased
+                                    } else {
+                                        r
+                                    }
+                                })),
+                            },
                         );
                     }
 
@@ -2033,7 +2041,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 .iter()
                                 .map(|predicate| predicate.with_self_ty(tcx, self_ty)),
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         );
 
                         let outlives_predicate = tcx.mk_predicate(Binder::dummy(
@@ -2044,7 +2052,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         self.prove_predicate(
                             outlives_predicate,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         );
                     }
 
@@ -2065,7 +2073,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             *ty_from,
                             *ty_to,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         ) {
                             span_mirbug!(
                                 self,
@@ -2131,7 +2139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             *ty_elem,
                             *ty_to,
                             location.to_locations(),
-                            ConstraintCategory::Cast,
+                            ConstraintCategory::Cast { unsize_to: None },
                         ) {
                             span_mirbug!(
                                 self,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index d9b27fc13182c..4b7de36e7c7bc 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -626,15 +626,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 };
 
-                let coerce_to = match opt_coerce_to {
-                    Some(c) => c,
-                    None => {
-                        // If the loop context is not a `loop { }`, then break with
-                        // a value is illegal, and `opt_coerce_to` will be `None`.
-                        // Return error in that case (#114529).
-                        return Ty::new_misc_error(tcx);
-                    }
-                };
+                // If the loop context is not a `loop { }`, then break with
+                // a value is illegal, and `opt_coerce_to` will be `None`.
+                // Set expectation to error in that case and set tainted
+                // by error (#114529)
+                let coerce_to = opt_coerce_to.unwrap_or_else(|| {
+                    let guar = tcx.sess.delay_span_bug(
+                        expr.span,
+                        "illegal break with value found but no error reported",
+                    );
+                    self.set_tainted_by_errors(guar);
+                    Ty::new_error(tcx, guar)
+                });
 
                 // Recurse without `enclosing_breakables` borrowed.
                 e_ty = self.check_expr_with_hint(e, coerce_to);
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 2797d07976113..c32c3aa6d2968 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -65,8 +65,15 @@ impl<'tcx> InferCtxt<'tcx> {
 
     /// Forks the inference context, creating a new inference context with the same inference
     /// variables in the same state. This can be used to "branch off" many tests from the same
-    /// common state. Used in coherence.
+    /// common state.
     pub fn fork(&self) -> Self {
+        self.fork_with_intercrate(self.intercrate)
+    }
+
+    /// Forks the inference context, creating a new inference context with the same inference
+    /// variables in the same state, except possibly changing the intercrate mode. This can be
+    /// used to "branch off" many tests from the same common state. Used in negative coherence.
+    pub fn fork_with_intercrate(&self, intercrate: bool) -> Self {
         Self {
             tcx: self.tcx,
             defining_use_anchor: self.defining_use_anchor,
@@ -81,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> {
             tainted_by_errors: self.tainted_by_errors.clone(),
             err_count_on_creation: self.err_count_on_creation,
             universe: self.universe.clone(),
-            intercrate: self.intercrate,
+            intercrate,
             next_trait_solver: self.next_trait_solver,
         }
     }
diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
index d2d99bc0da87d..d3e2d5c764652 100644
--- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
+++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
@@ -50,7 +50,7 @@ declare_lint! {
     Warn,
     "`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
         reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
     };
 }
@@ -59,12 +59,13 @@ declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);
 
 impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
+        let tcx = cx.tcx;
         // `Deref` is being implemented for `t`
         if let hir::ItemKind::Impl(impl_) = item.kind
             && let Some(trait_) = &impl_.of_trait
-            && let t = cx.tcx.type_of(item.owner_id).instantiate_identity()
+            && let t = tcx.type_of(item.owner_id).instantiate_identity()
             && let opt_did @ Some(did) = trait_.trait_def_id()
-            && opt_did == cx.tcx.lang_items().deref_trait()
+            && opt_did == tcx.lang_items().deref_trait()
             // `t` is `dyn t_principal`
             && let ty::Dynamic(data, _, ty::Dyn) = t.kind()
             && let Some(t_principal) = data.principal()
@@ -73,9 +74,14 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
             && let ty::Dynamic(data, _, ty::Dyn) = target.kind()
             && let Some(target_principal) = data.principal()
             // `target_principal` is a supertrait of `t_principal`
-            && supertraits(cx.tcx, t_principal.with_self_ty(cx.tcx, cx.tcx.types.trait_object_dummy_self))
-                .any(|sup| sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(cx.tcx, x)) == target_principal)
+            && supertraits(tcx, t_principal.with_self_ty(tcx, tcx.types.trait_object_dummy_self))
+                .any(|sup| {
+                    tcx.erase_regions(
+                        sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(tcx, x)),
+                    ) == tcx.erase_regions(target_principal)
+                })
         {
+            let t = tcx.erase_regions(t);
             let label = impl_
                 .items
                 .iter()
@@ -83,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
                 .map(|label| SupertraitAsDerefTargetLabel { label });
             cx.emit_spanned_lint(
                 DEREF_INTO_DYN_SUPERTRAIT,
-                cx.tcx.def_span(item.owner_id.def_id),
+                tcx.def_span(item.owner_id.def_id),
                 SupertraitAsDerefTarget { t, target_principal, label },
             );
         }
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index d609965f36fe6..b5dd3010d3a8b 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -341,7 +341,11 @@ pub enum ConstraintCategory<'tcx> {
     UseAsConst,
     UseAsStatic,
     TypeAnnotation,
-    Cast,
+    Cast {
+        /// Whether this is an unsizing cast and if yes, this contains the target type.
+        /// Region variables are erased to ReErased.
+        unsize_to: Option<Ty<'tcx>>,
+    },
 
     /// A constraint that came from checking the body of a closure.
     ///
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index f9ec368361c59..cb5da0f296a0f 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -109,10 +109,12 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
 // Queries marked with `fatal_cycle` do not need the latter implementation,
 // as they will raise an fatal error on query cycles instead.
 rustc_queries! {
+    /// This exists purely for testing the interactions between delay_span_bug and incremental.
     query trigger_delay_span_bug(key: DefId) -> () {
-        desc { "triggering a delay span bug" }
+        desc { "triggering a delay span bug for testing incremental" }
     }
 
+    /// Collects the list of all tools registered using `#![register_tool]`.
     query registered_tools(_: ()) -> &'tcx ty::RegisteredTools {
         arena_cache
         desc { "compute registered tools for crate" }
@@ -286,6 +288,7 @@ rustc_queries! {
         }
     }
 
+    /// The root query triggering all analysis passes like typeck or borrowck.
     query analysis(key: ()) -> Result<(), ErrorGuaranteed> {
         eval_always
         desc { "running analysis passes on this crate" }
@@ -1781,10 +1784,17 @@ rustc_queries! {
         desc { "calculating the missing lang items in a crate" }
         separate_provide_extern
     }
+
+    /// The visible parent map is a map from every item to a visible parent.
+    /// It prefers the shortest visible path to an item.
+    /// Used for diagnostics, for example path trimming.
+    /// The parents are modules, enums or traits.
     query visible_parent_map(_: ()) -> &'tcx DefIdMap<DefId> {
         arena_cache
         desc { "calculating the visible parent map" }
     }
+    /// Collects the "trimmed", shortest accessible paths to all items for diagnostics.
+    /// See the [provider docs](`rustc_middle::ty::print::trimmed_def_paths`) for more info.
     query trimmed_def_paths(_: ()) -> &'tcx FxHashMap<DefId, Symbol> {
         arena_cache
         desc { "calculating trimmed def paths" }
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 4af841fcf9a5f..16e7b16a0bf8c 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -3,7 +3,6 @@ use crate::mir;
 use crate::ty::abstract_const::CastKind;
 use crate::ty::GenericArgsRef;
 use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
 
@@ -77,28 +76,3 @@ static_assert_size!(Expr<'_>, 24);
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(super::ConstKind<'_>, 32);
-
-/// An inference variable for a const, for use in const generics.
-#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
-pub enum InferConst {
-    /// Infer the value of the const.
-    Var(ty::ConstVid),
-    /// Infer the value of the effect.
-    ///
-    /// For why this is separate from the `Var` variant above, see the
-    /// documentation on `EffectVid`.
-    EffectVar(ty::EffectVid),
-    /// A fresh const variable. See `infer::freshen` for more details.
-    Fresh(u32),
-}
-
-impl<CTX> HashStable<CTX> for InferConst {
-    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        match self {
-            InferConst::Var(_) | InferConst::EffectVar(_) => {
-                panic!("const variables should not be hashed: {self:?}")
-            }
-            InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
-        }
-    }
-}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index ee23c9c48978e..62b0536dabee6 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -26,9 +26,9 @@ use crate::traits::solve::{
 };
 use crate::ty::{
     self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
-    ImplPolarity, InferTy, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig,
-    Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
-    TyVid, TypeAndMut, Visibility,
+    ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
+    PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
+    TypeAndMut, Visibility,
 };
 use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use rustc_ast::{self as ast, attr};
@@ -95,7 +95,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type ParamTy = ParamTy;
     type BoundTy = ty::BoundTy;
     type PlaceholderTy = ty::PlaceholderType;
-    type InferTy = InferTy;
 
     type ErrorGuaranteed = ErrorGuaranteed;
     type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
@@ -103,7 +102,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type AllocId = crate::mir::interpret::AllocId;
 
     type Const = ty::Const<'tcx>;
-    type InferConst = ty::InferConst;
     type AliasConst = ty::UnevaluatedConst<'tcx>;
     type PlaceholderConst = ty::PlaceholderConst;
     type ParamConst = ty::ParamConst;
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 559bf9fb825de..2436daf62cf2b 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -84,9 +84,7 @@ pub use self::closure::{
     CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
     RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
 };
-pub use self::consts::{
-    Const, ConstData, ConstInt, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree,
-};
+pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
 pub use self::context::{
     tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed,
 };
@@ -98,7 +96,7 @@ pub use self::sty::BoundRegionKind::*;
 pub use self::sty::{
     AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
     BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind,
-    ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, EffectVid, ExistentialPredicate,
+    CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, ExistentialPredicate,
     ExistentialProjection, ExistentialTraitRef, FnSig, GenSig, InlineConstArgs,
     InlineConstArgsParts, LateParamRegion, ParamConst, ParamTy, PolyExistentialPredicate,
     PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index ad070dcc9e385..d478677c36793 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -3018,7 +3018,8 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
 /// The implementation uses similar import discovery logic to that of 'use' suggestions.
 ///
 /// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`].
-fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
+// this is pub to be able to intra-doc-link it
+pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
     let mut map: FxHashMap<DefId, Symbol> = FxHashMap::default();
 
     if let TrimmedDefPaths::GoodPath = tcx.sess.opts.trimmed_def_paths {
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index e223ffd7c5d54..971acda33e233 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -202,34 +202,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTy<'tcx> {
     }
 }
 
-impl fmt::Debug for ty::InferConst {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            InferConst::Var(var) => write!(f, "{var:?}"),
-            InferConst::EffectVar(var) => write!(f, "{var:?}"),
-            InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
-        }
-    }
-}
-impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::InferConst {
-    fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
-        this: WithInfcx<'_, Infcx, &Self>,
-        f: &mut core::fmt::Formatter<'_>,
-    ) -> core::fmt::Result {
-        use ty::InferConst::*;
-        match this.infcx.universe_of_ct(*this.data) {
-            None => write!(f, "{:?}", this.data),
-            Some(universe) => match *this.data {
-                Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
-                EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
-                Fresh(_) => {
-                    unreachable!()
-                }
-            },
-        }
-    }
-}
-
 impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         WithInfcx::with_no_infcx(self).fmt(f)
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index b22ff5c57c305..ea0e179c00de0 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1608,24 +1608,6 @@ impl fmt::Debug for EarlyParamRegion {
     }
 }
 
-rustc_index::newtype_index! {
-    /// A **`const`** **v**ariable **ID**.
-    #[debug_format = "?{}c"]
-    pub struct ConstVid {}
-}
-
-rustc_index::newtype_index! {
-    /// An **effect** **v**ariable **ID**.
-    ///
-    /// Handling effect infer variables happens separately from const infer variables
-    /// because we do not want to reuse any of the const infer machinery. If we try to
-    /// relate an effect variable with a normal one, we would ICE, which can catch bugs
-    /// where we are not correctly using the effect var for an effect param. Fallback
-    /// is also implemented on top of having separate effect and normal const variables.
-    #[debug_format = "?{}e"]
-    pub struct EffectVid {}
-}
-
 rustc_index::newtype_index! {
     /// A **region** (lifetime) **v**ariable **ID**.
     #[derive(HashStable)]
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 13d7ebe1db065..b6d2228d4b8fb 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -110,7 +110,7 @@ pub(super) trait GoalKind<'tcx>:
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
         impl_def_id: DefId,
-    ) -> QueryResult<'tcx>;
+    ) -> Result<Candidate<'tcx>, NoSolution>;
 
     /// If the predicate contained an error, we want to avoid emitting unnecessary trait
     /// errors but still want to emit errors for other trait goals. We have some special
@@ -263,7 +263,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> Vec<Candidate<'tcx>> {
         debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
         if let Some(ambig) = self.assemble_self_ty_infer_ambiguity_response(goal) {
-            return ambig;
+            return vec![ambig];
         }
 
         let mut candidates = self.assemble_candidates_via_self_ty(goal, 0);
@@ -288,15 +288,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     fn assemble_self_ty_infer_ambiguity_response<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
-    ) -> Option<Vec<Candidate<'tcx>>> {
-        goal.predicate.self_ty().is_ty_var().then(|| {
-            vec![Candidate {
-                source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                result: self
-                    .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
-                    .unwrap(),
-            }]
-        })
+    ) -> Option<Candidate<'tcx>> {
+        if goal.predicate.self_ty().is_ty_var() {
+            debug!("adding self_ty_infer_ambiguity_response");
+            let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
+            let result = self
+                .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                .unwrap();
+            let mut dummy_probe = self.inspect.new_probe();
+            dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result: Ok(result) });
+            self.inspect.finish_probe(dummy_probe);
+            Some(Candidate { source, result })
+        } else {
+            None
+        }
     }
 
     /// Assemble candidates which apply to the self type. This only looks at candidate which
@@ -310,7 +315,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> Vec<Candidate<'tcx>> {
         debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
         if let Some(ambig) = self.assemble_self_ty_infer_ambiguity_response(goal) {
-            return ambig;
+            return vec![ambig];
         }
 
         let mut candidates = Vec::new();
@@ -395,8 +400,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
                 for &impl_def_id in impls_for_type {
                     match G::consider_impl_candidate(self, goal, impl_def_id) {
-                        Ok(result) => candidates
-                            .push(Candidate { source: CandidateSource::Impl(impl_def_id), result }),
+                        Ok(candidate) => candidates.push(candidate),
                         Err(NoSolution) => (),
                     }
                 }
@@ -514,8 +518,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
         for &impl_def_id in trait_impls.blanket_impls() {
             match G::consider_impl_candidate(self, goal, impl_def_id) {
-                Ok(result) => candidates
-                    .push(Candidate { source: CandidateSource::Impl(impl_def_id), result }),
+                Ok(candidate) => candidates.push(candidate),
                 Err(NoSolution) => (),
             }
         }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
index 6087b91679095..91fd48807a4d8 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs
@@ -1,5 +1,10 @@
+use crate::solve::assembly::Candidate;
+
 use super::EvalCtxt;
-use rustc_middle::traits::solve::{inspect, CandidateSource, QueryResult};
+use rustc_middle::traits::{
+    query::NoSolution,
+    solve::{inspect, CandidateSource, QueryResult},
+};
 use std::marker::PhantomData;
 
 pub(in crate::solve) struct ProbeCtxt<'me, 'a, 'tcx, F, T> {
@@ -36,6 +41,23 @@ where
     }
 }
 
+pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, 'tcx, F> {
+    cx: ProbeCtxt<'me, 'a, 'tcx, F, QueryResult<'tcx>>,
+    source: CandidateSource,
+}
+
+impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F>
+where
+    F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>,
+{
+    pub(in crate::solve) fn enter(
+        self,
+        f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
+    ) -> Result<Candidate<'tcx>, NoSolution> {
+        self.cx.enter(|ecx| f(ecx)).map(|result| Candidate { source: self.source, result })
+    }
+}
+
 impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
     /// `probe_kind` is only called when proof tree building is enabled so it can be
     /// as expensive as necessary to output the desired information.
@@ -69,20 +91,18 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
     pub(in crate::solve) fn probe_trait_candidate(
         &mut self,
         source: CandidateSource,
-    ) -> ProbeCtxt<
-        '_,
-        'a,
-        'tcx,
-        impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>,
-        QueryResult<'tcx>,
-    > {
-        ProbeCtxt {
-            ecx: self,
-            probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::TraitCandidate {
-                source,
-                result: *result,
+    ) -> TraitProbeCtxt<'_, 'a, 'tcx, impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>>
+    {
+        TraitProbeCtxt {
+            cx: ProbeCtxt {
+                ecx: self,
+                probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::TraitCandidate {
+                    source,
+                    result: *result,
+                },
+                _result: PhantomData,
             },
-            _result: PhantomData,
+            source,
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs b/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs
index 7fb550aa3e063..6c29ce492df0e 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs
@@ -1,6 +1,6 @@
 use crate::traits::{check_args_compatible, specialization_graph};
 
-use super::assembly::{self, structural_traits};
+use super::assembly::{self, structural_traits, Candidate};
 use super::EvalCtxt;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -154,7 +154,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
         impl_def_id: DefId,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = ecx.tcx();
 
         let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx);
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 0f30b49314b03..a0c065dfa03ba 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -1,12 +1,14 @@
 //! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
 
-use super::assembly::{self, structural_traits};
+use super::assembly::{self, structural_traits, Candidate};
 use super::{EvalCtxt, SolverMode};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{LangItem, Movability};
 use rustc_infer::traits::query::NoSolution;
 use rustc_middle::traits::solve::inspect::ProbeKind;
-use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult};
+use rustc_middle::traits::solve::{
+    CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult,
+};
 use rustc_middle::traits::{BuiltinImplSource, Reveal};
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
@@ -38,7 +40,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, TraitPredicate<'tcx>>,
         impl_def_id: DefId,
-    ) -> QueryResult<'tcx> {
+    ) -> Result<Candidate<'tcx>, NoSolution> {
         let tcx = ecx.tcx();
 
         let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
@@ -63,7 +65,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             },
         };
 
-        ecx.probe_misc_candidate("impl").enter(|ecx| {
+        ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
             let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
 
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 362a734818c1e..e6e05d0adc627 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -25,7 +25,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::{util, TraitEngine};
 use rustc_middle::traits::query::NoSolution;
-use rustc_middle::traits::solve::{Certainty, Goal};
+use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_middle::traits::specialization_graph::OverlapMode;
 use rustc_middle::traits::DefiningAnchor;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
@@ -397,6 +397,8 @@ fn impl_intersection_has_negative_obligation(
 ) -> bool {
     debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id);
 
+    // N.B. We need to unify impl headers *with* intercrate mode, even if proving negative predicates
+    // do not need intercrate mode enabled.
     let ref infcx = tcx.infer_ctxt().intercrate(true).with_next_trait_solver(true).build();
     let root_universe = infcx.universe();
     assert_eq!(root_universe, ty::UniverseIndex::ROOT);
@@ -415,13 +417,6 @@ fn impl_intersection_has_negative_obligation(
         return false;
     };
 
-    plug_infer_with_placeholders(
-        infcx,
-        root_universe,
-        (impl1_header.impl_args, impl2_header.impl_args),
-    );
-    let param_env = infcx.resolve_vars_if_possible(param_env);
-
     // FIXME(with_negative_coherence): the infcx has constraints from equating
     // the impl headers. We should use these constraints as assumptions, not as
     // requirements, when proving the negated where clauses below.
@@ -429,6 +424,13 @@ fn impl_intersection_has_negative_obligation(
     drop(infcx.take_registered_region_obligations());
     drop(infcx.take_and_reset_region_constraints());
 
+    plug_infer_with_placeholders(
+        infcx,
+        root_universe,
+        (impl1_header.impl_args, impl2_header.impl_args),
+    );
+    let param_env = infcx.resolve_vars_if_possible(param_env);
+
     util::elaborate(tcx, tcx.predicates_of(impl2_def_id).instantiate(tcx, impl2_header.impl_args))
         .any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env))
 }
@@ -554,7 +556,11 @@ fn try_prove_negated_where_clause<'tcx>(
         return false;
     };
 
-    let ref infcx = root_infcx.fork();
+    // N.B. We don't need to use intercrate mode here because we're trying to prove
+    // the *existence* of a negative goal, not the non-existence of a positive goal.
+    // Without this, we over-eagerly register coherence ambiguity candidates when
+    // impl candidates do exist.
+    let ref infcx = root_infcx.fork_with_intercrate(false);
     let ocx = ObligationCtxt::new(infcx);
 
     ocx.register_obligation(Obligation::new(
@@ -1019,6 +1025,28 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
             _ => return ControlFlow::Continue(()),
         };
 
+        // Add ambiguity causes for reservation impls.
+        for cand in goal.candidates() {
+            if let inspect::ProbeKind::TraitCandidate {
+                source: CandidateSource::Impl(def_id),
+                result: Ok(_),
+            } = cand.kind()
+            {
+                if let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) {
+                    let value = infcx
+                        .tcx
+                        .get_attr(def_id, sym::rustc_reservation_impl)
+                        .and_then(|a| a.value_str());
+                    if let Some(value) = value {
+                        self.causes.insert(IntercrateAmbiguityCause::ReservationImpl {
+                            message: value.to_string(),
+                        });
+                    }
+                }
+            }
+        }
+
+        // Add ambiguity causes for unknowable goals.
         let mut ambiguity_cause = None;
         for cand in goal.candidates() {
             // FIXME: boiiii, using string comparisions here sure is scuffed.
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs
index a014a4f38caf5..1cdd51d68dc68 100644
--- a/compiler/rustc_type_ir/src/const_kind.rs
+++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -22,7 +22,7 @@ pub enum ConstKind<I: Interner> {
     Param(I::ParamConst),
 
     /// Infer the value of the const.
-    Infer(I::InferConst),
+    Infer(InferConst),
 
     /// Bound const variable, used only when preparing a trait query.
     Bound(DebruijnIndex, I::BoundConst),
@@ -65,7 +65,6 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
 impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
 where
     I::ParamConst: HashStable<CTX>,
-    I::InferConst: HashStable<CTX>,
     I::BoundConst: HashStable<CTX>,
     I::PlaceholderConst: HashStable<CTX>,
     I::AliasConst: HashStable<CTX>,
@@ -136,3 +135,77 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
         }
     }
 }
+
+rustc_index::newtype_index! {
+    /// A **`const`** **v**ariable **ID**.
+    #[debug_format = "?{}c"]
+    #[gate_rustc_only]
+    pub struct ConstVid {}
+}
+
+rustc_index::newtype_index! {
+    /// An **effect** **v**ariable **ID**.
+    ///
+    /// Handling effect infer variables happens separately from const infer variables
+    /// because we do not want to reuse any of the const infer machinery. If we try to
+    /// relate an effect variable with a normal one, we would ICE, which can catch bugs
+    /// where we are not correctly using the effect var for an effect param. Fallback
+    /// is also implemented on top of having separate effect and normal const variables.
+    #[debug_format = "?{}e"]
+    #[gate_rustc_only]
+    pub struct EffectVid {}
+}
+
+/// An inference variable for a const, for use in const generics.
+#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
+#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
+pub enum InferConst {
+    /// Infer the value of the const.
+    Var(ConstVid),
+    /// Infer the value of the effect.
+    ///
+    /// For why this is separate from the `Var` variant above, see the
+    /// documentation on `EffectVid`.
+    EffectVar(EffectVid),
+    /// A fresh const variable. See `infer::freshen` for more details.
+    Fresh(u32),
+}
+
+impl fmt::Debug for InferConst {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            InferConst::Var(var) => write!(f, "{var:?}"),
+            InferConst::EffectVar(var) => write!(f, "{var:?}"),
+            InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
+        }
+    }
+}
+impl<I: Interner> DebugWithInfcx<I> for InferConst {
+    fn fmt<Infcx: InferCtxtLike<Interner = I>>(
+        this: WithInfcx<'_, Infcx, &Self>,
+        f: &mut core::fmt::Formatter<'_>,
+    ) -> core::fmt::Result {
+        match this.infcx.universe_of_ct(*this.data) {
+            None => write!(f, "{:?}", this.data),
+            Some(universe) => match *this.data {
+                InferConst::Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
+                InferConst::EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
+                InferConst::Fresh(_) => {
+                    unreachable!()
+                }
+            },
+        }
+    }
+}
+
+#[cfg(feature = "nightly")]
+impl<CTX> HashStable<CTX> for InferConst {
+    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
+        match self {
+            InferConst::Var(_) | InferConst::EffectVar(_) => {
+                panic!("const variables should not be hashed: {self:?}")
+            }
+            InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
+        }
+    }
+}
diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs
index 4ea3eb3e84f43..db29ec9da8c9e 100644
--- a/compiler/rustc_type_ir/src/debug.rs
+++ b/compiler/rustc_type_ir/src/debug.rs
@@ -1,4 +1,4 @@
-use crate::{Interner, UniverseIndex};
+use crate::{InferConst, InferTy, Interner, UniverseIndex};
 
 use core::fmt;
 use std::marker::PhantomData;
@@ -6,15 +6,14 @@ use std::marker::PhantomData;
 pub trait InferCtxtLike {
     type Interner: Interner;
 
-    fn universe_of_ty(&self, ty: <Self::Interner as Interner>::InferTy) -> Option<UniverseIndex>;
+    fn universe_of_ty(&self, ty: InferTy) -> Option<UniverseIndex>;
 
     fn universe_of_lt(
         &self,
         lt: <Self::Interner as Interner>::InferRegion,
     ) -> Option<UniverseIndex>;
 
-    fn universe_of_ct(&self, ct: <Self::Interner as Interner>::InferConst)
-    -> Option<UniverseIndex>;
+    fn universe_of_ct(&self, ct: InferConst) -> Option<UniverseIndex>;
 }
 
 pub struct NoInfcx<I>(PhantomData<I>);
@@ -22,11 +21,11 @@ pub struct NoInfcx<I>(PhantomData<I>);
 impl<I: Interner> InferCtxtLike for NoInfcx<I> {
     type Interner = I;
 
-    fn universe_of_ty(&self, _ty: <I as Interner>::InferTy) -> Option<UniverseIndex> {
+    fn universe_of_ty(&self, _ty: InferTy) -> Option<UniverseIndex> {
         None
     }
 
-    fn universe_of_ct(&self, _ct: <I as Interner>::InferConst) -> Option<UniverseIndex> {
+    fn universe_of_ct(&self, _ct: InferConst) -> Option<UniverseIndex> {
         None
     }
 
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index da504c54fddd9..170a791fb54d6 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -27,7 +27,6 @@ pub trait Interner: Sized {
     type ParamTy: Clone + Debug + Hash + Ord;
     type BoundTy: Clone + Debug + Hash + Ord;
     type PlaceholderTy: Clone + Debug + Hash + Ord;
-    type InferTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
 
     // Things stored inside of tys
     type ErrorGuaranteed: Clone + Debug + Hash + Ord;
@@ -37,7 +36,6 @@ pub trait Interner: Sized {
 
     // Kinds of consts
     type Const: Clone + DebugWithInfcx<Self> + Hash + Ord;
-    type InferConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
     type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
     type PlaceholderConst: Clone + Debug + Hash + Ord;
     type ParamConst: Clone + Debug + Hash + Ord;
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index f31c5069b155d..53446c41f31c5 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -281,7 +281,7 @@ pub enum TyKind<I: Interner> {
     /// correctly deal with higher ranked types. Though unlike placeholders,
     /// that universe is stored in the `InferCtxt` instead of directly
     /// inside of the type.
-    Infer(I::InferTy),
+    Infer(InferTy),
 
     /// A placeholder for a type which could not be computed; this is
     /// propagated to avoid useless error messages.
@@ -491,7 +491,6 @@ where
     I::BoundTy: HashStable<CTX>,
     I::ParamTy: HashStable<CTX>,
     I::PlaceholderTy: HashStable<CTX>,
-    I::InferTy: HashStable<CTX>,
     I::ErrorGuaranteed: HashStable<CTX>,
 {
     #[inline]
@@ -922,7 +921,7 @@ impl fmt::Debug for InferTy {
     }
 }
 
-impl<I: Interner<InferTy = InferTy>> DebugWithInfcx<I> for InferTy {
+impl<I: Interner> DebugWithInfcx<I> for InferTy {
     fn fmt<Infcx: InferCtxtLike<Interner = I>>(
         this: WithInfcx<'_, Infcx, &Self>,
         f: &mut fmt::Formatter<'_>,
diff --git a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr
index 9f9d4bd8d6c05..b3bf2f924fc3e 100644
--- a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr
+++ b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr
@@ -77,6 +77,8 @@ LL |     reg.register_univ(Box::new(CapturePass::new(&reg.sess_mut)));
    |     |                 |                         immutable borrow occurs here
    |     |                 cast requires that `reg.sess_mut` is borrowed for `'a`
    |     mutable borrow occurs here
+   |
+   = note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
 
 error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
   --> $DIR/two-phase-surprise-no-conflict.rs:144:5
@@ -119,6 +121,8 @@ LL |     reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
    |     |                 |                             first mutable borrow occurs here
    |     |                 cast requires that `reg.sess_mut` is borrowed for `'a`
    |     second mutable borrow occurs here
+   |
+   = note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
 
 error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
   --> $DIR/two-phase-surprise-no-conflict.rs:158:53
diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs b/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs
index 0e16d12a18114..531977d6dac24 100644
--- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs
@@ -1,5 +1,9 @@
 // revisions: stock with_negative_coherence
+
 //[with_negative_coherence] known-bug: unknown
+// Ideally this would work, but we don't use `&'a T` to imply that `T: 'a`
+// which is required for `&'a T: !MyPredicate` to hold. This is similar to the
+// test `negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr`
 
 #![feature(negative_impls)]
 #![cfg_attr(with_negative_coherence, feature(with_negative_coherence))]
diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
index 097cc4e0fe3e6..6d6e163b2066d 100644
--- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
-  --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
+  --> $DIR/coherence-negative-outlives-lifetimes.rs:18:1
    |
 LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
    | ---------------------------------------------- first implementation here
diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
index 097cc4e0fe3e6..6d6e163b2066d 100644
--- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
-  --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1
+  --> $DIR/coherence-negative-outlives-lifetimes.rs:18:1
    |
 LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
    | ---------------------------------------------- first implementation here
diff --git a/tests/ui/coherence/coherence-overlap-with-regions.rs b/tests/ui/coherence/coherence-overlap-with-regions.rs
index 9945c8e6cfd7b..32f01f4180103 100644
--- a/tests/ui/coherence/coherence-overlap-with-regions.rs
+++ b/tests/ui/coherence/coherence-overlap-with-regions.rs
@@ -1,10 +1,4 @@
-// known-bug: unknown
-
-// This fails because we currently perform negative coherence in coherence mode.
-// This means that when looking for a negative predicate, we also assemble a
-// coherence-unknowable predicate. Since confirming the negative impl has region
-// obligations, we don't prefer the impl over the unknowable predicate
-// unconditionally and instead flounder.
+// check-pass
 
 #![feature(negative_impls)]
 #![feature(rustc_attrs)]
diff --git a/tests/ui/coherence/coherence-overlap-with-regions.stderr b/tests/ui/coherence/coherence-overlap-with-regions.stderr
deleted file mode 100644
index fd25f0978bad2..0000000000000
--- a/tests/ui/coherence/coherence-overlap-with-regions.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0119]: conflicting implementations of trait `Bar` for type `&_`
-  --> $DIR/coherence-overlap-with-regions.rs:20:1
-   |
-LL | impl<T: Foo> Bar for T {}
-   | ---------------------- first implementation here
-LL | impl<T> Bar for &T where T: 'static {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr
index 4cf50b4f208e3..442934a894927 100644
--- a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr
+++ b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Bar` for type `&_`
-  --> $DIR/negative-coherence-considering-regions.rs:22:1
+  --> $DIR/negative-coherence-considering-regions.rs:16:1
    |
 LL | impl<T> Bar for T where T: Foo {}
    | ------------------------------ first implementation here
diff --git a/tests/ui/coherence/negative-coherence-considering-regions.rs b/tests/ui/coherence/negative-coherence-considering-regions.rs
index 597a597262846..a43ad19eca7c0 100644
--- a/tests/ui/coherence/negative-coherence-considering-regions.rs
+++ b/tests/ui/coherence/negative-coherence-considering-regions.rs
@@ -1,11 +1,5 @@
 // revisions: any_lt static_lt
-//[static_lt] known-bug: unknown
-
-// This fails because we currently perform negative coherence in coherence mode.
-// This means that when looking for a negative predicate, we also assemble a
-// coherence-unknowable predicate. Since confirming the negative impl has region
-// obligations, we don't prefer the impl over the unknowable predicate
-// unconditionally and instead flounder.
+//[static_lt] check-pass
 
 #![feature(negative_impls)]
 #![feature(with_negative_coherence)]
diff --git a/tests/ui/coherence/negative-coherence-considering-regions.static_lt.stderr b/tests/ui/coherence/negative-coherence-considering-regions.static_lt.stderr
deleted file mode 100644
index 87e7be2aa44a9..0000000000000
--- a/tests/ui/coherence/negative-coherence-considering-regions.static_lt.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `Bar` for type `&'static _`
-  --> $DIR/negative-coherence-considering-regions.rs:26:1
-   |
-LL | impl<T> Bar for T where T: Foo {}
-   | ------------------------------ first implementation here
-...
-LL | impl<T> Bar for &'static T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&'static _`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/dropck/dropck_trait_cycle_checked.stderr b/tests/ui/dropck/dropck_trait_cycle_checked.stderr
index 4d4f7b9df1179..63fd07a91633d 100644
--- a/tests/ui/dropck/dropck_trait_cycle_checked.stderr
+++ b/tests/ui/dropck/dropck_trait_cycle_checked.stderr
@@ -8,6 +8,8 @@ LL |     o1.set0(&o2);
 ...
 LL | }
    | - `o2` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
 
 error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:112:13
@@ -20,6 +22,8 @@ LL |     o1.set1(&o3);
 ...
 LL | }
    | - `o3` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
 
 error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:113:13
@@ -32,6 +36,8 @@ LL |     o2.set0(&o2);
 ...
 LL | }
    | - `o2` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
 
 error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:114:13
@@ -44,6 +50,8 @@ LL |     o2.set1(&o3);
 ...
 LL | }
    | - `o3` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
 
 error[E0597]: `o1` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:115:13
@@ -56,6 +64,8 @@ LL |     o3.set0(&o1);
 LL |     o3.set1(&o2);
 LL | }
    | - `o1` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
 
 error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:116:13
@@ -67,6 +77,8 @@ LL |     o3.set1(&o2);
    |             ^^^ borrowed value does not live long enough
 LL | }
    | - `o2` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/impl-trait/auto-trait-coherence.next.stderr b/tests/ui/impl-trait/auto-trait-coherence.next.stderr
index cee359997b4ff..7833ac688babf 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.next.stderr
+++ b/tests/ui/impl-trait/auto-trait-coherence.next.stderr
@@ -6,8 +6,6 @@ LL | impl<T: Send> AnotherTrait for T {}
 ...
 LL | impl AnotherTrait for D<OpaqueType> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
-   |
-   = note: upstream crates may add a new impl of trait `std::marker::Send` for type `OpaqueType` in future versions
 
 error: aborting due to previous error
 
diff --git a/tests/ui/never_type/never-from-impl-is-reserved.stderr b/tests/ui/never_type/never-from-impl-is-reserved.current.stderr
similarity index 92%
rename from tests/ui/never_type/never-from-impl-is-reserved.stderr
rename to tests/ui/never_type/never-from-impl-is-reserved.current.stderr
index 871c512052821..6c71785de2897 100644
--- a/tests/ui/never_type/never-from-impl-is-reserved.stderr
+++ b/tests/ui/never_type/never-from-impl-is-reserved.current.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo`
-  --> $DIR/never-from-impl-is-reserved.rs:10:1
+  --> $DIR/never-from-impl-is-reserved.rs:13:1
    |
 LL | impl MyTrait for MyFoo {}
    | ---------------------- first implementation here
diff --git a/tests/ui/never_type/never-from-impl-is-reserved.next.stderr b/tests/ui/never_type/never-from-impl-is-reserved.next.stderr
new file mode 100644
index 0000000000000..6c71785de2897
--- /dev/null
+++ b/tests/ui/never_type/never-from-impl-is-reserved.next.stderr
@@ -0,0 +1,14 @@
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo`
+  --> $DIR/never-from-impl-is-reserved.rs:13:1
+   |
+LL | impl MyTrait for MyFoo {}
+   | ---------------------- first implementation here
+LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
+LL | impl<T> MyTrait for T where T: From<!> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
+   |
+   = note: permitting this impl would forbid us from adding `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/never_type/never-from-impl-is-reserved.rs b/tests/ui/never_type/never-from-impl-is-reserved.rs
index 9d16015bdc129..f358e045cf019 100644
--- a/tests/ui/never_type/never-from-impl-is-reserved.rs
+++ b/tests/ui/never_type/never-from-impl-is-reserved.rs
@@ -1,5 +1,8 @@
 // check that the `for<T> T: From<!>` impl is reserved
 
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next-coherence
+
 #![feature(never_type)]
 
 pub struct MyFoo;
diff --git a/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs b/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs
new file mode 100644
index 0000000000000..ce7e60356f279
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/edition-gated-async-move-syntax.rs
@@ -0,0 +1,39 @@
+// force-host
+// no-prefer-dynamic
+
+// Proc macro helper for issue #89699, used by tests/ui/proc-macro/edition-gated-async-move-
+// syntax-issue89699.rs, emitting an `async move` closure. This syntax is only available in
+// editions 2018 and up, but is used in edition 2015 in the test.
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_attribute]
+pub fn foo(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    let tt = item.into_iter().next().unwrap();
+    let sp = tt.span();
+    let mut arg = TokenStream::new();
+    let mut g = Group::new(Delimiter::Brace, TokenStream::new());
+    g.set_span(sp);
+    arg.extend([
+        TokenTree::Ident(Ident::new("async", sp)),
+        TokenTree::Ident(Ident::new("move", sp)),
+        TokenTree::Group(g),
+    ]);
+    let mut body = TokenStream::new();
+    body.extend([
+        TokenTree::Ident(Ident::new("async_main", sp)),
+        TokenTree::Group(Group::new(Delimiter::Parenthesis, arg)),
+    ]);
+
+    let mut ret = TokenStream::new();
+    ret.extend([
+        TokenTree::Ident(Ident::new("fn", sp)),
+        TokenTree::Ident(Ident::new("main", sp)),
+        TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+        TokenTree::Group(Group::new(Delimiter::Brace, body)),
+    ]);
+    ret
+}
diff --git a/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs
new file mode 100644
index 0000000000000..1a9d4601acafe
--- /dev/null
+++ b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.rs
@@ -0,0 +1,10 @@
+// aux-build:edition-gated-async-move-syntax.rs
+// edition: 2015
+
+// Non-regression test for issue #89699, where a proc-macro emitting syntax only available in
+// edition 2018 and up (`async move`) is used on edition 2015
+
+extern crate edition_gated_async_move_syntax;
+
+#[edition_gated_async_move_syntax::foo]
+fn foo() {} //~ ERROR `async move` blocks are only allowed in Rust 2018 or later
diff --git a/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr
new file mode 100644
index 0000000000000..a0dcc84eef8fa
--- /dev/null
+++ b/tests/ui/proc-macro/edition-gated-async-move-syntax-issue89699.stderr
@@ -0,0 +1,8 @@
+error: `async move` blocks are only allowed in Rust 2018 or later
+  --> $DIR/edition-gated-async-move-syntax-issue89699.rs:10:1
+   |
+LL | fn foo() {}
+   | ^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
index 4207c2f80b88f..5d5f325e4b473 100644
--- a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -6,9 +6,6 @@ LL | impl<T: Copy> Trait for T {}
 LL | struct LocalTy;
 LL | impl Trait for <LocalTy as Overflow>::Assoc {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<LocalTy as Overflow>::Assoc`
-   |
-   = note: downstream crates may implement trait `std::marker::Sized` for type `<LocalTy as Overflow>::Assoc`
-   = note: downstream crates may implement trait `std::marker::Copy` for type `<LocalTy as Overflow>::Assoc`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr b/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr
index e5a3c3f5cc4b7..393350ea3f12a 100644
--- a/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr
+++ b/tests/ui/traits/reservation-impl/coherence-conflict.next.stderr
@@ -5,6 +5,8 @@ LL | impl OtherTrait for () {}
    | ---------------------- first implementation here
 LL | impl<T: MyTrait> OtherTrait for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+   |
+   = note: this impl is reserved
 
 error: aborting due to previous error
 
diff --git a/tests/ui/traits/trait-object-lifetime-default-note.rs b/tests/ui/traits/trait-object-lifetime-default-note.rs
new file mode 100644
index 0000000000000..31e3eb4ba4155
--- /dev/null
+++ b/tests/ui/traits/trait-object-lifetime-default-note.rs
@@ -0,0 +1,16 @@
+trait A {}
+
+impl<T> A for T {}
+
+fn main() {
+    let local = 0; //~ NOTE binding `local` declared here
+    let r = &local; //~ ERROR `local` does not live long enough
+    //~| NOTE borrowed value does not live long enough
+    //~| NOTE due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
+    require_box(Box::new(r));
+    //~^ NOTE cast requires that `local` is borrowed for `'static`
+
+    let _ = 0;
+} //~ NOTE `local` dropped here while still borrowed
+
+fn require_box(_a: Box<dyn A>) {}
diff --git a/tests/ui/traits/trait-object-lifetime-default-note.stderr b/tests/ui/traits/trait-object-lifetime-default-note.stderr
new file mode 100644
index 0000000000000..b6dd67538993c
--- /dev/null
+++ b/tests/ui/traits/trait-object-lifetime-default-note.stderr
@@ -0,0 +1,19 @@
+error[E0597]: `local` does not live long enough
+  --> $DIR/trait-object-lifetime-default-note.rs:7:13
+   |
+LL |     let local = 0;
+   |         ----- binding `local` declared here
+LL |     let r = &local;
+   |             ^^^^^^ borrowed value does not live long enough
+...
+LL |     require_box(Box::new(r));
+   |                 ----------- cast requires that `local` is borrowed for `'static`
+...
+LL | }
+   | - `local` dropped here while still borrowed
+   |
+   = note: due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs
new file mode 100644
index 0000000000000..79fb643eacd01
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.rs
@@ -0,0 +1,36 @@
+#![deny(deref_into_dyn_supertrait)]
+#![feature(trait_upcasting)] // remove this and the test compiles
+
+use std::ops::Deref;
+
+trait Bar<T> {}
+impl<T, U> Bar<U> for T {}
+
+trait Foo: Bar<i32> {
+    fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a);
+}
+
+impl Foo for () {
+    fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a) {
+        self
+    }
+}
+
+impl<'a> Deref for dyn Foo + 'a {
+    type Target = dyn Bar<u32> + 'a;
+
+    fn deref(&self) -> &Self::Target {
+        self.as_dyn_bar_u32()
+    }
+}
+
+fn take_dyn<T>(x: &dyn Bar<T>) -> T {
+    todo!()
+}
+
+fn main() {
+    let x: &dyn Foo = &();
+    let y = take_dyn(x);
+    let z: u32 = y;
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr
new file mode 100644
index 0000000000000..cfd6f7f175ff1
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/inference-behavior-change-deref.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/inference-behavior-change-deref.rs:34:18
+   |
+LL |     let z: u32 = y;
+   |            ---   ^ expected `u32`, found `i32`
+   |            |
+   |            expected due to this
+   |
+help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
+   |
+LL |     let z: u32 = y.try_into().unwrap();
+   |                   ++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs
new file mode 100644
index 0000000000000..b3f14a5f256e5
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.rs
@@ -0,0 +1,18 @@
+#![deny(deref_into_dyn_supertrait)]
+
+use std::ops::Deref;
+
+trait Bar<'a> {}
+trait Foo<'a>: Bar<'a> {}
+
+impl<'a> Deref for dyn Foo<'a> {
+    //~^ ERROR dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
+    //~| WARN this will change its meaning in a future release!
+    type Target = dyn Bar<'a>;
+
+    fn deref(&self) -> &Self::Target {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr
new file mode 100644
index 0000000000000..250bcabc69820
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny-regions.stderr
@@ -0,0 +1,19 @@
+error: `dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
+  --> $DIR/migrate-lint-deny-regions.rs:8:1
+   |
+LL | impl<'a> Deref for dyn Foo<'a> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     type Target = dyn Bar<'a>;
+   |     -------------------------- target type is set here
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
+note: the lint level is defined here
+  --> $DIR/migrate-lint-deny-regions.rs:1:9
+   |
+LL | #![deny(deref_into_dyn_supertrait)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs
index d624187561ed7..114d2c249da06 100644
--- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny.rs
@@ -1,16 +1,14 @@
 #![deny(deref_into_dyn_supertrait)]
 
-extern crate core;
-
-use core::ops::Deref;
+use std::ops::Deref;
 
 // issue 89190
 trait A {}
 trait B: A {}
 
 impl<'a> Deref for dyn 'a + B {
-    //~^ ERROR `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
-    //~| WARN this was previously accepted by the compiler but is being phased out;
+    //~^ ERROR `dyn B` implements `Deref` with supertrait `A` as target
+    //~| WARN this will change its meaning in a future release!
 
     type Target = dyn A;
     fn deref(&self) -> &Self::Target {
diff --git a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr
index 4533b1163425c..c8b683c23c183 100644
--- a/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr
+++ b/tests/ui/traits/trait-upcasting/migrate-lint-deny.stderr
@@ -1,5 +1,5 @@
-error: `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
-  --> $DIR/migrate-lint-deny.rs:11:1
+error: `dyn B` implements `Deref` with supertrait `A` as target
+  --> $DIR/migrate-lint-deny.rs:9:1
    |
 LL | impl<'a> Deref for dyn 'a + B {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | impl<'a> Deref for dyn 'a + B {
 LL |     type Target = dyn A;
    |     -------------------- target type is set here
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this will change its meaning in a future release!
    = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
 note: the lint level is defined here
   --> $DIR/migrate-lint-deny.rs:1:9
diff --git a/tests/ui/treat-err-as-bug/delay_span_bug.rs b/tests/ui/treat-err-as-bug/delay_span_bug.rs
index 533c8d1ec8f51..f667f8eb99625 100644
--- a/tests/ui/treat-err-as-bug/delay_span_bug.rs
+++ b/tests/ui/treat-err-as-bug/delay_span_bug.rs
@@ -1,7 +1,7 @@
 // compile-flags: -Ztreat-err-as-bug
 // failure-status: 101
 // error-pattern: aborting due to `-Z treat-err-as-bug=1`
-// error-pattern: [trigger_delay_span_bug] triggering a delay span bug
+// error-pattern: [trigger_delay_span_bug] triggering a delay span bug for testing incremental
 // normalize-stderr-test "note: .*\n\n" -> ""
 // normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> ""
 // rustc-env:RUST_BACKTRACE=0
diff --git a/tests/ui/treat-err-as-bug/delay_span_bug.stderr b/tests/ui/treat-err-as-bug/delay_span_bug.stderr
index 22c6175048a63..06a31ae86b258 100644
--- a/tests/ui/treat-err-as-bug/delay_span_bug.stderr
+++ b/tests/ui/treat-err-as-bug/delay_span_bug.stderr
@@ -7,5 +7,5 @@ LL | fn main() {}
 error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
-#0 [trigger_delay_span_bug] triggering a delay span bug
+#0 [trigger_delay_span_bug] triggering a delay span bug for testing incremental
 end of query stack
diff --git a/tests/ui/typeck/issue-114529-illegal-break-with-value.rs b/tests/ui/typeck/issue-114529-illegal-break-with-value.rs
index 613d1b6343a34..353a935e37313 100644
--- a/tests/ui/typeck/issue-114529-illegal-break-with-value.rs
+++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.rs
@@ -17,4 +17,10 @@ fn main() {
         };
         51
     }];
+
+    while true {
+        break (|| { //~ ERROR `break` with value from a `while` loop
+            let local = 9;
+        });
+    }
 }
diff --git a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
index 4d6c27bbbd03b..731f234c162ad 100644
--- a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
+++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
@@ -24,6 +24,21 @@ help: use `break` on its own without a value inside this `while` loop
 LL |             break;
    |             ~~~~~
 
-error: aborting due to 2 previous errors
+error[E0571]: `break` with value from a `while` loop
+  --> $DIR/issue-114529-illegal-break-with-value.rs:22:9
+   |
+LL |       while true {
+   |       ---------- you can't `break` with a value in a `while` loop
+LL | /         break (|| {
+LL | |             let local = 9;
+LL | |         });
+   | |__________^ can only break with a value inside `loop` or breakable block
+   |
+help: use `break` on its own without a value inside this `while` loop
+   |
+LL |         break;
+   |         ~~~~~
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0571`.