about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs4
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl6
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/errs.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs133
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs69
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/test_type_match.rs15
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs4
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs4
-rw-r--r--compiler/rustc_infer/src/infer/relate/glb.rs9
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lub.rs8
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs9
-rw-r--r--compiler/rustc_mir_build/src/build/matches/match_pair.rs46
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs22
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs7
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs6
-rw-r--r--compiler/rustc_parse/src/errors.rs3
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/_match.rs12
-rw-r--r--compiler/rustc_type_ir/src/relate.rs25
-rw-r--r--library/test/src/test_result.rs15
-rw-r--r--src/bootstrap/defaults/config.tools.toml4
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh12
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css8
-rw-r--r--tests/rustdoc-gui/src/lib2/lib.rs1
-rw-r--r--tests/rustdoc-gui/type-declation-overflow.goml6
-rw-r--r--tests/ui/abi/statics/static-mut-foreign.stderr4
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.stderr2
-rw-r--r--tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr2
-rw-r--r--tests/ui/borrowck/issue-20801.stderr2
-rw-r--r--tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr6
-rw-r--r--tests/ui/consts/const_let_assign2.stderr2
-rw-r--r--tests/ui/drop/issue-23338-ensure-param-drop-order.stderr2
-rw-r--r--tests/ui/drop/issue-23611-enum-swap-in-drop.stderr2
-rw-r--r--tests/ui/issues/issue-54410.stderr2
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr8
-rw-r--r--tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr2
-rw-r--r--tests/ui/parser/issues/issue-101477-enum.stderr5
-rw-r--r--tests/ui/parser/issues/issue-101477-let.stderr5
-rw-r--r--tests/ui/parser/recover/unicode-double-equals-recovery.rs3
-rw-r--r--tests/ui/parser/recover/unicode-double-equals-recovery.stderr24
-rw-r--r--tests/ui/static/reference-to-mut-static-safe.e2021.stderr2
-rw-r--r--tests/ui/static/reference-to-mut-static-safe.e2024.stderr2
-rw-r--r--tests/ui/static/reference-to-mut-static-unsafe-fn.stderr12
-rw-r--r--tests/ui/static/reference-to-mut-static.e2021.stderr12
-rw-r--r--tests/ui/static/reference-to-mut-static.e2024.stderr12
-rw-r--r--tests/ui/static/safe-extern-statics-mut.stderr4
-rw-r--r--tests/ui/statics/issue-15261.stderr2
-rw-r--r--tests/ui/statics/static-mut-xc.stderr4
-rw-r--r--tests/ui/statics/static-recursive.stderr2
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.rs1
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr4
-rw-r--r--tests/ui/test-attrs/test-panic-abort.rs1
-rw-r--r--tests/ui/test-attrs/test-panic-abort.run.stdout2
-rw-r--r--tests/ui/traits/issue-105231.rs4
-rw-r--r--tests/ui/traits/issue-105231.stderr22
-rw-r--r--tests/ui/variance/variance-unused-type-param.rs10
-rw-r--r--tests/ui/variance/variance-unused-type-param.stderr41
63 files changed, 447 insertions, 247 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index ea4a94e57b3..8da4d80badf 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -313,10 +313,6 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
         self.type_checker.infcx.tcx
     }
 
-    fn tag(&self) -> &'static str {
-        "nll::subtype"
-    }
-
     #[instrument(skip(self, info), level = "trace", ret)]
     fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
         &mut self,
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 24c5377a3b1..b43559f4225 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -382,6 +382,10 @@ hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is no
 hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
     .label = `Self` is not a generic argument, but an alias to the type of the {$what}
 
+hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is only used recursively
+    .label = {$param_def_kind} must be used non-recursively in the definition
+    .note = all type parameters must be used in a non-recursive way in order to constrain their variance
+
 hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
     .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
 
@@ -549,6 +553,8 @@ hir_analysis_unused_generic_parameter =
     {$param_def_kind} `{$param_name}` is never used
     .label = unused {$param_def_kind}
     .const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead
+    .usage_spans = `{$param_name}` is named here, but is likely unused in the containing type
+
 hir_analysis_unused_generic_parameter_adt_help =
     consider removing `{$param_name}`, referring to it in a field, or using a marker such as `{$phantom_data}`
 hir_analysis_unused_generic_parameter_adt_no_phantom_data_help =
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index bf8ef18c04f..dbc265ad3ff 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1572,6 +1572,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
                 param_name,
                 param_def_kind: tcx.def_descr(param.def_id),
                 help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
+                usage_spans: vec![],
                 const_param_help,
             });
             diag.code(E0091);
diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs
index 17cb20df754..19a0476e630 100644
--- a/compiler/rustc_hir_analysis/src/check/errs.rs
+++ b/compiler/rustc_hir_analysis/src/check/errs.rs
@@ -1,5 +1,4 @@
 use rustc_hir as hir;
-use rustc_hir_pretty::qpath_to_string;
 use rustc_lint_defs::builtin::STATIC_MUT_REFS;
 use rustc_middle::ty::{Mutability, TyCtxt};
 use rustc_span::Span;
@@ -12,9 +11,17 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) {
     let hir_id = expr.hir_id;
     if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind
         && matches!(borrow_kind, hir::BorrowKind::Ref)
-        && let Some(var) = path_if_static_mut(tcx, expr)
+        && path_if_static_mut(expr)
     {
-        handle_static_mut_ref(tcx, span, var, span.edition().at_least_rust_2024(), m, hir_id);
+        handle_static_mut_ref(
+            tcx,
+            span,
+            span.with_hi(expr.span.lo()),
+            span.shrink_to_hi(),
+            span.edition().at_least_rust_2024(),
+            m,
+            hir_id,
+        );
     }
 }
 
@@ -24,12 +31,13 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
         && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind
         && let hir::ByRef::Yes(rmutbl) = ba.0
         && let Some(init) = loc.init
-        && let Some(var) = path_if_static_mut(tcx, init)
+        && path_if_static_mut(init)
     {
         handle_static_mut_ref(
             tcx,
             init.span,
-            var,
+            init.span.shrink_to_lo(),
+            init.span.shrink_to_hi(),
             loc.span.edition().at_least_rust_2024(),
             rmutbl,
             stmt.hir_id,
@@ -37,38 +45,39 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) {
     }
 }
 
-fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option<String> {
+fn path_if_static_mut(expr: &hir::Expr<'_>) -> bool {
     if let hir::ExprKind::Path(qpath) = expr.kind
         && let hir::QPath::Resolved(_, path) = qpath
         && let hir::def::Res::Def(def_kind, _) = path.res
         && let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } =
             def_kind
     {
-        return Some(qpath_to_string(&tcx, &qpath));
+        return true;
     }
-    None
+    false
 }
 
 fn handle_static_mut_ref(
     tcx: TyCtxt<'_>,
     span: Span,
-    var: String,
+    lo: Span,
+    hi: Span,
     e2024: bool,
     mutable: Mutability,
     hir_id: hir::HirId,
 ) {
     if e2024 {
         let (sugg, shared) = if mutable == Mutability::Mut {
-            (errors::StaticMutRefSugg::Mut { span, var }, "mutable")
+            (errors::MutRefSugg::Mut { lo, hi }, "mutable")
         } else {
-            (errors::StaticMutRefSugg::Shared { span, var }, "shared")
+            (errors::MutRefSugg::Shared { lo, hi }, "shared")
         };
         tcx.dcx().emit_err(errors::StaticMutRef { span, sugg, shared });
     } else {
         let (sugg, shared) = if mutable == Mutability::Mut {
-            (errors::RefOfMutStaticSugg::Mut { span, var }, "mutable")
+            (errors::MutRefSugg::Mut { lo, hi }, "mutable")
         } else {
-            (errors::RefOfMutStaticSugg::Shared { span, var }, "shared")
+            (errors::MutRefSugg::Shared { lo, hi }, "shared")
         };
         tcx.emit_node_span_lint(
             STATIC_MUT_REFS,
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index b2ef07d65c5..809427f86ee 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -4,12 +4,12 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
 use crate::errors;
 use crate::fluent_generated as fluent;
 
-use hir::intravisit::Visitor;
+use hir::intravisit::{self, Visitor};
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
@@ -1799,7 +1799,7 @@ fn receiver_is_implemented<'tcx>(
 
 fn check_variances_for_type_defn<'tcx>(
     tcx: TyCtxt<'tcx>,
-    item: &hir::Item<'tcx>,
+    item: &'tcx hir::Item<'tcx>,
     hir_generics: &hir::Generics<'tcx>,
 ) {
     let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id);
@@ -1886,21 +1886,21 @@ fn check_variances_for_type_defn<'tcx>(
             hir::ParamName::Error => {}
             _ => {
                 let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
-                report_bivariance(tcx, hir_param, has_explicit_bounds, item.kind);
+                report_bivariance(tcx, hir_param, has_explicit_bounds, item);
             }
         }
     }
 }
 
-fn report_bivariance(
-    tcx: TyCtxt<'_>,
-    param: &rustc_hir::GenericParam<'_>,
+fn report_bivariance<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param: &'tcx hir::GenericParam<'tcx>,
     has_explicit_bounds: bool,
-    item_kind: ItemKind<'_>,
+    item: &'tcx hir::Item<'tcx>,
 ) -> ErrorGuaranteed {
     let param_name = param.name.ident();
 
-    let help = match item_kind {
+    let help = match item.kind {
         ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
             if let Some(def_id) = tcx.lang_items().phantom_data() {
                 errors::UnusedGenericParameterHelp::Adt {
@@ -1915,6 +1915,49 @@ fn report_bivariance(
         item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"),
     };
 
+    let mut usage_spans = vec![];
+    intravisit::walk_item(
+        &mut CollectUsageSpans { spans: &mut usage_spans, param_def_id: param.def_id.to_def_id() },
+        item,
+    );
+
+    if !usage_spans.is_empty() {
+        // First, check if the ADT is (probably) cyclical. We say probably here, since
+        // we're not actually looking into substitutions, just walking through fields.
+        // And we only recurse into the fields of ADTs, and not the hidden types of
+        // opaques or anything else fancy.
+        let item_def_id = item.owner_id.to_def_id();
+        let is_probably_cyclical = if matches!(
+            tcx.def_kind(item_def_id),
+            DefKind::Struct | DefKind::Union | DefKind::Enum
+        ) {
+            IsProbablyCyclical { tcx, adt_def_id: item_def_id, seen: Default::default() }
+                .visit_all_fields(tcx.adt_def(item_def_id))
+                .is_break()
+        } else {
+            false
+        };
+        // If the ADT is cyclical, then if at least one usage of the type parameter or
+        // the `Self` alias is present in the, then it's probably a cyclical struct, and
+        // we should call those parameter usages recursive rather than just saying they're
+        // unused...
+        //
+        // We currently report *all* of the parameter usages, since computing the exact
+        // subset is very involved, and the fact we're mentioning recursion at all is
+        // likely to guide the user in the right direction.
+        if is_probably_cyclical {
+            let diag = tcx.dcx().create_err(errors::RecursiveGenericParameter {
+                spans: usage_spans,
+                param_span: param.span,
+                param_name,
+                param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
+                help,
+                note: (),
+            });
+            return diag.emit();
+        }
+    }
+
     let const_param_help =
         matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds)
             .then_some(());
@@ -1923,6 +1966,7 @@ fn report_bivariance(
         span: param.span,
         param_name,
         param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
+        usage_spans,
         help,
         const_param_help,
     });
@@ -1930,6 +1974,77 @@ fn report_bivariance(
     diag.emit()
 }
 
+/// Detects cases where an ADT is trivially cyclical -- we want to detect this so
+/// /we only mention that its parameters are used cyclically if the ADT is truly
+/// cyclical.
+///
+/// Notably, we don't consider substitutions here, so this may have false positives.
+struct IsProbablyCyclical<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    adt_def_id: DefId,
+    seen: FxHashSet<DefId>,
+}
+
+impl<'tcx> IsProbablyCyclical<'tcx> {
+    fn visit_all_fields(&mut self, adt_def: ty::AdtDef<'tcx>) -> ControlFlow<(), ()> {
+        for field in adt_def.all_fields() {
+            self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?;
+        }
+
+        ControlFlow::Continue(())
+    }
+}
+
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsProbablyCyclical<'tcx> {
+    type Result = ControlFlow<(), ()>;
+
+    fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<(), ()> {
+        if let Some(adt_def) = t.ty_adt_def() {
+            if adt_def.did() == self.adt_def_id {
+                return ControlFlow::Break(());
+            }
+
+            if self.seen.insert(adt_def.did()) {
+                self.visit_all_fields(adt_def)?;
+            }
+        }
+
+        t.super_visit_with(self)
+    }
+}
+
+/// Collect usages of the `param_def_id` and `Res::SelfTyAlias` in the HIR.
+///
+/// This is used to report places where the user has used parameters in a
+/// non-variance-constraining way for better bivariance errors.
+struct CollectUsageSpans<'a> {
+    spans: &'a mut Vec<Span>,
+    param_def_id: DefId,
+}
+
+impl<'tcx> Visitor<'tcx> for CollectUsageSpans<'_> {
+    type Result = ();
+
+    fn visit_generics(&mut self, _g: &'tcx rustc_hir::Generics<'tcx>) -> Self::Result {
+        // Skip the generics. We only care about fields, not where clause/param bounds.
+    }
+
+    fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result {
+        if let hir::TyKind::Path(hir::QPath::Resolved(None, qpath)) = t.kind {
+            if let Res::Def(DefKind::TyParam, def_id) = qpath.res
+                && def_id == self.param_def_id
+            {
+                self.spans.push(t.span);
+                return;
+            } else if let Res::SelfTyAlias { .. } = qpath.res {
+                self.spans.push(t.span);
+                return;
+            }
+        }
+        intravisit::walk_ty(self, t);
+    }
+}
+
 impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
     /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
     /// aren't true.
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 0ee87a13e9e..03311fed396 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1500,33 +1500,33 @@ pub struct StaticMutRef<'a> {
     #[label]
     pub span: Span,
     #[subdiagnostic]
-    pub sugg: StaticMutRefSugg,
+    pub sugg: MutRefSugg,
     pub shared: &'a str,
 }
 
 #[derive(Subdiagnostic)]
-pub enum StaticMutRefSugg {
-    #[suggestion(
+pub enum MutRefSugg {
+    #[multipart_suggestion(
         hir_analysis_suggestion,
         style = "verbose",
-        code = "addr_of!({var})",
         applicability = "maybe-incorrect"
     )]
     Shared {
-        #[primary_span]
-        span: Span,
-        var: String,
+        #[suggestion_part(code = "addr_of!(")]
+        lo: Span,
+        #[suggestion_part(code = ")")]
+        hi: Span,
     },
-    #[suggestion(
+    #[multipart_suggestion(
         hir_analysis_suggestion_mut,
         style = "verbose",
-        code = "addr_of_mut!({var})",
         applicability = "maybe-incorrect"
     )]
     Mut {
-        #[primary_span]
-        span: Span,
-        var: String,
+        #[suggestion_part(code = "addr_of_mut!(")]
+        lo: Span,
+        #[suggestion_part(code = ")")]
+        hi: Span,
     },
 }
 
@@ -1539,36 +1539,10 @@ pub struct RefOfMutStatic<'a> {
     #[label]
     pub span: Span,
     #[subdiagnostic]
-    pub sugg: RefOfMutStaticSugg,
+    pub sugg: MutRefSugg,
     pub shared: &'a str,
 }
 
-#[derive(Subdiagnostic)]
-pub enum RefOfMutStaticSugg {
-    #[suggestion(
-        hir_analysis_suggestion,
-        style = "verbose",
-        code = "addr_of!({var})",
-        applicability = "maybe-incorrect"
-    )]
-    Shared {
-        #[primary_span]
-        span: Span,
-        var: String,
-    },
-    #[suggestion(
-        hir_analysis_suggestion_mut,
-        style = "verbose",
-        code = "addr_of_mut!({var})",
-        applicability = "maybe-incorrect"
-    )]
-    Mut {
-        #[primary_span]
-        span: Span,
-        var: String,
-    },
-}
-
 #[derive(Diagnostic)]
 #[diag(hir_analysis_not_supported_delegation)]
 pub struct NotSupportedDelegation<'a> {
@@ -1597,12 +1571,29 @@ pub(crate) struct UnusedGenericParameter {
     pub span: Span,
     pub param_name: Ident,
     pub param_def_kind: &'static str,
+    #[label(hir_analysis_usage_spans)]
+    pub usage_spans: Vec<Span>,
     #[subdiagnostic]
     pub help: UnusedGenericParameterHelp,
     #[help(hir_analysis_const_param_help)]
     pub const_param_help: Option<()>,
 }
 
+#[derive(Diagnostic)]
+#[diag(hir_analysis_recursive_generic_parameter)]
+pub(crate) struct RecursiveGenericParameter {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    #[label]
+    pub param_span: Span,
+    pub param_name: Ident,
+    pub param_def_kind: &'static str,
+    #[subdiagnostic]
+    pub help: UnusedGenericParameterHelp,
+    #[note]
+    pub note: (),
+}
+
 #[derive(Subdiagnostic)]
 pub(crate) enum UnusedGenericParameterHelp {
     #[help(hir_analysis_unused_generic_parameter_adt_help)]
diff --git a/compiler/rustc_infer/src/error_reporting/infer/mod.rs b/compiler/rustc_infer/src/error_reporting/infer/mod.rs
index a4af721cf75..1401d16108a 100644
--- a/compiler/rustc_infer/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/mod.rs
@@ -1934,10 +1934,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for SameTypeModuloInfer<'_, 'tcx> {
         self.0.tcx
     }
 
-    fn tag(&self) -> &'static str {
-        "SameTypeModuloInfer"
-    }
-
     fn relate_with_variance<T: relate::Relate<TyCtxt<'tcx>>>(
         &mut self,
         _variance: ty::Variance,
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index d60d9113d91..c63eeaf812c 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -110,7 +110,7 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
 
     /// Binds the pattern variable `br` to `value`; returns an `Err` if the pattern
     /// is already bound to a different value.
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "trace", skip(self))]
     fn bind(
         &mut self,
         br: ty::BoundRegion,
@@ -133,10 +133,6 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
 }
 
 impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx> {
-    fn tag(&self) -> &'static str {
-        "MatchAgainstHigherRankedOutlives"
-    }
-
     fn cx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -154,13 +150,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
         if variance != ty::Bivariant { self.relate(a, b) } else { Ok(a) }
     }
 
-    #[instrument(skip(self), level = "debug")]
+    #[instrument(skip(self), level = "trace")]
     fn regions(
         &mut self,
         pattern: ty::Region<'tcx>,
         value: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-        debug!("self.pattern_depth = {:?}", self.pattern_depth);
         if let ty::RegionKind::ReBound(depth, br) = pattern.kind()
             && depth == self.pattern_depth
         {
@@ -172,7 +167,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
         }
     }
 
-    #[instrument(skip(self), level = "debug")]
+    #[instrument(skip(self), level = "trace")]
     fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         // FIXME(non_lifetime_binders): What to do here?
         if matches!(pattern.kind(), ty::Error(_) | ty::Bound(..)) {
@@ -185,13 +180,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
         }
     }
 
-    #[instrument(skip(self), level = "debug")]
+    #[instrument(skip(self), level = "trace")]
     fn consts(
         &mut self,
         pattern: ty::Const<'tcx>,
         value: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), pattern, value);
         if pattern == value {
             Ok(pattern)
         } else {
@@ -199,6 +193,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
         }
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn binders<T>(
         &mut self,
         pattern: ty::Binder<'tcx, T>,
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index c93b89756f9..1dc03de4c8b 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -79,6 +79,7 @@ impl<'tcx> InferCtxt<'tcx> {
     where
         R: PredicateEmittingRelation<InferCtxt<'tcx>>,
     {
+        debug!("super_combine_tys::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
         debug_assert!(!a.has_escaping_bound_vars());
         debug_assert!(!b.has_escaping_bound_vars());
 
@@ -174,9 +175,10 @@ impl<'tcx> InferCtxt<'tcx> {
     where
         R: PredicateEmittingRelation<InferCtxt<'tcx>>,
     {
-        debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
+        debug!("super_combine_consts::<{}>({:?}, {:?})", std::any::type_name::<R>(), a, b);
         debug_assert!(!a.has_escaping_bound_vars());
         debug_assert!(!b.has_escaping_bound_vars());
+
         if a == b {
             return Ok(a);
         }
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index ace439545b8..30cfbcae6b2 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -401,10 +401,6 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
         self.infcx.tcx
     }
 
-    fn tag(&self) -> &'static str {
-        "Generalizer"
-    }
-
     fn relate_item_args(
         &mut self,
         item_def_id: DefId,
diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index 819a47fcf93..4f2cf2c43e7 100644
--- a/compiler/rustc_infer/src/infer/relate/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -23,10 +23,6 @@ impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
 }
 
 impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
-    fn tag(&self) -> &'static str {
-        "Glb"
-    }
-
     fn cx(&self) -> TyCtxt<'tcx> {
         self.fields.tcx()
     }
@@ -47,17 +43,17 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
         }
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         lattice::super_lattice_tys(self, a, b)
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn regions(
         &mut self,
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-        debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
-
         let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
         Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
@@ -68,6 +64,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
         ))
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn consts(
         &mut self,
         a: ty::Const<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index 46e7466141a..d1d87071562 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -56,8 +56,6 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
 where
     L: LatticeDir<'a, 'tcx>,
 {
-    debug!("{}", this.tag());
-
     if a == b {
         return Ok(a);
     }
diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index 56d325c5dc1..2eb20f311cf 100644
--- a/compiler/rustc_infer/src/infer/relate/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -23,10 +23,6 @@ impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
 }
 
 impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
-    fn tag(&self) -> &'static str {
-        "Lub"
-    }
-
     fn cx(&self) -> TyCtxt<'tcx> {
         self.fields.tcx()
     }
@@ -51,13 +47,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
         lattice::super_lattice_tys(self, a, b)
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn regions(
         &mut self,
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-        debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
-
         let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
         Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
@@ -68,6 +63,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
         ))
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn consts(
         &mut self,
         a: ty::Const<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index 97bd858defb..3fe35354286 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -28,10 +28,6 @@ impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
 }
 
 impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
-    fn tag(&self) -> &'static str {
-        "TypeRelating"
-    }
-
     fn cx(&self) -> TyCtxt<'tcx> {
         self.fields.infcx.tcx
     }
@@ -71,7 +67,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
         r
     }
 
-    #[instrument(skip(self), level = "debug")]
+    #[instrument(skip(self), level = "trace")]
     fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         if a == b {
             return Ok(a);
@@ -166,12 +162,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
         Ok(a)
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn regions(
         &mut self,
         a: ty::Region<'tcx>,
         b: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
-        debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
         let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
 
         match self.ambient_variance {
@@ -209,6 +205,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
         Ok(a)
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn consts(
         &mut self,
         a: ty::Const<'tcx>,
diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs
index 2f540478674..95fec154918 100644
--- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs
@@ -3,37 +3,37 @@ use rustc_middle::thir::{self, *};
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
 use crate::build::expr::as_place::{PlaceBase, PlaceBuilder};
-use crate::build::matches::{FlatPat, MatchPair, TestCase};
+use crate::build::matches::{FlatPat, MatchPairTree, TestCase};
 use crate::build::Builder;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
-    /// Builds and returns [`MatchPair`] trees, one for each pattern in
+    /// Builds and returns [`MatchPairTree`] subtrees, one for each pattern in
     /// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
     /// [`PatKind::Leaf`].
     ///
-    /// Used internally by [`MatchPair::new`].
+    /// Used internally by [`MatchPairTree::for_pattern`].
     fn field_match_pairs<'pat>(
         &mut self,
         place: PlaceBuilder<'tcx>,
         subpatterns: &'pat [FieldPat<'tcx>],
-    ) -> Vec<MatchPair<'pat, 'tcx>> {
+    ) -> Vec<MatchPairTree<'pat, 'tcx>> {
         subpatterns
             .iter()
             .map(|fieldpat| {
                 let place =
                     place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
-                MatchPair::new(place, &fieldpat.pattern, self)
+                MatchPairTree::for_pattern(place, &fieldpat.pattern, self)
             })
             .collect()
     }
 
-    /// Builds [`MatchPair`] trees for the prefix/middle/suffix parts of an
+    /// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
     /// array pattern or slice pattern, and adds those trees to `match_pairs`.
     ///
-    /// Used internally by [`MatchPair::new`].
+    /// Used internally by [`MatchPairTree::for_pattern`].
     fn prefix_slice_suffix<'pat>(
         &mut self,
-        match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
+        match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
         place: &PlaceBuilder<'tcx>,
         prefix: &'pat [Box<Pat<'tcx>>],
         opt_slice: &'pat Option<Box<Pat<'tcx>>>,
@@ -52,7 +52,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
             let elem =
                 ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false };
-            MatchPair::new(place.clone_project(elem), subpattern, self)
+            MatchPairTree::for_pattern(place.clone_project(elem), subpattern, self)
         }));
 
         if let Some(subslice_pat) = opt_slice {
@@ -62,7 +62,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 to: if exact_size { min_length - suffix_len } else { suffix_len },
                 from_end: !exact_size,
             });
-            match_pairs.push(MatchPair::new(subslice, subslice_pat, self));
+            match_pairs.push(MatchPairTree::for_pattern(subslice, subslice_pat, self));
         }
 
         match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| {
@@ -73,19 +73,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 from_end: !exact_size,
             };
             let place = place.clone_project(elem);
-            MatchPair::new(place, subpattern, self)
+            MatchPairTree::for_pattern(place, subpattern, self)
         }));
     }
 }
 
-impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
-    /// Recursively builds a `MatchPair` tree for the given pattern and its
+impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
+    /// Recursively builds a match pair tree for the given pattern and its
     /// subpatterns.
-    pub(in crate::build) fn new(
+    pub(in crate::build) fn for_pattern(
         mut place_builder: PlaceBuilder<'tcx>,
         pattern: &'pat Pat<'tcx>,
         cx: &mut Builder<'_, 'tcx>,
-    ) -> MatchPair<'pat, 'tcx> {
+    ) -> MatchPairTree<'pat, 'tcx> {
         // Force the place type to the pattern's type.
         // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
         if let Some(resolved) = place_builder.resolve_upvar(cx) {
@@ -138,7 +138,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
                     variance,
                 });
 
-                subpairs.push(MatchPair::new(place_builder, subpattern, cx));
+                subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
                 TestCase::Irrefutable { ascription, binding: None }
             }
 
@@ -152,7 +152,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
 
                 if let Some(subpattern) = subpattern.as_ref() {
                     // this is the `x @ P` case; have to keep matching against `P` now
-                    subpairs.push(MatchPair::new(place_builder, subpattern, cx));
+                    subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
                 }
                 TestCase::Irrefutable { ascription: None, binding }
             }
@@ -182,7 +182,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
                     super::Ascription { annotation, source, variance: ty::Contravariant }
                 });
 
-                subpairs.push(MatchPair::new(place_builder, pattern, cx));
+                subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
                 TestCase::Irrefutable { ascription, binding: None }
             }
 
@@ -231,7 +231,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
             }
 
             PatKind::Deref { ref subpattern } => {
-                subpairs.push(MatchPair::new(place_builder.deref(), subpattern, cx));
+                subpairs.push(MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx));
                 default_irrefutable()
             }
 
@@ -242,13 +242,17 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
                     Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability),
                     pattern.span,
                 );
-                subpairs.push(MatchPair::new(PlaceBuilder::from(temp).deref(), subpattern, cx));
+                subpairs.push(MatchPairTree::for_pattern(
+                    PlaceBuilder::from(temp).deref(),
+                    subpattern,
+                    cx,
+                ));
                 TestCase::Deref { temp, mutability }
             }
 
             PatKind::Never => TestCase::Never,
         };
 
-        MatchPair { place, test_case, subpairs, pattern }
+        MatchPairTree { place, test_case, subpairs, pattern }
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 20c33745af8..b531a392efa 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1032,15 +1032,15 @@ impl<'tcx> PatternExtraData<'tcx> {
 #[derive(Debug, Clone)]
 struct FlatPat<'pat, 'tcx> {
     /// To match the pattern, all of these must be satisfied...
-    // Invariant: all the `MatchPair`s are recursively simplified.
+    // Invariant: all the match pairs are recursively simplified.
     // Invariant: or-patterns must be sorted to the end.
-    match_pairs: Vec<MatchPair<'pat, 'tcx>>,
+    match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,
 
     extra_data: PatternExtraData<'tcx>,
 }
 
 impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
-    /// Creates a `FlatPat` containing a simplified [`MatchPair`] list/forest
+    /// Creates a `FlatPat` containing a simplified [`MatchPairTree`] list/forest
     /// for the given pattern.
     fn new(
         place: PlaceBuilder<'tcx>,
@@ -1048,7 +1048,7 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
         cx: &mut Builder<'_, 'tcx>,
     ) -> Self {
         // First, recursively build a tree of match pairs for the given pattern.
-        let mut match_pairs = vec![MatchPair::new(place, pattern, cx)];
+        let mut match_pairs = vec![MatchPairTree::for_pattern(place, pattern, cx)];
         let mut extra_data = PatternExtraData {
             span: pattern.span,
             bindings: Vec::new(),
@@ -1065,9 +1065,9 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
 #[derive(Debug)]
 struct Candidate<'pat, 'tcx> {
     /// For the candidate to match, all of these must be satisfied...
-    // Invariant: all the `MatchPair`s are recursively simplified.
+    // Invariant: all the match pairs are recursively simplified.
     // Invariant: or-patterns must be sorted at the end.
-    match_pairs: Vec<MatchPair<'pat, 'tcx>>,
+    match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,
 
     /// ...and if this is non-empty, one of these subcandidates also has to match...
     // Invariant: at the end of the algorithm, this must never contain a `is_never` candidate
@@ -1126,7 +1126,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
 
     /// Returns whether the first match pair of this candidate is an or-pattern.
     fn starts_with_or_pattern(&self) -> bool {
-        matches!(&*self.match_pairs, [MatchPair { test_case: TestCase::Or { .. }, .. }, ..])
+        matches!(&*self.match_pairs, [MatchPairTree { test_case: TestCase::Or { .. }, .. }, ..])
     }
 
     /// Visit the leaf candidates (those with no subcandidates) contained in
@@ -1206,7 +1206,7 @@ impl<'pat, 'tcx> TestCase<'pat, 'tcx> {
 /// Each node also has a list of subpairs (possibly empty) that must also match,
 /// and a reference to the THIR pattern it represents.
 #[derive(Debug, Clone)]
-pub(crate) struct MatchPair<'pat, 'tcx> {
+pub(crate) struct MatchPairTree<'pat, 'tcx> {
     /// This place...
     ///
     /// ---
@@ -1629,7 +1629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     fn create_or_subcandidates<'pat>(
         &mut self,
         candidate: &mut Candidate<'pat, 'tcx>,
-        match_pair: MatchPair<'pat, 'tcx>,
+        match_pair: MatchPairTree<'pat, 'tcx>,
     ) {
         let TestCase::Or { pats } = match_pair.test_case else { bug!() };
         debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
@@ -1813,8 +1813,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// [`Range`]: TestKind::Range
     fn pick_test(&mut self, candidates: &[&mut Candidate<'_, 'tcx>]) -> (Place<'tcx>, Test<'tcx>) {
         // Extract the match-pair from the highest priority candidate
-        let match_pair = &candidates.first().unwrap().match_pairs[0];
-        let test = self.test(match_pair);
+        let match_pair = &candidates[0].match_pairs[0];
+        let test = self.pick_test_for_match_pair(match_pair);
         // Unwrap is ok after simplification.
         let match_place = match_pair.place.unwrap();
         debug!(?test, ?match_pair);
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 543301c71a0..20310f60821 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -12,7 +12,7 @@
 //! sort of test: for example, testing which variant an enum is, or
 //! testing a value against a constant.
 
-use crate::build::matches::{MatchPair, PatternExtraData, TestCase};
+use crate::build::matches::{MatchPairTree, PatternExtraData, TestCase};
 use crate::build::Builder;
 use tracing::{debug, instrument};
 
@@ -24,7 +24,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
     pub(super) fn simplify_match_pairs<'pat>(
         &mut self,
-        match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
+        match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
         extra_data: &mut PatternExtraData<'tcx>,
     ) {
         // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 5aed2537750..8a02ea1a06d 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -5,7 +5,7 @@
 // identify what tests are needed, perform the tests, and then filter
 // the candidates based on the result.
 
-use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, TestKind};
+use crate::build::matches::{Candidate, MatchPairTree, Test, TestBranch, TestCase, TestKind};
 use crate::build::Builder;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::{LangItem, RangeEnd};
@@ -26,7 +26,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Identifies what test is needed to decide if `match_pair` is applicable.
     ///
     /// It is a bug to call this with a not-fully-simplified pattern.
-    pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
+    pub(super) fn pick_test_for_match_pair<'pat>(
+        &mut self,
+        match_pair: &MatchPairTree<'pat, 'tcx>,
+    ) -> Test<'tcx> {
         let kind = match match_pair.test_case {
             TestCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def },
 
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index e67fc843285..8fe8069b345 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -1,7 +1,7 @@
 use std::marker::PhantomData;
 
 use crate::build::expr::as_place::PlaceBase;
-use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase};
+use crate::build::matches::{Binding, Candidate, FlatPat, MatchPairTree, TestCase};
 use crate::build::Builder;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_middle::mir::*;
@@ -152,7 +152,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) {
+    fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
         if let TestCase::Or { pats, .. } = &match_pair.test_case {
             for flat_pat in pats.iter() {
                 self.visit_flat_pat(flat_pat)
@@ -260,7 +260,7 @@ where
         }
     }
 
-    fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) {
+    fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
         if let TestCase::Or { pats, .. } = &match_pair.test_case {
             // All the or-alternatives should bind the same locals, so we only visit the first one.
             self.visit_flat_pat(&pats[0])
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 4222486034b..da0701efddb 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -660,9 +660,8 @@ pub(crate) struct RemoveLet {
 #[diag(parse_use_eq_instead)]
 pub(crate) struct UseEqInstead {
     #[primary_span]
+    #[suggestion(style = "verbose", applicability = "machine-applicable", code = "=")]
     pub span: Span,
-    #[suggestion(style = "verbose", applicability = "machine-applicable", code = "")]
-    pub suggestion: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 2fe3ab56146..326478a7175 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -566,10 +566,7 @@ impl<'a> Parser<'a> {
             && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq)))
         {
             // Likely typo: `=` → `==` in let expr or enum item
-            return Err(self.dcx().create_err(UseEqInstead {
-                span: self.token.span,
-                suggestion: self.token.span.with_lo(self.token.span.lo() + BytePos(1)),
-            }));
+            return Err(self.dcx().create_err(UseEqInstead { span: self.token.span }));
         }
 
         if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) {
diff --git a/compiler/rustc_trait_selection/src/traits/select/_match.rs b/compiler/rustc_trait_selection/src/traits/select/_match.rs
index 8676f30a53b..7ead65721f9 100644
--- a/compiler/rustc_trait_selection/src/traits/select/_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/_match.rs
@@ -3,7 +3,7 @@ use rustc_infer::infer::relate::{
 };
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
-use tracing::{debug, instrument};
+use tracing::instrument;
 
 /// A type "A" *matches* "B" if the fresh types in B could be
 /// instantiated with values so as to make it equal to A. Matching is
@@ -32,10 +32,6 @@ impl<'tcx> MatchAgainstFreshVars<'tcx> {
 }
 
 impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
-    fn tag(&self) -> &'static str {
-        "MatchAgainstFreshVars"
-    }
-
     fn cx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -50,7 +46,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
         self.relate(a, b)
     }
 
-    #[instrument(skip(self), level = "debug")]
+    #[instrument(skip(self), level = "trace")]
     fn regions(
         &mut self,
         a: ty::Region<'tcx>,
@@ -59,7 +55,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
         Ok(a)
     }
 
-    #[instrument(skip(self), level = "debug")]
+    #[instrument(skip(self), level = "trace")]
     fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         if a == b {
             return Ok(a);
@@ -83,12 +79,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
         }
     }
 
+    #[instrument(skip(self), level = "trace")]
     fn consts(
         &mut self,
         a: ty::Const<'tcx>,
         b: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
         if a == b {
             return Ok(a);
         }
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index a8f48d14af5..ae840ec0210 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -1,7 +1,7 @@
 use std::iter;
 
 use rustc_ast_ir::Mutability;
-use tracing::{debug, instrument};
+use tracing::{instrument, trace};
 
 use crate::error::{ExpectedFound, TypeError};
 use crate::fold::TypeFoldable;
@@ -58,9 +58,6 @@ impl<I: Interner> VarianceDiagInfo<I> {
 pub trait TypeRelation<I: Interner>: Sized {
     fn cx(&self) -> I;
 
-    /// Returns a static string we can use for printouts.
-    fn tag(&self) -> &'static str;
-
     /// Generic relation routine suitable for most anything.
     fn relate<T: Relate<I>>(&mut self, a: T, b: T) -> RelateResult<I, T> {
         Relate::relate(self, a, b)
@@ -69,17 +66,13 @@ pub trait TypeRelation<I: Interner>: Sized {
     /// Relate the two args for the given item. The default
     /// is to look up the variance for the item and proceed
     /// accordingly.
+    #[instrument(skip(self), level = "trace")]
     fn relate_item_args(
         &mut self,
         item_def_id: I::DefId,
         a_arg: I::GenericArgs,
         b_arg: I::GenericArgs,
     ) -> RelateResult<I, I::GenericArgs> {
-        debug!(
-            "relate_item_args(item_def_id={:?}, a_arg={:?}, b_arg={:?})",
-            item_def_id, a_arg, b_arg
-        );
-
         let cx = self.cx();
         let opt_variances = cx.variances_of(item_def_id);
         relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
@@ -571,7 +564,12 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
     mut a: I::Const,
     mut b: I::Const,
 ) -> RelateResult<I, I::Const> {
-    debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
+    trace!(
+        "structurally_relate_consts::<{}>(a = {:?}, b = {:?})",
+        std::any::type_name::<R>(),
+        a,
+        b
+    );
     let cx = relation.cx();
 
     if cx.features().generic_const_exprs() {
@@ -579,7 +577,12 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
         b = cx.expand_abstract_consts(b);
     }
 
-    debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b);
+    trace!(
+        "structurally_relate_consts::<{}>(normed_a = {:?}, normed_b = {:?})",
+        std::any::type_name::<R>(),
+        a,
+        b
+    );
 
     // Currently, the values that can be unified are primitive types,
     // and those that derive both `PartialEq` and `Eq`, corresponding
diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs
index bb32c70d663..98c54f038da 100644
--- a/library/test/src/test_result.rs
+++ b/library/test/src/test_result.rs
@@ -19,7 +19,15 @@ pub const TR_OK: i32 = 50;
 // On Windows we use __fastfail to abort, which is documented to use this
 // exception code.
 #[cfg(windows)]
-const STATUS_ABORTED: i32 = 0xC0000409u32 as i32;
+const STATUS_FAIL_FAST_EXCEPTION: i32 = 0xC0000409u32 as i32;
+
+// On Zircon (the Fuchsia kernel), an abort from userspace calls the
+// LLVM implementation of __builtin_trap(), e.g., ud2 on x86, which
+// raises a kernel exception. If a userspace process does not
+// otherwise arrange exception handling, the kernel kills the process
+// with this return code.
+#[cfg(target_os = "fuchsia")]
+const ZX_TASK_RETCODE_EXCEPTION_KILL: i32 = -1028;
 
 #[derive(Debug, Clone, PartialEq)]
 pub enum TestResult {
@@ -96,7 +104,7 @@ pub fn get_result_from_exit_code(
     let result = match status.code() {
         Some(TR_OK) => TestResult::TrOk,
         #[cfg(windows)]
-        Some(STATUS_ABORTED) => TestResult::TrFailed,
+        Some(STATUS_FAIL_FAST_EXCEPTION) => TestResult::TrFailed,
         #[cfg(unix)]
         None => match status.signal() {
             Some(libc::SIGABRT) => TestResult::TrFailed,
@@ -105,6 +113,9 @@ pub fn get_result_from_exit_code(
             }
             None => unreachable!("status.code() returned None but status.signal() was None"),
         },
+        // Upon an abort, Fuchsia returns the status code ZX_TASK_RETCODE_EXCEPTION_KILL.
+        #[cfg(target_os = "fuchsia")]
+        Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => TestResult::TrFailed,
         #[cfg(not(unix))]
         None => TestResult::TrFailedMsg(format!("unknown return code")),
         #[cfg(any(windows, unix))]
diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml
index 6e6c3660027..75ad37ce335 100644
--- a/src/bootstrap/defaults/config.tools.toml
+++ b/src/bootstrap/defaults/config.tools.toml
@@ -1,10 +1,6 @@
 # These defaults are meant for contributors to tools which build on the
 # compiler, but do not modify it directly.
 [rust]
-# This enables `RUSTC_LOG=debug`, avoiding confusing situations
-# where adding `debug!()` appears to do nothing.
-# However, it makes running the compiler slightly slower.
-debug-logging = true
 # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
 incremental = true
 # Download rustc from CI instead of building it from source.
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index ccab25e55a9..6a7c5c0f9b7 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -200,4 +200,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "`llvm.lld` is enabled by default for the dist profile. If set to false, `lld` will not be included in the dist build.",
     },
+    ChangeInfo {
+        change_id: 127913,
+        severity: ChangeSeverity::Warning,
+        summary: "`debug-logging` option has been removed from the default `tools` profile.",
+    },
 ];
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 0d9c21c4487..571378774be 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -37,6 +37,7 @@ RUN sh /scripts/sccache.sh
 COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
 RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt
 
+COPY host-x86_64/mingw-check/check-default-config-profiles.sh /scripts/
 COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
@@ -46,6 +47,7 @@ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 # We disable optimized compiler built-ins because that requires a C toolchain for the target.
 # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs.
 ENV SCRIPT python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
+           /scripts/check-default-config-profiles.sh && \
            python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
            python3 ../x.py clippy bootstrap -Dwarnings && \
            python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \
diff --git a/src/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh b/src/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh
new file mode 100755
index 00000000000..d706927d6d9
--- /dev/null
+++ b/src/ci/docker/host-x86_64/mingw-check/check-default-config-profiles.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Runs bootstrap (in dry-run mode) with each default config profile to ensure they are not broken.
+
+set -euo pipefail
+
+config_dir="../src/bootstrap/defaults"
+
+# Loop through each configuration file in the directory
+for config_file in "$config_dir"/*.toml;
+do
+    python3 ../x.py check --config $config_file --dry-run
+done
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index cb8b82e8bde..a305335e0b3 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -2174,6 +2174,14 @@ in src-script.js and main.js
 		padding: 2px 4px;
 		box-shadow: 0 0 4px var(--main-background-color);
 	}
+
+	.item-table > li > .item-name {
+		width: 33%;
+	}
+	.item-table > li > div {
+		padding-bottom: 5px;
+		word-break: break-all;
+	}
 }
 
 @media print {
diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs
index b467b044052..2467c7adae1 100644
--- a/tests/rustdoc-gui/src/lib2/lib.rs
+++ b/tests/rustdoc-gui/src/lib2/lib.rs
@@ -117,6 +117,7 @@ pub mod too_long {
     pub type ReallyLongTypeNameLongLongLong =
         Option<unsafe extern "C" fn(a: *const u8, b: *const u8) -> *const u8>;
 
+    /// Short doc.
     pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0;
 
     /// This also has a really long doccomment. Lorem ipsum dolor sit amet,
diff --git a/tests/rustdoc-gui/type-declation-overflow.goml b/tests/rustdoc-gui/type-declation-overflow.goml
index 3709aa10266..fdf84c3fd29 100644
--- a/tests/rustdoc-gui/type-declation-overflow.goml
+++ b/tests/rustdoc-gui/type-declation-overflow.goml
@@ -16,7 +16,11 @@ assert-property: ("pre.item-decl", {"scrollWidth": "1324"})
 
 // In the table-ish view on the module index, the name should not be wrapped more than necessary.
 go-to: "file://" + |DOC_PATH| + "/lib2/too_long/index.html"
-assert-property: (".item-table .struct", {"offsetWidth": "684"})
+
+// We'll ensure that items with short documentation have the same width.
+store-property: ("//*[@class='item-table']//*[@class='struct']/..", {"offsetWidth": offset_width})
+assert: |offset_width| == "277"
+assert-property: ("//*[@class='item-table']//*[@class='constant']/..", {"offsetWidth": |offset_width|})
 
 // We now make the same check on type declaration...
 go-to: "file://" + |DOC_PATH| + "/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html"
diff --git a/tests/ui/abi/statics/static-mut-foreign.stderr b/tests/ui/abi/statics/static-mut-foreign.stderr
index 983325c1abd..0c4bd5382a1 100644
--- a/tests/ui/abi/statics/static-mut-foreign.stderr
+++ b/tests/ui/abi/statics/static-mut-foreign.stderr
@@ -11,7 +11,7 @@ LL |     static_bound(&rust_dbg_static_mut);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     static_bound(addr_of!(rust_dbg_static_mut));
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                  ~~~~~~~~~                   +
 
 warning: creating a mutable reference to mutable static is discouraged
   --> $DIR/static-mut-foreign.rs:33:22
@@ -25,7 +25,7 @@ LL |     static_bound_set(&mut rust_dbg_static_mut);
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |     static_bound_set(addr_of_mut!(rust_dbg_static_mut));
-   |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                      ~~~~~~~~~~~~~                   +
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr
index 11e2b63bd6c..36e259fa6e8 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.stderr
+++ b/tests/ui/borrowck/borrowck-access-permissions.stderr
@@ -11,7 +11,7 @@ LL |             let _y2 = &mut static_x_mut;
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |             let _y2 = addr_of_mut!(static_x_mut);
-   |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                       ~~~~~~~~~~~~~            +
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-access-permissions.rs:10:19
diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
index 354d70eb1ad..a727c9414c5 100644
--- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
+++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
@@ -11,7 +11,7 @@ LL |         let sfoo: *mut Foo = &mut SFOO;
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         let sfoo: *mut Foo = addr_of_mut!(SFOO);
-   |                              ~~~~~~~~~~~~~~~~~~
+   |                              ~~~~~~~~~~~~~    +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr
index c1d06ac3e21..769b34831c1 100644
--- a/tests/ui/borrowck/issue-20801.stderr
+++ b/tests/ui/borrowck/issue-20801.stderr
@@ -11,7 +11,7 @@ LL |     unsafe { &mut GLOBAL_MUT_T }
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |     unsafe { addr_of_mut!(GLOBAL_MUT_T) }
-   |              ~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |              ~~~~~~~~~~~~~            +
 
 error[E0507]: cannot move out of a mutable reference
   --> $DIR/issue-20801.rs:27:22
diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
index ff5ec1db346..72fd0d8ce16 100644
--- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
+++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
@@ -11,7 +11,7 @@ LL |             c1(&mut Y);
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |             c1(addr_of_mut!(Y));
-   |                ~~~~~~~~~~~~~~~
+   |                ~~~~~~~~~~~~~ +
 
 warning: creating a mutable reference to mutable static is discouraged
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16
@@ -25,7 +25,7 @@ LL |             c1(&mut Z);
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |             c1(addr_of_mut!(Z));
-   |                ~~~~~~~~~~~~~~~
+   |                ~~~~~~~~~~~~~ +
 
 warning: creating a mutable reference to mutable static is discouraged
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37
@@ -39,7 +39,7 @@ LL |         borrowck_closures_unique::e(&mut X);
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         borrowck_closures_unique::e(addr_of_mut!(X));
-   |                                     ~~~~~~~~~~~~~~~
+   |                                     ~~~~~~~~~~~~~ +
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46
diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr
index 5ae8fd353dd..87b94a7be67 100644
--- a/tests/ui/consts/const_let_assign2.stderr
+++ b/tests/ui/consts/const_let_assign2.stderr
@@ -11,7 +11,7 @@ LL |     let ptr = unsafe { &mut BB };
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |     let ptr = unsafe { addr_of_mut!(BB) };
-   |                        ~~~~~~~~~~~~~~~~
+   |                        ~~~~~~~~~~~~~  +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr b/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
index de1194e74b4..9126e602391 100644
--- a/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
+++ b/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
@@ -11,7 +11,7 @@ LL |             (mem::size_of_val(&trails) * 8) as u32
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |             (mem::size_of_val(addr_of!(trails)) * 8) as u32
-   |                               ~~~~~~~~~~~~~~~~
+   |                               ~~~~~~~~~      +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr b/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr
index bdf46abea8a..6da87416802 100644
--- a/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr
+++ b/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr
@@ -11,7 +11,7 @@ LL |             (mem::size_of_val(&trails) * 8) as u32
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |             (mem::size_of_val(addr_of!(trails)) * 8) as u32
-   |                               ~~~~~~~~~~~~~~~~
+   |                               ~~~~~~~~~      +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/issues/issue-54410.stderr b/tests/ui/issues/issue-54410.stderr
index 7cc67ab72c3..6cc5cd95e2f 100644
--- a/tests/ui/issues/issue-54410.stderr
+++ b/tests/ui/issues/issue-54410.stderr
@@ -19,7 +19,7 @@ LL |     println!("{:p}", unsafe { &symbol });
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     println!("{:p}", unsafe { addr_of!(symbol) });
-   |                               ~~~~~~~~~~~~~~~~
+   |                               ~~~~~~~~~      +
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
index 944fe8aa8e5..48e7da96612 100644
--- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
+++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
@@ -8,7 +8,9 @@ error[E0392]: type parameter `T` is never used
   --> $DIR/inherent-impls-overflow.rs:14:12
    |
 LL | type Poly0<T> = Poly1<(T,)>;
-   |            ^ unused type parameter
+   |            ^           - `T` is named here, but is likely unused in the containing type
+   |            |
+   |            unused type parameter
    |
    = help: consider removing `T` or referring to it in the body of the type alias
    = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
@@ -17,7 +19,9 @@ error[E0392]: type parameter `T` is never used
   --> $DIR/inherent-impls-overflow.rs:17:12
    |
 LL | type Poly1<T> = Poly0<(T,)>;
-   |            ^ unused type parameter
+   |            ^           - `T` is named here, but is likely unused in the containing type
+   |            |
+   |            unused type parameter
    |
    = help: consider removing `T` or referring to it in the body of the type alias
    = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
index 82065cc06ea..a6d4f9a2a5c 100644
--- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
+++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
@@ -11,7 +11,7 @@ LL |         S1 { a: unsafe { &mut X1 } }
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         S1 { a: unsafe { addr_of_mut!(X1) } }
-   |                          ~~~~~~~~~~~~~~~~
+   |                          ~~~~~~~~~~~~~  +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/parser/issues/issue-101477-enum.stderr b/tests/ui/parser/issues/issue-101477-enum.stderr
index c6dadeab8b3..8d4efdd17f7 100644
--- a/tests/ui/parser/issues/issue-101477-enum.stderr
+++ b/tests/ui/parser/issues/issue-101477-enum.stderr
@@ -7,9 +7,8 @@ LL |     B == 2
    = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
 help: try using `=` instead
    |
-LL -     B == 2
-LL +     B = 2
-   |
+LL |     B = 2
+   |       ~
 
 error: expected item, found `==`
   --> $DIR/issue-101477-enum.rs:6:7
diff --git a/tests/ui/parser/issues/issue-101477-let.stderr b/tests/ui/parser/issues/issue-101477-let.stderr
index 59e90c8102f..d2671abbdea 100644
--- a/tests/ui/parser/issues/issue-101477-let.stderr
+++ b/tests/ui/parser/issues/issue-101477-let.stderr
@@ -6,9 +6,8 @@ LL |     let x == 2;
    |
 help: try using `=` instead
    |
-LL -     let x == 2;
-LL +     let x = 2;
-   |
+LL |     let x = 2;
+   |           ~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/recover/unicode-double-equals-recovery.rs b/tests/ui/parser/recover/unicode-double-equals-recovery.rs
new file mode 100644
index 00000000000..589f0a559bb
--- /dev/null
+++ b/tests/ui/parser/recover/unicode-double-equals-recovery.rs
@@ -0,0 +1,3 @@
+const A: usize ⩵ 2;
+//~^ ERROR unknown start of token: \u{2a75}
+//~| ERROR unexpected `==`
diff --git a/tests/ui/parser/recover/unicode-double-equals-recovery.stderr b/tests/ui/parser/recover/unicode-double-equals-recovery.stderr
new file mode 100644
index 00000000000..6e10dcce04a
--- /dev/null
+++ b/tests/ui/parser/recover/unicode-double-equals-recovery.stderr
@@ -0,0 +1,24 @@
+error: unknown start of token: \u{2a75}
+  --> $DIR/unicode-double-equals-recovery.rs:1:16
+   |
+LL | const A: usize ⩵ 2;
+   |                ^
+   |
+help: Unicode character '⩵' (Two Consecutive Equals Signs) looks like '==' (Double Equals Sign), but it is not
+   |
+LL | const A: usize == 2;
+   |                ~~
+
+error: unexpected `==`
+  --> $DIR/unicode-double-equals-recovery.rs:1:16
+   |
+LL | const A: usize ⩵ 2;
+   |                ^
+   |
+help: try using `=` instead
+   |
+LL | const A: usize = 2;
+   |                ~
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/static/reference-to-mut-static-safe.e2021.stderr b/tests/ui/static/reference-to-mut-static-safe.e2021.stderr
index 9ea34290e36..9fdfc00dfcd 100644
--- a/tests/ui/static/reference-to-mut-static-safe.e2021.stderr
+++ b/tests/ui/static/reference-to-mut-static-safe.e2021.stderr
@@ -11,7 +11,7 @@ LL |     let _x = &X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     let _x = addr_of!(X);
-   |              ~~~~~~~~~~~
+   |              ~~~~~~~~~ +
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/reference-to-mut-static-safe.rs:9:15
diff --git a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr
index c57b418d7b2..b3e0c84d1d8 100644
--- a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr
+++ b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr
@@ -8,7 +8,7 @@ LL |     let _x = &X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     let _x = addr_of!(X);
-   |              ~~~~~~~~~~~
+   |              ~~~~~~~~~ +
 
 error[E0133]: use of mutable static is unsafe and requires unsafe block
   --> $DIR/reference-to-mut-static-safe.rs:9:15
diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr
index b24943cf593..ca9cfbf7ac7 100644
--- a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr
+++ b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr
@@ -8,7 +8,7 @@ LL |         let _y = &X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let _y = addr_of!(X);
-   |                  ~~~~~~~~~~~
+   |                  ~~~~~~~~~ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22
@@ -20,7 +20,7 @@ LL |         let ref _a = X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let ref _a = addr_of!(X);
-   |                      ~~~~~~~~~~~
+   |                      +++++++++ +
 
 error[E0796]: creating a mutable reference to a mutable static
   --> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26
@@ -32,7 +32,7 @@ LL |         let ref mut _a = X;
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         let ref mut _a = addr_of_mut!(X);
-   |                          ~~~~~~~~~~~~~~~
+   |                          +++++++++++++ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25
@@ -44,7 +44,7 @@ LL |         let (_b, _c) = (&X, &mut Y);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let (_b, _c) = (addr_of!(X), &mut Y);
-   |                         ~~~~~~~~~~~
+   |                         ~~~~~~~~~ +
 
 error[E0796]: creating a mutable reference to a mutable static
   --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29
@@ -56,7 +56,7 @@ LL |         let (_b, _c) = (&X, &mut Y);
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         let (_b, _c) = (&X, addr_of_mut!(Y));
-   |                             ~~~~~~~~~~~~~~~
+   |                             ~~~~~~~~~~~~~ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13
@@ -68,7 +68,7 @@ LL |         foo(&X);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         foo(addr_of!(X));
-   |             ~~~~~~~~~~~
+   |             ~~~~~~~~~ +
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/static/reference-to-mut-static.e2021.stderr b/tests/ui/static/reference-to-mut-static.e2021.stderr
index f477e5ac6c5..667d7602f34 100644
--- a/tests/ui/static/reference-to-mut-static.e2021.stderr
+++ b/tests/ui/static/reference-to-mut-static.e2021.stderr
@@ -15,7 +15,7 @@ LL | #![deny(static_mut_refs)]
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let _y = addr_of!(X);
-   |                  ~~~~~~~~~~~
+   |                  ~~~~~~~~~ +
 
 error: creating a mutable reference to mutable static is discouraged
   --> $DIR/reference-to-mut-static.rs:20:18
@@ -29,7 +29,7 @@ LL |         let _y = &mut X;
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         let _y = addr_of_mut!(X);
-   |                  ~~~~~~~~~~~~~~~
+   |                  ~~~~~~~~~~~~~ +
 
 error: creating a shared reference to mutable static is discouraged
   --> $DIR/reference-to-mut-static.rs:28:22
@@ -43,7 +43,7 @@ LL |         let ref _a = X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let ref _a = addr_of!(X);
-   |                      ~~~~~~~~~~~
+   |                      +++++++++ +
 
 error: creating a shared reference to mutable static is discouraged
   --> $DIR/reference-to-mut-static.rs:32:25
@@ -57,7 +57,7 @@ LL |         let (_b, _c) = (&X, &Y);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let (_b, _c) = (addr_of!(X), &Y);
-   |                         ~~~~~~~~~~~
+   |                         ~~~~~~~~~ +
 
 error: creating a shared reference to mutable static is discouraged
   --> $DIR/reference-to-mut-static.rs:32:29
@@ -71,7 +71,7 @@ LL |         let (_b, _c) = (&X, &Y);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let (_b, _c) = (&X, addr_of!(Y));
-   |                             ~~~~~~~~~~~
+   |                             ~~~~~~~~~ +
 
 error: creating a shared reference to mutable static is discouraged
   --> $DIR/reference-to-mut-static.rs:38:13
@@ -85,7 +85,7 @@ LL |         foo(&X);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         foo(addr_of!(X));
-   |             ~~~~~~~~~~~
+   |             ~~~~~~~~~ +
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/static/reference-to-mut-static.e2024.stderr b/tests/ui/static/reference-to-mut-static.e2024.stderr
index b18e214e84f..e77f4355466 100644
--- a/tests/ui/static/reference-to-mut-static.e2024.stderr
+++ b/tests/ui/static/reference-to-mut-static.e2024.stderr
@@ -8,7 +8,7 @@ LL |         let _y = &X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let _y = addr_of!(X);
-   |                  ~~~~~~~~~~~
+   |                  ~~~~~~~~~ +
 
 error[E0796]: creating a mutable reference to a mutable static
   --> $DIR/reference-to-mut-static.rs:20:18
@@ -20,7 +20,7 @@ LL |         let _y = &mut X;
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |         let _y = addr_of_mut!(X);
-   |                  ~~~~~~~~~~~~~~~
+   |                  ~~~~~~~~~~~~~ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static.rs:28:22
@@ -32,7 +32,7 @@ LL |         let ref _a = X;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let ref _a = addr_of!(X);
-   |                      ~~~~~~~~~~~
+   |                      +++++++++ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static.rs:32:25
@@ -44,7 +44,7 @@ LL |         let (_b, _c) = (&X, &Y);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let (_b, _c) = (addr_of!(X), &Y);
-   |                         ~~~~~~~~~~~
+   |                         ~~~~~~~~~ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static.rs:32:29
@@ -56,7 +56,7 @@ LL |         let (_b, _c) = (&X, &Y);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         let (_b, _c) = (&X, addr_of!(Y));
-   |                             ~~~~~~~~~~~
+   |                             ~~~~~~~~~ +
 
 error[E0796]: creating a shared reference to a mutable static
   --> $DIR/reference-to-mut-static.rs:38:13
@@ -68,7 +68,7 @@ LL |         foo(&X);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |         foo(addr_of!(X));
-   |             ~~~~~~~~~~~
+   |             ~~~~~~~~~ +
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/static/safe-extern-statics-mut.stderr b/tests/ui/static/safe-extern-statics-mut.stderr
index 9a4b651405f..7705a897e27 100644
--- a/tests/ui/static/safe-extern-statics-mut.stderr
+++ b/tests/ui/static/safe-extern-statics-mut.stderr
@@ -11,7 +11,7 @@ LL |     let rb = &B;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     let rb = addr_of!(B);
-   |              ~~~~~~~~~~~
+   |              ~~~~~~~~~ +
 
 warning: creating a shared reference to mutable static is discouraged
   --> $DIR/safe-extern-statics-mut.rs:15:15
@@ -25,7 +25,7 @@ LL |     let xrb = &XB;
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     let xrb = addr_of!(XB);
-   |               ~~~~~~~~~~~~
+   |               ~~~~~~~~~  +
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/safe-extern-statics-mut.rs:11:13
diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr
index c31793f3d8f..6035eef5b71 100644
--- a/tests/ui/statics/issue-15261.stderr
+++ b/tests/ui/statics/issue-15261.stderr
@@ -11,7 +11,7 @@ LL | static n: &'static usize = unsafe { &n_mut };
 help: use `addr_of!` instead to create a raw pointer
    |
 LL | static n: &'static usize = unsafe { addr_of!(n_mut) };
-   |                                     ~~~~~~~~~~~~~~~
+   |                                     ~~~~~~~~~     +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr
index d381328c071..9751f754332 100644
--- a/tests/ui/statics/static-mut-xc.stderr
+++ b/tests/ui/statics/static-mut-xc.stderr
@@ -11,7 +11,7 @@ LL |     static_bound(&static_mut_xc::a);
 help: use `addr_of!` instead to create a raw pointer
    |
 LL |     static_bound(addr_of!(static_mut_xc::a));
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                  ~~~~~~~~~                +
 
 warning: creating a mutable reference to mutable static is discouraged
   --> $DIR/static-mut-xc.rs:30:22
@@ -25,7 +25,7 @@ LL |     static_bound_set(&mut static_mut_xc::a);
 help: use `addr_of_mut!` instead to create a raw pointer
    |
 LL |     static_bound_set(addr_of_mut!(static_mut_xc::a));
-   |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                      ~~~~~~~~~~~~~                +
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr
index cd285c6c2a4..a7a1a1610af 100644
--- a/tests/ui/statics/static-recursive.stderr
+++ b/tests/ui/statics/static-recursive.stderr
@@ -11,7 +11,7 @@ LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
 help: use `addr_of!` instead to create a raw pointer
    |
 LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 };
-   |                                    ~~~~~~~~~~~
+   |                                    ~~~~~~~~~ +
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs
index c2c3d6d547d..f3485d9c1fa 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs
@@ -10,7 +10,6 @@
 //@ ignore-wasm no panic or subprocess support
 //@ ignore-emscripten no panic or subprocess support
 //@ ignore-sgx no subprocess support
-//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
 
 #![cfg(test)]
 
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
index 4c94518d4d1..16001b3eecd 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
@@ -1,9 +1,9 @@
-thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:35:5:
+thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:34:5:
 assertion `left == right` failed
   left: 2
  right: 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:29:5:
+thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:28:5:
 assertion `left == right` failed
   left: 2
  right: 4
diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs
index 0c44acaffd7..84740161a70 100644
--- a/tests/ui/test-attrs/test-panic-abort.rs
+++ b/tests/ui/test-attrs/test-panic-abort.rs
@@ -10,7 +10,6 @@
 //@ ignore-wasm no panic or subprocess support
 //@ ignore-emscripten no panic or subprocess support
 //@ ignore-sgx no subprocess support
-//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
 
 #![cfg(test)]
 #![feature(test)]
diff --git a/tests/ui/test-attrs/test-panic-abort.run.stdout b/tests/ui/test-attrs/test-panic-abort.run.stdout
index 25105f38fcf..f5d14e77da9 100644
--- a/tests/ui/test-attrs/test-panic-abort.run.stdout
+++ b/tests/ui/test-attrs/test-panic-abort.run.stdout
@@ -17,7 +17,7 @@ hello, world
 testing123
 ---- it_fails stderr ----
 testing321
-thread 'main' panicked at $DIR/test-panic-abort.rs:40:5:
+thread 'main' panicked at $DIR/test-panic-abort.rs:39:5:
 assertion `left == right` failed
   left: 2
  right: 5
diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs
index 89b2da4452a..7338642beef 100644
--- a/tests/ui/traits/issue-105231.rs
+++ b/tests/ui/traits/issue-105231.rs
@@ -1,9 +1,9 @@
 //~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
 struct A<T>(B<T>);
 //~^ ERROR recursive types `A` and `B` have infinite size
-//~| ERROR `T` is never used
+//~| ERROR `T` is only used recursively
 struct B<T>(A<A<T>>);
-//~^ ERROR `T` is never used
+//~^ ERROR `T` is only used recursively
 trait Foo {}
 impl<T> Foo for T where T: Send {}
 impl Foo for B<u8> {}
diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr
index 6467a438375..d3014a79ad6 100644
--- a/tests/ui/traits/issue-105231.stderr
+++ b/tests/ui/traits/issue-105231.stderr
@@ -15,23 +15,27 @@ LL |
 LL ~ struct B<T>(Box<A<A<T>>>);
    |
 
-error[E0392]: type parameter `T` is never used
-  --> $DIR/issue-105231.rs:2:10
+error: type parameter `T` is only used recursively
+  --> $DIR/issue-105231.rs:2:15
    |
 LL | struct A<T>(B<T>);
-   |          ^ unused type parameter
+   |          -    ^
+   |          |
+   |          type parameter must be used non-recursively in the definition
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
-   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+   = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
-error[E0392]: type parameter `T` is never used
-  --> $DIR/issue-105231.rs:5:10
+error: type parameter `T` is only used recursively
+  --> $DIR/issue-105231.rs:5:17
    |
 LL | struct B<T>(A<A<T>>);
-   |          ^ unused type parameter
+   |          -      ^
+   |          |
+   |          type parameter must be used non-recursively in the definition
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
-   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+   = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
 error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
    |
@@ -44,5 +48,5 @@ LL | struct B<T>(A<A<T>>);
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0072, E0275, E0392.
+Some errors have detailed explanations: E0072, E0275.
 For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/variance/variance-unused-type-param.rs b/tests/ui/variance/variance-unused-type-param.rs
index d1114064364..ef3c41ca556 100644
--- a/tests/ui/variance/variance-unused-type-param.rs
+++ b/tests/ui/variance/variance-unused-type-param.rs
@@ -11,11 +11,14 @@ enum SomeEnum<A> { Nothing }
 
 // Here T might *appear* used, but in fact it isn't.
 enum ListCell<T> {
-//~^ ERROR parameter `T` is never used
     Cons(Box<ListCell<T>>),
+    //~^ ERROR parameter `T` is only used recursively
     Nil
 }
 
+struct SelfTyAlias<T>(Box<Self>);
+//~^ ERROR parameter `T` is only used recursively
+
 struct WithBounds<T: Sized> {}
 //~^ ERROR parameter `T` is never used
 
@@ -25,4 +28,9 @@ struct WithWhereBounds<T> where T: Sized {}
 struct WithOutlivesBounds<T: 'static> {}
 //~^ ERROR parameter `T` is never used
 
+struct DoubleNothing<T> {
+//~^ ERROR parameter `T` is never used
+    s: SomeStruct<T>,
+}
+
 fn main() {}
diff --git a/tests/ui/variance/variance-unused-type-param.stderr b/tests/ui/variance/variance-unused-type-param.stderr
index 3011b7bd18f..c747532e628 100644
--- a/tests/ui/variance/variance-unused-type-param.stderr
+++ b/tests/ui/variance/variance-unused-type-param.stderr
@@ -16,17 +16,30 @@ LL | enum SomeEnum<A> { Nothing }
    = help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
 
-error[E0392]: type parameter `T` is never used
-  --> $DIR/variance-unused-type-param.rs:13:15
+error: type parameter `T` is only used recursively
+  --> $DIR/variance-unused-type-param.rs:14:23
    |
 LL | enum ListCell<T> {
-   |               ^ unused type parameter
+   |               - type parameter must be used non-recursively in the definition
+LL |     Cons(Box<ListCell<T>>),
+   |                       ^
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
-   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+   = note: all type parameters must be used in a non-recursive way in order to constrain their variance
+
+error: type parameter `T` is only used recursively
+  --> $DIR/variance-unused-type-param.rs:19:27
+   |
+LL | struct SelfTyAlias<T>(Box<Self>);
+   |                    -      ^^^^
+   |                    |
+   |                    type parameter must be used non-recursively in the definition
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
 error[E0392]: type parameter `T` is never used
-  --> $DIR/variance-unused-type-param.rs:19:19
+  --> $DIR/variance-unused-type-param.rs:22:19
    |
 LL | struct WithBounds<T: Sized> {}
    |                   ^ unused type parameter
@@ -34,7 +47,7 @@ LL | struct WithBounds<T: Sized> {}
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
 error[E0392]: type parameter `T` is never used
-  --> $DIR/variance-unused-type-param.rs:22:24
+  --> $DIR/variance-unused-type-param.rs:25:24
    |
 LL | struct WithWhereBounds<T> where T: Sized {}
    |                        ^ unused type parameter
@@ -42,13 +55,25 @@ LL | struct WithWhereBounds<T> where T: Sized {}
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
 error[E0392]: type parameter `T` is never used
-  --> $DIR/variance-unused-type-param.rs:25:27
+  --> $DIR/variance-unused-type-param.rs:28:27
    |
 LL | struct WithOutlivesBounds<T: 'static> {}
    |                           ^ unused type parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: aborting due to 6 previous errors
+error[E0392]: type parameter `T` is never used
+  --> $DIR/variance-unused-type-param.rs:31:22
+   |
+LL | struct DoubleNothing<T> {
+   |                      ^ unused type parameter
+LL |
+LL |     s: SomeStruct<T>,
+   |                   - `T` is named here, but is likely unused in the containing type
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0392`.