about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-02 00:06:46 +0000
committerbors <bors@rust-lang.org>2024-03-02 00:06:46 +0000
commiteaee1e9453bfb4e1fb3753aa37450bb47cd7629d (patch)
treefa527cb250e0d9057b6f58b7fdae689dc842272b
parente612d079a1102803fd2cae5dcd7f7f277e493b8e (diff)
parent63e916e26c7d7d5b0df63639c7ff7b5b586a68e2 (diff)
downloadrust-eaee1e9453bfb4e1fb3753aa37450bb47cd7629d.tar.gz
rust-eaee1e9453bfb4e1fb3753aa37450bb47cd7629d.zip
Auto merge of #121870 - matthiaskrgr:rollup-mfpa3jx, r=matthiaskrgr
Rollup of 11 pull requests

Successful merges:

 - #111505 (Made `INVALID_DOC_ATTRIBUTES` lint deny by default)
 - #120305 (Delete line if suggestion would replace it with an empty line)
 - #121153 (Suggest removing superfluous semicolon when statements used as expression)
 - #121497 (`-Znext-solver=coherence`: suggest increasing recursion limit)
 - #121634 (Clarify behavior of slice prefix/suffix operations in case of equality)
 - #121706 (match lowering: Remove hacky branch in sort_candidate)
 - #121730 (Add profiling support to AIX)
 - #121750 (match lowering: Separate the `bool` case from other integers in `TestKind`)
 - #121803 (Never say "`Trait` is implemented for `{type error}`")
 - #121811 (Move sanitizer ui tests to sanitizer directory)
 - #121824 (Implement missing ABI structures in StableMIR)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs4
-rw-r--r--compiler/rustc_errors/src/json.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs41
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs96
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs10
-rw-r--r--compiler/rustc_infer/src/traits/structural_impls.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs11
-rw-r--r--compiler/rustc_middle/src/traits/solve.rs30
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs17
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs122
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/abi.rs69
-rw-r--r--compiler/rustc_trait_selection/src/solve/alias_relate.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs33
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs237
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs105
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs58
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs1
-rw-r--r--compiler/stable_mir/src/abi.rs179
-rw-r--r--compiler/stable_mir/src/error.rs11
-rw-r--r--compiler/stable_mir/src/target.rs10
-rw-r--r--compiler/stable_mir/src/ty.rs7
-rw-r--r--library/core/src/slice/mod.rs14
-rw-r--r--library/profiler_builtins/build.rs1
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.fixed8
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.fixed2
-rw-r--r--src/tools/clippy/tests/ui/must_use_unit.fixed3
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports.fixed1
-rw-r--r--src/tools/tidy/src/issues.txt6
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff15
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff15
-rw-r--r--tests/rustdoc-ui/doc-include-suggestion.rs6
-rw-r--r--tests/rustdoc-ui/doc-include-suggestion.stderr10
-rw-r--r--tests/rustdoc-ui/doctest/doc-test-attr.rs4
-rw-r--r--tests/rustdoc-ui/doctest/doc-test-attr.stderr20
-rw-r--r--tests/rustdoc-ui/lints/doc-attr.rs8
-rw-r--r--tests/rustdoc-ui/lints/doc-attr.stderr41
-rw-r--r--tests/rustdoc-ui/lints/doc-spotlight.fixed2
-rw-r--r--tests/rustdoc-ui/lints/doc-spotlight.rs2
-rw-r--r--tests/rustdoc-ui/lints/doc-spotlight.stderr11
-rw-r--r--tests/rustdoc-ui/lints/doc_cfg_hide.rs4
-rw-r--r--tests/rustdoc-ui/lints/doc_cfg_hide.stderr21
-rw-r--r--tests/rustdoc-ui/lints/invalid-doc-attr.rs9
-rw-r--r--tests/rustdoc-ui/lints/invalid-doc-attr.stderr50
-rw-r--r--tests/ui-fulldeps/stable-mir/check_abi.rs45
-rw-r--r--tests/ui/associated-consts/issue-105330.stderr2
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-6.fixed1
-rw-r--r--tests/ui/attributes/doc-attr.rs8
-rw-r--r--tests/ui/attributes/doc-attr.stderr41
-rw-r--r--tests/ui/attributes/doc-test-literal.rs3
-rw-r--r--tests/ui/attributes/doc-test-literal.stderr11
-rw-r--r--tests/ui/future-incompatible-lint-group.rs3
-rw-r--r--tests/ui/future-incompatible-lint-group.stderr9
-rw-r--r--tests/ui/generics/generic-no-mangle.fixed2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr1
-rw-r--r--tests/ui/imports/issue-52891.fixed2
-rw-r--r--tests/ui/imports/unused-import-issue-87973.fixed1
-rw-r--r--tests/ui/inference/stmts-as-exp-105431.rs76
-rw-r--r--tests/ui/inference/stmts-as-exp-105431.stderr129
-rw-r--r--tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr2
-rw-r--r--tests/ui/lazy-type-alias/leading-where-clause.fixed2
-rw-r--r--tests/ui/lint/suggestions.fixed1
-rw-r--r--tests/ui/lint/unused/import_remove_line.fixed11
-rw-r--r--tests/ui/lint/unused/import_remove_line.rs13
-rw-r--r--tests/ui/lint/unused/import_remove_line.stderr32
-rw-r--r--tests/ui/repr/invalid_repr_list_help.rs3
-rw-r--r--tests/ui/repr/invalid_repr_list_help.stderr8
-rw-r--r--tests/ui/resolve/resolve-conflict-import-vs-import.fixed1
-rw-r--r--tests/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed1
-rw-r--r--tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed1
-rw-r--r--tests/ui/rustdoc/deny-invalid-doc-attrs.rs2
-rw-r--r--tests/ui/rustdoc/deny-invalid-doc-attrs.stderr2
-rw-r--r--tests/ui/rustdoc/doc-primitive.rs1
-rw-r--r--tests/ui/rustdoc/doc-primitive.stderr2
-rw-r--r--tests/ui/rustdoc/doc-test-attr.rs3
-rw-r--r--tests/ui/rustdoc/doc-test-attr.stderr12
-rw-r--r--tests/ui/sanitizer/address.rs (renamed from tests/ui/sanitize/address.rs)0
-rw-r--r--tests/ui/sanitizer/badfree.rs (renamed from tests/ui/sanitize/badfree.rs)0
-rw-r--r--tests/ui/sanitizer/cfg-kasan.rs (renamed from tests/ui/sanitize/cfg-kasan.rs)0
-rw-r--r--tests/ui/sanitizer/cfg.rs (renamed from tests/ui/sanitize/cfg.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-canonical-jump-tables-requires-cfi.rs (renamed from tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-canonical-jump-tables-requires-cfi.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.stderr)0
-rw-r--r--tests/ui/sanitizer/cfi-generalize-pointers-attr-cfg.rs (renamed from tests/ui/sanitize/sanitizer-cfi-generalize-pointers-attr-cfg.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-generalize-pointers-requires-cfi.rs (renamed from tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-generalize-pointers-requires-cfi.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.stderr)0
-rw-r--r--tests/ui/sanitizer/cfi-invalid-attr-cfi-encoding.rs (renamed from tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-invalid-attr-cfi-encoding.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.stderr)2
-rw-r--r--tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.aarch64.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.aarch64.stderr)0
-rw-r--r--tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.rs (renamed from tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.x86_64.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.x86_64.stderr)0
-rw-r--r--tests/ui/sanitizer/cfi-normalize-integers-attr-cfg.rs (renamed from tests/ui/sanitize/sanitizer-cfi-normalize-integers-attr-cfg.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-normalize-integers-requires-cfi.rs (renamed from tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-normalize-integers-requires-cfi.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.stderr)0
-rw-r--r--tests/ui/sanitizer/cfi-requires-lto.rs (renamed from tests/ui/sanitize/sanitizer-cfi-requires-lto.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-requires-lto.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr)0
-rw-r--r--tests/ui/sanitizer/cfi-with-rustc-lto-requires-single-codegen-unit.rs (renamed from tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs)0
-rw-r--r--tests/ui/sanitizer/cfi-with-rustc-lto-requires-single-codegen-unit.stderr (renamed from tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr)0
-rw-r--r--tests/ui/sanitizer/crt-static.rs (renamed from tests/ui/sanitize/crt-static.rs)0
-rw-r--r--tests/ui/sanitizer/crt-static.stderr (renamed from tests/ui/sanitize/crt-static.stderr)0
-rw-r--r--tests/ui/sanitizer/hwaddress.rs (renamed from tests/ui/sanitize/hwaddress.rs)0
-rw-r--r--tests/ui/sanitizer/incompatible.rs (renamed from tests/ui/sanitize/incompatible.rs)0
-rw-r--r--tests/ui/sanitizer/incompatible.stderr (renamed from tests/ui/sanitize/incompatible.stderr)0
-rw-r--r--tests/ui/sanitizer/inline-always.rs (renamed from tests/ui/sanitize/inline-always.rs)0
-rw-r--r--tests/ui/sanitizer/inline-always.stderr (renamed from tests/ui/sanitize/inline-always.stderr)0
-rw-r--r--tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs (renamed from tests/ui/sanitize/issue-111184-coroutine-witness.rs)0
-rw-r--r--tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs (renamed from tests/ui/sanitize/issue-114275-cfi-const-expr-in-arry-len.rs)0
-rw-r--r--tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs (renamed from tests/ui/sanitize/issue-72154-lifetime-markers.rs)0
-rw-r--r--tests/ui/sanitizer/leak.rs (renamed from tests/ui/sanitize/leak.rs)0
-rw-r--r--tests/ui/sanitizer/memory-eager.rs (renamed from tests/ui/sanitize/memory-eager.rs)0
-rw-r--r--tests/ui/sanitizer/memory-passing.rs (renamed from tests/ui/sanitize/memory-passing.rs)0
-rw-r--r--tests/ui/sanitizer/memory.rs (renamed from tests/ui/sanitize/memory.rs)0
-rw-r--r--tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs (renamed from tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs)0
-rw-r--r--tests/ui/sanitizer/split-lto-unit-requires-lto.rs (renamed from tests/ui/sanitize/split-lto-unit-requires-lto.rs)0
-rw-r--r--tests/ui/sanitizer/split-lto-unit-requires-lto.stderr (renamed from tests/ui/sanitize/split-lto-unit-requires-lto.stderr)0
-rw-r--r--tests/ui/sanitizer/thread.rs (renamed from tests/ui/sanitize/thread.rs)0
-rw-r--r--tests/ui/sanitizer/unsupported-target.rs (renamed from tests/ui/sanitize/unsupported-target.rs)0
-rw-r--r--tests/ui/sanitizer/unsupported-target.stderr (renamed from tests/ui/sanitize/unsupported-target.stderr)0
-rw-r--r--tests/ui/sanitizer/use-after-scope.rs (renamed from tests/ui/sanitize/use-after-scope.rs)0
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.stderr10
-rw-r--r--tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr3
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr3
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr1
-rw-r--r--tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr2
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr1
-rw-r--r--tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr2
-rw-r--r--tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr1
-rw-r--r--tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr1
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-2.stderr8
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-4.next.stderr5
-rw-r--r--tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr1
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs7
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr27
137 files changed, 1165 insertions, 708 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 1f3383815e2..e52efd86955 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1631,7 +1631,9 @@ impl<'a> Linker for AixLinker<'a> {
 
     fn optimize(&mut self) {}
 
-    fn pgo_gen(&mut self) {}
+    fn pgo_gen(&mut self) {
+        self.cmd.arg("-bdbg:namedsects:ss");
+    }
 
     fn control_flow_guard(&mut self) {}
 
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index bc1822f83fc..af82d8092c2 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -428,7 +428,7 @@ impl DiagnosticSpan {
     }
 
     fn from_span_full(
-        span: Span,
+        mut span: Span,
         is_primary: bool,
         label: Option<String>,
         suggestion: Option<(&String, Applicability)>,
@@ -436,6 +436,16 @@ impl DiagnosticSpan {
         je: &JsonEmitter,
     ) -> DiagnosticSpan {
         let start = je.sm.lookup_char_pos(span.lo());
+        // If this goes from the start of a line to the end and the replacement
+        // is an empty string, increase the length to include the newline so we don't
+        // leave an empty line
+        if start.col.0 == 0
+            && suggestion.map_or(false, |(s, _)| s.is_empty())
+            && let Ok(after) = je.sm.span_to_next_source(span)
+            && after.starts_with('\n')
+        {
+            span = span.with_hi(span.hi() + rustc_span::BytePos(1));
+        }
         let end = je.sm.lookup_char_pos(span.hi());
         let backtrace_step = backtrace.next().map(|bt| {
             let call_site = Self::from_span_full(bt.call_site, false, None, None, backtrace, je);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 1311cc8968a..fc674520295 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1744,7 +1744,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                         Ty::new_unit(self.tcx),
                                     );
                                 }
-                                if !self.consider_removing_semicolon(blk, expected_ty, err) {
+                                if !self.err_ctxt().consider_removing_semicolon(
+                                    blk,
+                                    expected_ty,
+                                    err,
+                                ) {
                                     self.err_ctxt().consider_returning_binding(
                                         blk,
                                         expected_ty,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index ccd9b38bf62..809102557ac 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -22,7 +22,7 @@ use rustc_hir::{
     Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
 };
 use rustc_hir_analysis::astconv::AstConv;
-use rustc_infer::traits::{self, StatementAsExpression};
+use rustc_infer::traits::{self};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -1791,45 +1791,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    /// A common error is to add an extra semicolon:
-    ///
-    /// ```compile_fail,E0308
-    /// fn foo() -> usize {
-    ///     22;
-    /// }
-    /// ```
-    ///
-    /// This routine checks if the final statement in a block is an
-    /// expression with an explicit semicolon whose type is compatible
-    /// with `expected_ty`. If so, it suggests removing the semicolon.
-    pub(crate) fn consider_removing_semicolon(
-        &self,
-        blk: &'tcx hir::Block<'tcx>,
-        expected_ty: Ty<'tcx>,
-        err: &mut Diag<'_>,
-    ) -> bool {
-        if let Some((span_semi, boxed)) = self.err_ctxt().could_remove_semicolon(blk, expected_ty) {
-            if let StatementAsExpression::NeedsBoxing = boxed {
-                err.span_suggestion_verbose(
-                    span_semi,
-                    "consider removing this semicolon and boxing the expression",
-                    "",
-                    Applicability::HasPlaceholders,
-                );
-            } else {
-                err.span_suggestion_short(
-                    span_semi,
-                    "remove this semicolon to return this value",
-                    "",
-                    Applicability::MachineApplicable,
-                );
-            }
-            true
-        } else {
-            false
-        }
-    }
-
     pub(crate) fn is_field_suggestable(
         &self,
         field: &ty::FieldDef,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index af1aa346c09..342f18a18dc 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1989,6 +1989,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
                 self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
                 self.suggest_function_pointers(cause, span, &exp_found, diag);
+                self.suggest_turning_stmt_into_expr(cause, &exp_found, diag);
             }
         }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index cfe8b75bdd7..472dab639d5 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -1,8 +1,13 @@
+use crate::infer::error_reporting::hir::Path;
 use hir::def::CtorKind;
 use hir::intravisit::{walk_expr, walk_stmt, Visitor};
+use hir::{Local, QPath};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir as hir;
+use rustc_hir::def::Res;
+use rustc_hir::MatchSource;
+use rustc_hir::Node;
 use rustc_middle::traits::{
     IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
     StatementAsExpression,
@@ -293,6 +298,97 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
     }
 
+    pub(super) fn suggest_turning_stmt_into_expr(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
+        diag: &mut Diag<'_>,
+    ) {
+        let ty::error::ExpectedFound { expected, found } = exp_found;
+        if !found.peel_refs().is_unit() {
+            return;
+        }
+
+        let ObligationCauseCode::BlockTailExpression(hir_id, MatchSource::Normal) = cause.code()
+        else {
+            return;
+        };
+
+        let node = self.tcx.hir_node(*hir_id);
+        let mut blocks = vec![];
+        if let hir::Node::Block(block) = node
+            && let Some(expr) = block.expr
+            && let hir::ExprKind::Path(QPath::Resolved(_, Path { res, .. })) = expr.kind
+            && let Res::Local(local) = res
+            && let Node::Local(Local { init: Some(init), .. }) = self.tcx.parent_hir_node(*local)
+        {
+            fn collect_blocks<'hir>(expr: &hir::Expr<'hir>, blocks: &mut Vec<&hir::Block<'hir>>) {
+                match expr.kind {
+                    // `blk1` and `blk2` must be have the same types, it will be reported before reaching here
+                    hir::ExprKind::If(_, blk1, Some(blk2)) => {
+                        collect_blocks(blk1, blocks);
+                        collect_blocks(blk2, blocks);
+                    }
+                    hir::ExprKind::Match(_, arms, _) => {
+                        // all arms must have same types
+                        for arm in arms.iter() {
+                            collect_blocks(arm.body, blocks);
+                        }
+                    }
+                    hir::ExprKind::Block(blk, _) => {
+                        blocks.push(blk);
+                    }
+                    _ => {}
+                }
+            }
+            collect_blocks(init, &mut blocks);
+        }
+
+        let expected_inner: Ty<'_> = expected.peel_refs();
+        for block in blocks.iter() {
+            self.consider_removing_semicolon(block, expected_inner, diag);
+        }
+    }
+
+    /// A common error is to add an extra semicolon:
+    ///
+    /// ```compile_fail,E0308
+    /// fn foo() -> usize {
+    ///     22;
+    /// }
+    /// ```
+    ///
+    /// This routine checks if the final statement in a block is an
+    /// expression with an explicit semicolon whose type is compatible
+    /// with `expected_ty`. If so, it suggests removing the semicolon.
+    pub fn consider_removing_semicolon(
+        &self,
+        blk: &'tcx hir::Block<'tcx>,
+        expected_ty: Ty<'tcx>,
+        diag: &mut Diag<'_>,
+    ) -> bool {
+        if let Some((span_semi, boxed)) = self.could_remove_semicolon(blk, expected_ty) {
+            if let StatementAsExpression::NeedsBoxing = boxed {
+                diag.span_suggestion_verbose(
+                    span_semi,
+                    "consider removing this semicolon and boxing the expression",
+                    "",
+                    Applicability::HasPlaceholders,
+                );
+            } else {
+                diag.span_suggestion_short(
+                    span_semi,
+                    "remove this semicolon to return this value",
+                    "",
+                    Applicability::MachineApplicable,
+                );
+            }
+            true
+        } else {
+            false
+        }
+    }
+
     pub(super) fn suggest_function_pointers(
         &self,
         cause: &ObligationCause<'tcx>,
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 72ec07375ac..4808a1defdd 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -135,16 +135,18 @@ pub struct FulfillmentError<'tcx> {
 
 #[derive(Clone)]
 pub enum FulfillmentErrorCode<'tcx> {
-    /// Inherently impossible to fulfill; this trait is implemented if and only if it is already implemented.
+    /// Inherently impossible to fulfill; this trait is implemented if and only
+    /// if it is already implemented.
     Cycle(Vec<PredicateObligation<'tcx>>),
     SelectionError(SelectionError<'tcx>),
     ProjectionError(MismatchedProjectionTypes<'tcx>),
     SubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
     ConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
     Ambiguity {
-        /// Overflow reported from the new solver `-Znext-solver`, which will
-        /// be reported as an regular error as opposed to a fatal error.
-        overflow: bool,
+        /// Overflow is only `Some(suggest_recursion_limit)` when using the next generation
+        /// trait solver `-Znext-solver`. With the old solver overflow is eagerly handled by
+        /// emitting a fatal error instead.
+        overflow: Option<bool>,
     },
 }
 
diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs
index 3b4050fcd27..bf4f88530d0 100644
--- a/compiler/rustc_infer/src/traits/structural_impls.rs
+++ b/compiler/rustc_infer/src/traits/structural_impls.rs
@@ -47,8 +47,10 @@ impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> {
             ConstEquateError(ref a, ref b) => {
                 write!(f, "CodeConstEquateError({a:?}, {b:?})")
             }
-            Ambiguity { overflow: false } => write!(f, "Ambiguity"),
-            Ambiguity { overflow: true } => write!(f, "Overflow"),
+            Ambiguity { overflow: None } => write!(f, "Ambiguity"),
+            Ambiguity { overflow: Some(suggest_increasing_limit) } => {
+                write!(f, "Overflow({suggest_increasing_limit})")
+            }
             Cycle(ref cycle) => write!(f, "Cycle({cycle:?})"),
         }
     }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 1cddb45428c..94f8bbe2437 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3586,18 +3586,9 @@ declare_lint! {
     /// being validated. Usually these should be rejected as a hard error,
     /// but this lint was introduced to avoid breaking any existing
     /// crates which included them.
-    ///
-    /// This is a [future-incompatible] lint to transition this to a hard
-    /// error in the future. See [issue #82730] for more details.
-    ///
-    /// [issue #82730]: https://github.com/rust-lang/rust/issues/82730
     pub INVALID_DOC_ATTRIBUTES,
-    Warn,
+    Deny,
     "detects invalid `#[doc(...)]` attributes",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
-        reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>",
-    };
 }
 
 declare_lint! {
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index 048df367bd6..0dc65126011 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -60,7 +60,6 @@ pub enum Certainty {
 
 impl Certainty {
     pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
-    pub const OVERFLOW: Certainty = Certainty::Maybe(MaybeCause::Overflow);
 
     /// Use this function to merge the certainty of multiple nested subgoals.
     ///
@@ -79,16 +78,13 @@ impl Certainty {
             (Certainty::Yes, Certainty::Yes) => Certainty::Yes,
             (Certainty::Yes, Certainty::Maybe(_)) => other,
             (Certainty::Maybe(_), Certainty::Yes) => self,
-            (Certainty::Maybe(MaybeCause::Ambiguity), Certainty::Maybe(MaybeCause::Ambiguity)) => {
-                Certainty::Maybe(MaybeCause::Ambiguity)
-            }
-            (Certainty::Maybe(MaybeCause::Ambiguity), Certainty::Maybe(MaybeCause::Overflow))
-            | (Certainty::Maybe(MaybeCause::Overflow), Certainty::Maybe(MaybeCause::Ambiguity))
-            | (Certainty::Maybe(MaybeCause::Overflow), Certainty::Maybe(MaybeCause::Overflow)) => {
-                Certainty::Maybe(MaybeCause::Overflow)
-            }
+            (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)),
         }
     }
+
+    pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
+        Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit })
+    }
 }
 
 /// Why we failed to evaluate a goal.
@@ -99,7 +95,21 @@ pub enum MaybeCause {
     /// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
     Ambiguity,
     /// We gave up due to an overflow, most often by hitting the recursion limit.
-    Overflow,
+    Overflow { suggest_increasing_limit: bool },
+}
+
+impl MaybeCause {
+    fn unify_with(self, other: MaybeCause) -> MaybeCause {
+        match (self, other) {
+            (MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
+            (MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
+            (MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
+            (
+                MaybeCause::Overflow { suggest_increasing_limit: a },
+                MaybeCause::Overflow { suggest_increasing_limit: b },
+            ) => MaybeCause::Overflow { suggest_increasing_limit: a || b },
+        }
+    }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 6cdb78d1a94..d8dfb910de5 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1097,21 +1097,18 @@ enum TestKind<'tcx> {
         variants: BitSet<VariantIdx>,
     },
 
-    /// Test what value an integer, `bool`, or `char` has.
+    /// Test what value an integer or `char` has.
     SwitchInt {
-        /// The type of the value that we're testing.
-        switch_ty: Ty<'tcx>,
         /// The (ordered) set of values that we test for.
         ///
-        /// For integers and `char`s we create a branch to each of the values in
-        /// `options`, as well as an "otherwise" branch for all other values, even
-        /// in the (rare) case that `options` is exhaustive.
-        ///
-        /// For `bool` we always generate two edges, one for `true` and one for
-        /// `false`.
+        /// We create a branch to each of the values in `options`, as well as an "otherwise" branch
+        /// for all other values, even in the (rare) case that `options` is exhaustive.
         options: FxIndexMap<Const<'tcx>, u128>,
     },
 
+    /// Test what value a `bool` has.
+    If,
+
     /// Test for equality with value, possibly after an unsizing coercion to
     /// `ty`,
     Eq {
@@ -1617,7 +1614,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // a test like SwitchInt, we may want to add cases based on the candidates that are
         // available
         match test.kind {
-            TestKind::SwitchInt { switch_ty: _, ref mut options } => {
+            TestKind::SwitchInt { ref mut options } => {
                 for candidate in candidates.iter() {
                     if !self.add_cases_to_switch(&match_place, candidate, options) {
                         break;
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 1b6994966d1..8ce7461747b 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -34,12 +34,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 TestKind::Switch { adt_def, variants: BitSet::new_empty(adt_def.variants().len()) }
             }
 
+            TestCase::Constant { .. } if match_pair.pattern.ty.is_bool() => TestKind::If,
+
             TestCase::Constant { .. } if is_switch_ty(match_pair.pattern.ty) => {
                 // For integers, we use a `SwitchInt` match, which allows
                 // us to handle more cases.
                 TestKind::SwitchInt {
-                    switch_ty: match_pair.pattern.ty,
-
                     // these maps are empty to start; cases are
                     // added below in add_cases_to_switch
                     options: Default::default(),
@@ -182,31 +182,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 );
             }
 
-            TestKind::SwitchInt { switch_ty, ref options } => {
-                let terminator = if *switch_ty.kind() == ty::Bool {
-                    assert!(!options.is_empty() && options.len() <= 2);
-                    let [first_bb, second_bb] = *target_blocks else {
-                        bug!("`TestKind::SwitchInt` on `bool` should have two targets")
-                    };
-                    let (true_bb, false_bb) = match options[0] {
-                        1 => (first_bb, second_bb),
-                        0 => (second_bb, first_bb),
-                        v => span_bug!(test.span, "expected boolean value but got {:?}", v),
-                    };
-                    TerminatorKind::if_(Operand::Copy(place), true_bb, false_bb)
-                } else {
-                    // The switch may be inexhaustive so we have a catch all block
-                    debug_assert_eq!(options.len() + 1, target_blocks.len());
-                    let otherwise_block = *target_blocks.last().unwrap();
-                    let switch_targets = SwitchTargets::new(
-                        options.values().copied().zip(target_blocks),
-                        otherwise_block,
-                    );
-                    TerminatorKind::SwitchInt {
-                        discr: Operand::Copy(place),
-                        targets: switch_targets,
-                    }
+            TestKind::SwitchInt { ref options } => {
+                // The switch may be inexhaustive so we have a catch-all block
+                debug_assert_eq!(options.len() + 1, target_blocks.len());
+                let otherwise_block = *target_blocks.last().unwrap();
+                let switch_targets = SwitchTargets::new(
+                    options.values().copied().zip(target_blocks),
+                    otherwise_block,
+                );
+                let terminator = TerminatorKind::SwitchInt {
+                    discr: Operand::Copy(place),
+                    targets: switch_targets,
+                };
+                self.cfg.terminate(block, self.source_info(match_start_span), terminator);
+            }
+
+            TestKind::If => {
+                let [false_bb, true_bb] = *target_blocks else {
+                    bug!("`TestKind::If` should have two targets")
                 };
+                let terminator = TerminatorKind::if_(Operand::Copy(place), true_bb, false_bb);
                 self.cfg.terminate(block, self.source_info(match_start_span), terminator);
             }
 
@@ -583,24 +578,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 fully_matched = true;
                 Some(variant_index.as_usize())
             }
-            (&TestKind::Switch { .. }, _) => {
-                fully_matched = false;
-                None
-            }
 
             // If we are performing a switch over integers, then this informs integer
             // equality, but nothing else.
             //
             // FIXME(#29623) we could use PatKind::Range to rule
             // things out here, in some cases.
-            (TestKind::SwitchInt { switch_ty: _, options }, TestCase::Constant { value })
+            (TestKind::SwitchInt { options }, TestCase::Constant { value })
                 if is_switch_ty(match_pair.pattern.ty) =>
             {
                 fully_matched = true;
                 let index = options.get_index_of(value).unwrap();
                 Some(index)
             }
-            (TestKind::SwitchInt { switch_ty: _, options }, TestCase::Range(range)) => {
+            (TestKind::SwitchInt { options }, TestCase::Range(range)) => {
                 fully_matched = false;
                 let not_contained =
                     self.values_not_contained_in_range(&*range, options).unwrap_or(false);
@@ -611,7 +602,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     options.len()
                 })
             }
-            (&TestKind::SwitchInt { .. }, _) => {
+
+            (&TestKind::If, TestCase::Constant { value }) => {
+                fully_matched = true;
+                let value = value.try_eval_bool(self.tcx, self.param_env).unwrap_or_else(|| {
+                    span_bug!(test.span, "expected boolean value but got {value:?}")
+                });
+                Some(value as usize)
+            }
+            (&TestKind::If, _) => {
                 fully_matched = false;
                 None
             }
@@ -703,34 +702,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     None
                 }
             }
-            (&TestKind::Range { .. }, _) => {
-                fully_matched = false;
-                None
-            }
 
-            (&TestKind::Eq { .. } | &TestKind::Len { .. }, _) => {
-                // The call to `self.test(&match_pair)` below is not actually used to generate any
-                // MIR. Instead, we just want to compare with `test` (the parameter of the method)
-                // to see if it is the same.
-                //
-                // However, at this point we can still encounter or-patterns that were extracted
-                // from previous calls to `sort_candidate`, so we need to manually address that
-                // case to avoid panicking in `self.test()`.
-                if let TestCase::Or { .. } = &match_pair.test_case {
-                    return None;
-                }
+            // FIXME(#29623): return `Some(1)` when the values are different.
+            (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val })
+                if test_val == case_val =>
+            {
+                fully_matched = true;
+                Some(0)
+            }
 
-                // These are all binary tests.
-                //
-                // FIXME(#29623) we can be more clever here
-                let pattern_test = self.test(match_pair);
-                if pattern_test.kind == test.kind {
-                    fully_matched = true;
-                    Some(0)
-                } else {
-                    fully_matched = false;
-                    None
-                }
+            (
+                TestKind::Switch { .. }
+                | TestKind::SwitchInt { .. }
+                | TestKind::Len { .. }
+                | TestKind::Range { .. }
+                | TestKind::Eq { .. },
+                _,
+            ) => {
+                fully_matched = false;
+                None
             }
         };
 
@@ -763,7 +753,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 impl Test<'_> {
     pub(super) fn targets(&self) -> usize {
         match self.kind {
-            TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } => 2,
+            TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } | TestKind::If => 2,
             TestKind::Switch { adt_def, .. } => {
                 // While the switch that we generate doesn't test for all
                 // variants, we have a target for each variant and the
@@ -771,21 +761,13 @@ impl Test<'_> {
                 // specified have the same block.
                 adt_def.variants().len() + 1
             }
-            TestKind::SwitchInt { switch_ty, ref options, .. } => {
-                if switch_ty.is_bool() {
-                    // `bool` is special cased in `perform_test` to always
-                    // branch to two blocks.
-                    2
-                } else {
-                    options.len() + 1
-                }
-            }
+            TestKind::SwitchInt { ref options } => options.len() + 1,
         }
     }
 }
 
 fn is_switch_ty(ty: Ty<'_>) -> bool {
-    ty.is_integral() || ty.is_char() || ty.is_bool()
+    ty.is_integral() || ty.is_char()
 }
 
 fn trait_method<'tcx>(
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
index 088a836c901..6fb1560ac6c 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs
@@ -6,11 +6,13 @@ use crate::rustc_smir::{Stable, Tables};
 use rustc_middle::ty;
 use rustc_target::abi::call::Conv;
 use stable_mir::abi::{
-    ArgAbi, CallConvention, FieldsShape, FnAbi, Layout, LayoutShape, PassMode, TagEncoding,
-    TyAndLayout, ValueAbi, VariantsShape,
+    AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, Layout,
+    LayoutShape, PassMode, Primitive, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantsShape,
+    WrappingRange,
 };
-use stable_mir::ty::{Align, IndexedVal, Size, VariantIdx};
-use stable_mir::{opaque, Opaque};
+use stable_mir::opaque;
+use stable_mir::target::MachineSize as Size;
+use stable_mir::ty::{Align, IndexedVal, VariantIdx};
 
 impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx {
     type T = VariantIdx;
@@ -220,7 +222,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Size {
     type T = Size;
 
     fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
-        self.bytes_usize()
+        Size::from_bits(self.bits_usize())
     }
 }
 
@@ -233,9 +235,62 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Align {
 }
 
 impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
-    type T = Opaque;
+    type T = Scalar;
+
+    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
+        match self {
+            rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
+                value: value.stable(tables),
+                valid_range: valid_range.stable(tables),
+            },
+            rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables) },
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
+    type T = Primitive;
+
+    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
+        match self {
+            rustc_abi::Primitive::Int(length, signed) => {
+                Primitive::Int { length: length.stable(tables), signed: *signed }
+            }
+            rustc_abi::Primitive::F16 => Primitive::Float { length: FloatLength::F16 },
+            rustc_abi::Primitive::F32 => Primitive::Float { length: FloatLength::F32 },
+            rustc_abi::Primitive::F64 => Primitive::Float { length: FloatLength::F64 },
+            rustc_abi::Primitive::F128 => Primitive::Float { length: FloatLength::F128 },
+            rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)),
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
+    type T = AddressSpace;
+
+    fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
+        AddressSpace(self.0)
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
+    type T = IntegerLength;
+
+    fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
+        match self {
+            rustc_abi::Integer::I8 => IntegerLength::I8,
+            rustc_abi::Integer::I16 => IntegerLength::I16,
+            rustc_abi::Integer::I32 => IntegerLength::I32,
+            rustc_abi::Integer::I64 => IntegerLength::I64,
+            rustc_abi::Integer::I128 => IntegerLength::I128,
+        }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
+    type T = WrappingRange;
 
     fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
-        opaque(self)
+        WrappingRange { start: self.start, end: self.end }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
index afd9d95cb57..67657c81cf6 100644
--- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs
+++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
@@ -36,11 +36,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
 
         let Some(lhs) = self.try_normalize_term(param_env, lhs)? else {
-            return self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW);
+            return self
+                .evaluate_added_goals_and_make_canonical_response(Certainty::overflow(true));
         };
 
         let Some(rhs) = self.try_normalize_term(param_env, rhs)? else {
-            return self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW);
+            return self
+                .evaluate_added_goals_and_make_canonical_response(Certainty::overflow(true));
         };
 
         let variance = match direction {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 4a86f708632..98d28f10a54 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -7,6 +7,7 @@ use rustc_infer::infer::{
     BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt,
 };
 use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::solve::MaybeCause;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::infer::canonical::CanonicalVarInfos;
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
@@ -29,7 +30,7 @@ use std::ops::ControlFlow;
 use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment};
 
 use super::inspect::ProofTreeBuilder;
-use super::{search_graph, GoalEvaluationKind};
+use super::{search_graph, GoalEvaluationKind, FIXPOINT_STEP_LIMIT};
 use super::{search_graph::SearchGraph, Goal};
 use super::{GoalSource, SolverMode};
 pub use select::InferCtxtSelectExt;
@@ -154,10 +155,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         self.search_graph.solver_mode()
     }
 
-    pub(super) fn local_overflow_limit(&self) -> usize {
-        self.search_graph.local_overflow_limit()
-    }
-
     /// Creates a root evaluation context and search graph. This should only be
     /// used from outside of any evaluation, and other methods should be preferred
     /// over using this manually (such as [`InferCtxtEvalExt::evaluate_root_goal`]).
@@ -167,7 +164,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> R,
     ) -> (R, Option<inspect::GoalEvaluation<'tcx>>) {
         let mode = if infcx.intercrate { SolverMode::Coherence } else { SolverMode::Normal };
-        let mut search_graph = search_graph::SearchGraph::new(infcx.tcx, mode);
+        let mut search_graph = search_graph::SearchGraph::new(mode);
 
         let mut ecx = EvalCtxt {
             search_graph: &mut search_graph,
@@ -388,16 +385,18 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 && source != GoalSource::ImplWhereBound
         };
 
-        if response.value.certainty == Certainty::OVERFLOW && !keep_overflow_constraints() {
-            (Certainty::OVERFLOW, false)
-        } else {
-            let has_changed = !response.value.var_values.is_identity_modulo_regions()
-                || !response.value.external_constraints.opaque_types.is_empty();
-
-            let certainty =
-                self.instantiate_and_apply_query_response(param_env, original_values, response);
-            (certainty, has_changed)
+        if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty
+            && !keep_overflow_constraints()
+        {
+            return (response.value.certainty, false);
         }
+
+        let has_changed = !response.value.var_values.is_identity_modulo_regions()
+            || !response.value.external_constraints.opaque_types.is_empty();
+
+        let certainty =
+            self.instantiate_and_apply_query_response(param_env, original_values, response);
+        (certainty, has_changed)
     }
 
     fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult<'tcx> {
@@ -466,8 +465,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         let inspect = self.inspect.new_evaluate_added_goals();
         let inspect = core::mem::replace(&mut self.inspect, inspect);
 
-        let mut response = Ok(Certainty::OVERFLOW);
-        for _ in 0..self.local_overflow_limit() {
+        let mut response = Ok(Certainty::overflow(false));
+        for _ in 0..FIXPOINT_STEP_LIMIT {
             // FIXME: This match is a bit ugly, it might be nice to change the inspect
             // stuff to use a closure instead. which should hopefully simplify this a bit.
             match self.evaluate_added_goals_step() {
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index c1b07765e50..bc2bae9da61 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -24,7 +24,7 @@ use super::{Certainty, InferCtxtEvalExt};
 /// It is also likely that we want to use slightly different datastructures
 /// here as this will have to deal with far more root goals than `evaluate_all`.
 pub struct FulfillmentCtxt<'tcx> {
-    obligations: Vec<PredicateObligation<'tcx>>,
+    obligations: ObligationStorage<'tcx>,
 
     /// The snapshot in which this context was created. Using the context
     /// outside of this snapshot leads to subtle bugs if the snapshot
@@ -33,6 +33,57 @@ pub struct FulfillmentCtxt<'tcx> {
     usable_in_snapshot: usize,
 }
 
+#[derive(Default)]
+struct ObligationStorage<'tcx> {
+    /// Obligations which resulted in an overflow in fulfillment itself.
+    ///
+    /// We cannot eagerly return these as error so we instead store them here
+    /// to avoid recomputing them each time `select_where_possible` is called.
+    /// This also allows us to return the correct `FulfillmentError` for them.
+    overflowed: Vec<PredicateObligation<'tcx>>,
+    pending: Vec<PredicateObligation<'tcx>>,
+}
+
+impl<'tcx> ObligationStorage<'tcx> {
+    fn register(&mut self, obligation: PredicateObligation<'tcx>) {
+        self.pending.push(obligation);
+    }
+
+    fn clone_pending(&self) -> Vec<PredicateObligation<'tcx>> {
+        let mut obligations = self.pending.clone();
+        obligations.extend(self.overflowed.iter().cloned());
+        obligations
+    }
+
+    fn take_pending(&mut self) -> Vec<PredicateObligation<'tcx>> {
+        let mut obligations = mem::take(&mut self.pending);
+        obligations.extend(self.overflowed.drain(..));
+        obligations
+    }
+
+    fn unstalled_for_select(&mut self) -> impl Iterator<Item = PredicateObligation<'tcx>> {
+        mem::take(&mut self.pending).into_iter()
+    }
+
+    fn on_fulfillment_overflow(&mut self, infcx: &InferCtxt<'tcx>) {
+        infcx.probe(|_| {
+            // IMPORTANT: we must not use solve any inference variables in the obligations
+            // as this is all happening inside of a probe. We use a probe to make sure
+            // we get all obligations involved in the overflow. We pretty much check: if
+            // we were to do another step of `select_where_possible`, which goals would
+            // change.
+            self.overflowed.extend(self.pending.extract_if(|o| {
+                let goal = o.clone().into();
+                let result = infcx.evaluate_root_goal(goal, GenerateProofTree::Never).0;
+                match result {
+                    Ok((has_changed, _)) => has_changed,
+                    _ => false,
+                }
+            }));
+        })
+    }
+}
+
 impl<'tcx> FulfillmentCtxt<'tcx> {
     pub fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentCtxt<'tcx> {
         assert!(
@@ -40,7 +91,10 @@ impl<'tcx> FulfillmentCtxt<'tcx> {
             "new trait solver fulfillment context created when \
             infcx is set up for old trait solver"
         );
-        FulfillmentCtxt { obligations: Vec::new(), usable_in_snapshot: infcx.num_open_snapshots() }
+        FulfillmentCtxt {
+            obligations: Default::default(),
+            usable_in_snapshot: infcx.num_open_snapshots(),
+        }
     }
 
     fn inspect_evaluated_obligation(
@@ -67,40 +121,24 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
         obligation: PredicateObligation<'tcx>,
     ) {
         assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
-        self.obligations.push(obligation);
+        self.obligations.register(obligation);
     }
 
     fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
-        self.obligations
+        let mut errors: Vec<_> = self
+            .obligations
+            .pending
             .drain(..)
-            .map(|obligation| {
-                let code = infcx.probe(|_| {
-                    match infcx
-                        .evaluate_root_goal(obligation.clone().into(), GenerateProofTree::IfEnabled)
-                        .0
-                    {
-                        Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
-                            FulfillmentErrorCode::Ambiguity { overflow: false }
-                        }
-                        Ok((_, Certainty::Maybe(MaybeCause::Overflow))) => {
-                            FulfillmentErrorCode::Ambiguity { overflow: true }
-                        }
-                        Ok((_, Certainty::Yes)) => {
-                            bug!("did not expect successful goal when collecting ambiguity errors")
-                        }
-                        Err(_) => {
-                            bug!("did not expect selection error when collecting ambiguity errors")
-                        }
-                    }
-                });
+            .map(|obligation| fulfillment_error_for_stalled(infcx, obligation))
+            .collect();
 
-                FulfillmentError {
-                    obligation: obligation.clone(),
-                    code,
-                    root_obligation: obligation,
-                }
-            })
-            .collect()
+        errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError {
+            root_obligation: obligation.clone(),
+            code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) },
+            obligation,
+        }));
+
+        errors
     }
 
     fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
@@ -108,79 +146,27 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
         let mut errors = Vec::new();
         for i in 0.. {
             if !infcx.tcx.recursion_limit().value_within_limit(i) {
-                // Only return true errors that we have accumulated while processing;
-                // keep ambiguities around, *including overflows*, because they shouldn't
-                // be considered true errors.
+                self.obligations.on_fulfillment_overflow(infcx);
+                // Only return true errors that we have accumulated while processing.
                 return errors;
             }
 
             let mut has_changed = false;
-            for obligation in mem::take(&mut self.obligations) {
+            for obligation in self.obligations.unstalled_for_select() {
                 let goal = obligation.clone().into();
                 let result = infcx.evaluate_root_goal(goal, GenerateProofTree::IfEnabled).0;
                 self.inspect_evaluated_obligation(infcx, &obligation, &result);
                 let (changed, certainty) = match result {
                     Ok(result) => result,
                     Err(NoSolution) => {
-                        errors.push(FulfillmentError {
-                            obligation: obligation.clone(),
-                            code: match goal.predicate.kind().skip_binder() {
-                                ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
-                                    FulfillmentErrorCode::ProjectionError(
-                                        // FIXME: This could be a `Sorts` if the term is a type
-                                        MismatchedProjectionTypes { err: TypeError::Mismatch },
-                                    )
-                                }
-                                ty::PredicateKind::NormalizesTo(..) => {
-                                    FulfillmentErrorCode::ProjectionError(
-                                        MismatchedProjectionTypes { err: TypeError::Mismatch },
-                                    )
-                                }
-                                ty::PredicateKind::AliasRelate(_, _, _) => {
-                                    FulfillmentErrorCode::ProjectionError(
-                                        MismatchedProjectionTypes { err: TypeError::Mismatch },
-                                    )
-                                }
-                                ty::PredicateKind::Subtype(pred) => {
-                                    let (a, b) = infcx.enter_forall_and_leak_universe(
-                                        goal.predicate.kind().rebind((pred.a, pred.b)),
-                                    );
-                                    let expected_found = ExpectedFound::new(true, a, b);
-                                    FulfillmentErrorCode::SubtypeError(
-                                        expected_found,
-                                        TypeError::Sorts(expected_found),
-                                    )
-                                }
-                                ty::PredicateKind::Coerce(pred) => {
-                                    let (a, b) = infcx.enter_forall_and_leak_universe(
-                                        goal.predicate.kind().rebind((pred.a, pred.b)),
-                                    );
-                                    let expected_found = ExpectedFound::new(false, a, b);
-                                    FulfillmentErrorCode::SubtypeError(
-                                        expected_found,
-                                        TypeError::Sorts(expected_found),
-                                    )
-                                }
-                                ty::PredicateKind::Clause(_)
-                                | ty::PredicateKind::ObjectSafe(_)
-                                | ty::PredicateKind::Ambiguous => {
-                                    FulfillmentErrorCode::SelectionError(
-                                        SelectionError::Unimplemented,
-                                    )
-                                }
-                                ty::PredicateKind::ConstEquate(..) => {
-                                    bug!("unexpected goal: {goal:?}")
-                                }
-                            },
-                            root_obligation: obligation,
-                        });
+                        errors.push(fulfillment_error_for_no_solution(infcx, obligation));
                         continue;
                     }
                 };
                 has_changed |= changed;
                 match certainty {
                     Certainty::Yes => {}
-                    Certainty::Maybe(_) => self.obligations.push(obligation),
+                    Certainty::Maybe(_) => self.obligations.register(obligation),
                 }
             }
 
@@ -193,13 +179,84 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
     }
 
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
-        self.obligations.clone()
+        self.obligations.clone_pending()
     }
 
     fn drain_unstalled_obligations(
         &mut self,
         _: &InferCtxt<'tcx>,
     ) -> Vec<PredicateObligation<'tcx>> {
-        std::mem::take(&mut self.obligations)
+        self.obligations.take_pending()
     }
 }
+
+fn fulfillment_error_for_no_solution<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    obligation: PredicateObligation<'tcx>,
+) -> FulfillmentError<'tcx> {
+    let code = match obligation.predicate.kind().skip_binder() {
+        ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
+            FulfillmentErrorCode::ProjectionError(
+                // FIXME: This could be a `Sorts` if the term is a type
+                MismatchedProjectionTypes { err: TypeError::Mismatch },
+            )
+        }
+        ty::PredicateKind::NormalizesTo(..) => {
+            FulfillmentErrorCode::ProjectionError(MismatchedProjectionTypes {
+                err: TypeError::Mismatch,
+            })
+        }
+        ty::PredicateKind::AliasRelate(_, _, _) => {
+            FulfillmentErrorCode::ProjectionError(MismatchedProjectionTypes {
+                err: TypeError::Mismatch,
+            })
+        }
+        ty::PredicateKind::Subtype(pred) => {
+            let (a, b) = infcx.enter_forall_and_leak_universe(
+                obligation.predicate.kind().rebind((pred.a, pred.b)),
+            );
+            let expected_found = ExpectedFound::new(true, a, b);
+            FulfillmentErrorCode::SubtypeError(expected_found, TypeError::Sorts(expected_found))
+        }
+        ty::PredicateKind::Coerce(pred) => {
+            let (a, b) = infcx.enter_forall_and_leak_universe(
+                obligation.predicate.kind().rebind((pred.a, pred.b)),
+            );
+            let expected_found = ExpectedFound::new(false, a, b);
+            FulfillmentErrorCode::SubtypeError(expected_found, TypeError::Sorts(expected_found))
+        }
+        ty::PredicateKind::Clause(_)
+        | ty::PredicateKind::ObjectSafe(_)
+        | ty::PredicateKind::Ambiguous => {
+            FulfillmentErrorCode::SelectionError(SelectionError::Unimplemented)
+        }
+        ty::PredicateKind::ConstEquate(..) => {
+            bug!("unexpected goal: {obligation:?}")
+        }
+    };
+    FulfillmentError { root_obligation: obligation.clone(), code, obligation }
+}
+
+fn fulfillment_error_for_stalled<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    obligation: PredicateObligation<'tcx>,
+) -> FulfillmentError<'tcx> {
+    let code = infcx.probe(|_| {
+        match infcx.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::Never).0 {
+            Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
+                FulfillmentErrorCode::Ambiguity { overflow: None }
+            }
+            Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => {
+                FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }
+            }
+            Ok((_, Certainty::Yes)) => {
+                bug!("did not expect successful goal when collecting ambiguity errors")
+            }
+            Err(_) => {
+                bug!("did not expect selection error when collecting ambiguity errors")
+            }
+        }
+    });
+
+    FulfillmentError { obligation: obligation.clone(), code, root_obligation: obligation }
+}
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 51094b781c0..0bf28f520a4 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -42,6 +42,17 @@ pub use fulfill::FulfillmentCtxt;
 pub(crate) use normalize::deeply_normalize_for_diagnostics;
 pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes};
 
+/// How many fixpoint iterations we should attempt inside of the solver before bailing
+/// with overflow.
+///
+/// We previously used  `tcx.recursion_limit().0.checked_ilog2().unwrap_or(0)` for this.
+/// However, it feels unlikely that uncreasing the recursion limit by a power of two
+/// to get one more itereation is every useful or desirable. We now instead used a constant
+/// here. If there ever ends up some use-cases where a bigger number of fixpoint iterations
+/// is required, we can add a new attribute for that or revert this to be dependant on the
+/// recursion limit again. However, this feels very unlikely.
+const FIXPOINT_STEP_LIMIT: usize = 8;
+
 #[derive(Debug, Clone, Copy)]
 enum SolverMode {
     /// Ordinary trait solving, using everywhere except for coherence.
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs
index bede94a2e43..07a8aca85a0 100644
--- a/compiler/rustc_trait_selection/src/solve/search_graph.rs
+++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs
@@ -1,3 +1,5 @@
+use crate::solve::FIXPOINT_STEP_LIMIT;
+
 use super::inspect;
 use super::inspect::ProofTreeBuilder;
 use super::SolverMode;
@@ -99,7 +101,6 @@ impl<'tcx> ProvisionalCacheEntry<'tcx> {
 
 pub(super) struct SearchGraph<'tcx> {
     mode: SolverMode,
-    local_overflow_limit: usize,
     /// The stack of goals currently being computed.
     ///
     /// An element is *deeper* in the stack if its index is *lower*.
@@ -116,10 +117,9 @@ pub(super) struct SearchGraph<'tcx> {
 }
 
 impl<'tcx> SearchGraph<'tcx> {
-    pub(super) fn new(tcx: TyCtxt<'tcx>, mode: SolverMode) -> SearchGraph<'tcx> {
+    pub(super) fn new(mode: SolverMode) -> SearchGraph<'tcx> {
         Self {
             mode,
-            local_overflow_limit: tcx.recursion_limit().0.checked_ilog2().unwrap_or(0) as usize,
             stack: Default::default(),
             provisional_cache: Default::default(),
             cycle_participants: Default::default(),
@@ -130,10 +130,6 @@ impl<'tcx> SearchGraph<'tcx> {
         self.mode
     }
 
-    pub(super) fn local_overflow_limit(&self) -> usize {
-        self.local_overflow_limit
-    }
-
     /// Update the stack and reached depths on cache hits.
     #[instrument(level = "debug", skip(self))]
     fn on_cache_hit(&mut self, additional_depth: usize, encountered_overflow: bool) {
@@ -277,7 +273,7 @@ impl<'tcx> SearchGraph<'tcx> {
             }
 
             inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow);
-            return Self::response_no_constraints(tcx, input, Certainty::OVERFLOW);
+            return Self::response_no_constraints(tcx, input, Certainty::overflow(true));
         };
 
         // Try to fetch the goal from the global cache.
@@ -370,7 +366,7 @@ impl<'tcx> SearchGraph<'tcx> {
             } else if is_coinductive_cycle {
                 Self::response_no_constraints(tcx, input, Certainty::Yes)
             } else {
-                Self::response_no_constraints(tcx, input, Certainty::OVERFLOW)
+                Self::response_no_constraints(tcx, input, Certainty::overflow(false))
             };
         } else {
             // No entry, we push this goal on the stack and try to prove it.
@@ -398,7 +394,7 @@ impl<'tcx> SearchGraph<'tcx> {
                 // of this we continuously recompute the cycle until the result
                 // of the previous iteration is equal to the final result, at which
                 // point we are done.
-                for _ in 0..self.local_overflow_limit() {
+                for _ in 0..FIXPOINT_STEP_LIMIT {
                     let result = prove_goal(self, inspect);
                     let stack_entry = self.pop_stack();
                     debug_assert_eq!(stack_entry.input, input);
@@ -431,7 +427,8 @@ impl<'tcx> SearchGraph<'tcx> {
                     } else if stack_entry.has_been_used == HasBeenUsed::COINDUCTIVE_CYCLE {
                         Self::response_no_constraints(tcx, input, Certainty::Yes) == result
                     } else if stack_entry.has_been_used == HasBeenUsed::INDUCTIVE_CYCLE {
-                        Self::response_no_constraints(tcx, input, Certainty::OVERFLOW) == result
+                        Self::response_no_constraints(tcx, input, Certainty::overflow(false))
+                            == result
                     } else {
                         false
                     };
@@ -452,7 +449,7 @@ impl<'tcx> SearchGraph<'tcx> {
                 debug!("canonical cycle overflow");
                 let current_entry = self.pop_stack();
                 debug_assert!(current_entry.has_been_used.is_empty());
-                let result = Self::response_no_constraints(tcx, input, Certainty::OVERFLOW);
+                let result = Self::response_no_constraints(tcx, input, Certainty::overflow(false));
                 (current_entry, result)
             });
 
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 6778cb7b7a9..68111c4cc1f 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -22,7 +22,7 @@ use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::{util, TraitEngine, TraitEngineExt};
+use rustc_infer::traits::{util, FulfillmentErrorCode, TraitEngine, TraitEngineExt};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_middle::traits::specialization_graph::OverlapMode;
@@ -35,6 +35,8 @@ use rustc_span::DUMMY_SP;
 use std::fmt::Debug;
 use std::ops::ControlFlow;
 
+use super::error_reporting::suggest_new_overflow_limit;
+
 /// Whether we do the orphan check relative to this crate or
 /// to some remote crate.
 #[derive(Copy, Clone, Debug)]
@@ -56,6 +58,9 @@ pub struct OverlapResult<'tcx> {
     /// `true` if the overlap might've been permitted before the shift
     /// to universes.
     pub involves_placeholder: bool,
+
+    /// Used in the new solver to suggest increasing the recursion limit.
+    pub overflowing_predicates: Vec<ty::Predicate<'tcx>>,
 }
 
 pub fn add_placeholder_note<G: EmissionGuarantee>(err: &mut Diag<'_, G>) {
@@ -65,6 +70,18 @@ pub fn add_placeholder_note<G: EmissionGuarantee>(err: &mut Diag<'_, G>) {
     );
 }
 
+pub fn suggest_increasing_recursion_limit<'tcx, G: EmissionGuarantee>(
+    tcx: TyCtxt<'tcx>,
+    err: &mut Diag<'_, G>,
+    overflowing_predicates: &[ty::Predicate<'tcx>],
+) {
+    for pred in overflowing_predicates {
+        err.note(format!("overflow evaluating the requirement `{}`", pred));
+    }
+
+    suggest_new_overflow_limit(tcx, err);
+}
+
 #[derive(Debug, Clone, Copy)]
 enum TrackAmbiguityCauses {
     Yes,
@@ -221,11 +238,13 @@ fn overlap<'tcx>(
         ),
     );
 
+    let mut overflowing_predicates = Vec::new();
     if overlap_mode.use_implicit_negative() {
-        if let Some(_failing_obligation) =
-            impl_intersection_has_impossible_obligation(selcx, &obligations)
-        {
-            return None;
+        match impl_intersection_has_impossible_obligation(selcx, &obligations) {
+            IntersectionHasImpossibleObligations::Yes => return None,
+            IntersectionHasImpossibleObligations::No { overflowing_predicates: p } => {
+                overflowing_predicates = p
+            }
         }
     }
 
@@ -261,7 +280,12 @@ fn overlap<'tcx>(
         impl_header = deeply_normalize_for_diagnostics(&infcx, param_env, impl_header);
     }
 
-    Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
+    Some(OverlapResult {
+        impl_header,
+        intercrate_ambiguity_causes,
+        involves_placeholder,
+        overflowing_predicates,
+    })
 }
 
 #[instrument(level = "debug", skip(infcx), ret)]
@@ -287,6 +311,19 @@ fn equate_impl_headers<'tcx>(
     result.map(|infer_ok| infer_ok.obligations).ok()
 }
 
+/// The result of [fn impl_intersection_has_impossible_obligation].
+enum IntersectionHasImpossibleObligations<'tcx> {
+    Yes,
+    No {
+        /// With `-Znext-solver=coherence`, some obligations may
+        /// fail if only the user increased the recursion limit.
+        ///
+        /// We return those obligations here and mention them in the
+        /// error message.
+        overflowing_predicates: Vec<ty::Predicate<'tcx>>,
+    },
+}
+
 /// Check if both impls can be satisfied by a common type by considering whether
 /// any of either impl's obligations is not known to hold.
 ///
@@ -308,7 +345,7 @@ fn equate_impl_headers<'tcx>(
 fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     obligations: &'a [PredicateObligation<'tcx>],
-) -> Option<PredicateObligation<'tcx>> {
+) -> IntersectionHasImpossibleObligations<'tcx> {
     let infcx = selcx.infcx;
 
     if infcx.next_trait_solver() {
@@ -317,28 +354,42 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
 
         // We only care about the obligations that are *definitely* true errors.
         // Ambiguities do not prove the disjointness of two impls.
-        let mut errors = fulfill_cx.select_where_possible(infcx);
-        errors.pop().map(|err| err.obligation)
+        let errors = fulfill_cx.select_where_possible(infcx);
+        if errors.is_empty() {
+            let overflow_errors = fulfill_cx.collect_remaining_errors(infcx);
+            let overflowing_predicates = overflow_errors
+                .into_iter()
+                .filter(|e| match e.code {
+                    FulfillmentErrorCode::Ambiguity { overflow: Some(true) } => true,
+                    _ => false,
+                })
+                .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
+                .collect();
+            IntersectionHasImpossibleObligations::No { overflowing_predicates }
+        } else {
+            IntersectionHasImpossibleObligations::Yes
+        }
     } else {
-        obligations
-            .iter()
-            .find(|obligation| {
-                // We use `evaluate_root_obligation` to correctly track intercrate
-                // ambiguity clauses. We cannot use this in the new solver.
-                let evaluation_result = selcx.evaluate_root_obligation(obligation);
-
-                match evaluation_result {
-                    Ok(result) => !result.may_apply(),
-                    // If overflow occurs, we need to conservatively treat the goal as possibly holding,
-                    // since there can be instantiations of this goal that don't overflow and result in
-                    // success. This isn't much of a problem in the old solver, since we treat overflow
-                    // fatally (this still can be encountered: <https://github.com/rust-lang/rust/issues/105231>),
-                    // but in the new solver, this is very important for correctness, since overflow
-                    // *must* be treated as ambiguity for completeness.
-                    Err(_overflow) => false,
+        for obligation in obligations {
+            // We use `evaluate_root_obligation` to correctly track intercrate
+            // ambiguity clauses.
+            let evaluation_result = selcx.evaluate_root_obligation(obligation);
+
+            match evaluation_result {
+                Ok(result) => {
+                    if !result.may_apply() {
+                        return IntersectionHasImpossibleObligations::Yes;
+                    }
                 }
-            })
-            .cloned()
+                // If overflow occurs, we need to conservatively treat the goal as possibly holding,
+                // since there can be instantiations of this goal that don't overflow and result in
+                // success. While this isn't much of a problem in the old solver, since we treat overflow
+                // fatally, this still can be encountered: <https://github.com/rust-lang/rust/issues/105231>.
+                Err(_overflow) => {}
+            }
+        }
+
+        IntersectionHasImpossibleObligations::No { overflowing_predicates: Vec::new() }
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 7f7bd867f63..3aaed398f57 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -20,10 +20,9 @@ use crate::traits::{
     SelectionError, SignatureMismatch, TraitNotObjectSafe,
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
-use rustc_errors::{
-    codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, FatalError,
-    MultiSpan, StashKey, StringPart,
-};
+use rustc_errors::codes::*;
+use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart};
+use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -62,6 +61,22 @@ pub enum OverflowCause<'tcx> {
     TraitSolver(ty::Predicate<'tcx>),
 }
 
+pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>(
+    tcx: TyCtxt<'tcx>,
+    err: &mut Diag<'_, G>,
+) {
+    let suggested_limit = match tcx.recursion_limit() {
+        Limit(0) => Limit(2),
+        limit => limit * 2,
+    };
+    err.help(format!(
+        "consider increasing the recursion limit by adding a \
+         `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
+        suggested_limit,
+        tcx.crate_name(LOCAL_CRATE),
+    ));
+}
+
 #[extension(pub trait TypeErrCtxtExt<'tcx>)]
 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn report_fulfillment_errors(
@@ -263,7 +278,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         };
 
         if suggest_increasing_limit {
-            self.suggest_new_overflow_limit(&mut err);
+            suggest_new_overflow_limit(self.tcx, &mut err);
         }
 
         err
@@ -303,19 +318,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         );
     }
 
-    fn suggest_new_overflow_limit(&self, err: &mut Diag<'_>) {
-        let suggested_limit = match self.tcx.recursion_limit() {
-            Limit(0) => Limit(2),
-            limit => limit * 2,
-        };
-        err.help(format!(
-            "consider increasing the recursion limit by adding a \
-             `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
-            suggested_limit,
-            self.tcx.crate_name(LOCAL_CRATE),
-        ));
-    }
-
     /// Reports that a cycle was detected which led to overflow and halts
     /// compilation. This is equivalent to `report_overflow_obligation` except
     /// that we can give a more helpful error message (and, in particular,
@@ -335,12 +337,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         );
     }
 
-    fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed {
+    fn report_overflow_no_abort(
+        &self,
+        obligation: PredicateObligation<'tcx>,
+        suggest_increasing_limit: bool,
+    ) -> ErrorGuaranteed {
         let obligation = self.resolve_vars_if_possible(obligation);
         let mut err = self.build_overflow_error(
             OverflowCause::TraitSolver(obligation.predicate),
             obligation.cause.span,
-            true,
+            suggest_increasing_limit,
         );
         self.note_obligation_cause(&mut err, &obligation);
         self.point_at_returns_when_relevant(&mut err, &obligation);
@@ -1422,11 +1428,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             FulfillmentErrorCode::ProjectionError(ref e) => {
                 self.report_projection_error(&error.obligation, e)
             }
-            FulfillmentErrorCode::Ambiguity { overflow: false } => {
+            FulfillmentErrorCode::Ambiguity { overflow: None } => {
                 self.maybe_report_ambiguity(&error.obligation)
             }
-            FulfillmentErrorCode::Ambiguity { overflow: true } => {
-                self.report_overflow_no_abort(error.obligation.clone())
+            FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) } => {
+                self.report_overflow_no_abort(error.obligation.clone(), suggest_increasing_limit)
             }
             FulfillmentErrorCode::SubtypeError(ref expected_found, ref err) => self
                 .report_mismatched_types(
@@ -1910,6 +1916,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()),
                         },
                     );
+                    if cand.references_error() {
+                        return false;
+                    }
                     err.highlighted_help(vec![
                         StringPart::normal(format!("the trait `{}` ", cand.print_trait_sugared())),
                         StringPart::highlighted("is"),
@@ -1934,7 +1943,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
 
         let other = if other { "other " } else { "" };
-        let report = |candidates: Vec<TraitRef<'tcx>>, err: &mut Diag<'_>| {
+        let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diag<'_>| {
+            candidates.retain(|tr| !tr.references_error());
             if candidates.is_empty() {
                 return false;
             }
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index b91698af942..2fd64f474d5 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -138,7 +138,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         _infcx: &InferCtxt<'tcx>,
     ) -> Vec<FulfillmentError<'tcx>> {
         self.predicates
-            .to_errors(FulfillmentErrorCode::Ambiguity { overflow: false })
+            .to_errors(FulfillmentErrorCode::Ambiguity { overflow: None })
             .into_iter()
             .map(to_fulfillment_error)
             .collect()
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index b329739609c..f5bc6c3ad2c 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -39,6 +39,7 @@ pub struct OverlapError<'tcx> {
     pub self_ty: Option<Ty<'tcx>>,
     pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
     pub involves_placeholder: bool,
+    pub overflowing_predicates: Vec<ty::Predicate<'tcx>>,
 }
 
 /// Given the generic parameters for the requested impl, translate it to the generic parameters
@@ -435,6 +436,14 @@ fn report_conflicting_impls<'tcx>(
         if overlap.involves_placeholder {
             coherence::add_placeholder_note(err);
         }
+
+        if !overlap.overflowing_predicates.is_empty() {
+            coherence::suggest_increasing_recursion_limit(
+                tcx,
+                err,
+                &overlap.overflowing_predicates,
+            );
+        }
     }
 
     let msg = DelayDm(|| {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index f3b77d68922..95db9e2092f 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -103,6 +103,7 @@ impl<'tcx> Children {
                     self_ty: self_ty.has_concrete_skeleton().then_some(self_ty),
                     intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
                     involves_placeholder: overlap.involves_placeholder,
+                    overflowing_predicates: overlap.overflowing_predicates,
                 }
             };
 
diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs
index a15fd3e0999..7fda9ceb79a 100644
--- a/compiler/stable_mir/src/abi.rs
+++ b/compiler/stable_mir/src/abi.rs
@@ -1,7 +1,11 @@
 use crate::compiler_interface::with;
+use crate::error;
 use crate::mir::FieldIdx;
-use crate::ty::{Align, IndexedVal, Size, Ty, VariantIdx};
+use crate::target::{MachineInfo, MachineSize as Size};
+use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
+use crate::Error;
 use crate::Opaque;
+use std::fmt::{self, Debug};
 use std::num::NonZeroUsize;
 use std::ops::RangeInclusive;
 
@@ -100,7 +104,7 @@ impl LayoutShape {
 
     /// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1).
     pub fn is_1zst(&self) -> bool {
-        self.is_sized() && self.size == 0 && self.abi_align == 1
+        self.is_sized() && self.size.bits() == 0 && self.abi_align == 1
     }
 }
 
@@ -245,8 +249,175 @@ impl ValueAbi {
     }
 }
 
-/// We currently do not support `Scalar`, and use opaque instead.
-type Scalar = Opaque;
+/// Information about one scalar component of a Rust type.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+pub enum Scalar {
+    Initialized {
+        /// The primitive type used to represent this value.
+        value: Primitive,
+        /// The range that represents valid values.
+        /// The range must be valid for the `primitive` size.
+        valid_range: WrappingRange,
+    },
+    Union {
+        /// Unions never have niches, so there is no `valid_range`.
+        /// Even for unions, we need to use the correct registers for the kind of
+        /// values inside the union, so we keep the `Primitive` type around.
+        /// It is also used to compute the size of the scalar.
+        value: Primitive,
+    },
+}
+
+impl Scalar {
+    pub fn has_niche(&self, target: &MachineInfo) -> bool {
+        match self {
+            Scalar::Initialized { value, valid_range } => {
+                !valid_range.is_full(value.size(target)).unwrap()
+            }
+            Scalar::Union { .. } => false,
+        }
+    }
+}
+
+/// Fundamental unit of memory access and layout.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum Primitive {
+    /// The `bool` is the signedness of the `Integer` type.
+    ///
+    /// One would think we would not care about such details this low down,
+    /// but some ABIs are described in terms of C types and ISAs where the
+    /// integer arithmetic is done on {sign,zero}-extended registers, e.g.
+    /// a negative integer passed by zero-extension will appear positive in
+    /// the callee, and most operations on it will produce the wrong values.
+    Int {
+        length: IntegerLength,
+        signed: bool,
+    },
+    Float {
+        length: FloatLength,
+    },
+    Pointer(AddressSpace),
+}
+
+impl Primitive {
+    pub fn size(self, target: &MachineInfo) -> Size {
+        match self {
+            Primitive::Int { length, .. } => Size::from_bits(length.bits()),
+            Primitive::Float { length } => Size::from_bits(length.bits()),
+            Primitive::Pointer(_) => target.pointer_width,
+        }
+    }
+}
+
+/// Enum representing the existing integer lengths.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum IntegerLength {
+    I8,
+    I16,
+    I32,
+    I64,
+    I128,
+}
+
+/// Enum representing the existing float lengths.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum FloatLength {
+    F16,
+    F32,
+    F64,
+    F128,
+}
+
+impl IntegerLength {
+    pub fn bits(self) -> usize {
+        match self {
+            IntegerLength::I8 => 8,
+            IntegerLength::I16 => 16,
+            IntegerLength::I32 => 32,
+            IntegerLength::I64 => 64,
+            IntegerLength::I128 => 128,
+        }
+    }
+}
+
+impl FloatLength {
+    pub fn bits(self) -> usize {
+        match self {
+            FloatLength::F16 => 16,
+            FloatLength::F32 => 32,
+            FloatLength::F64 => 64,
+            FloatLength::F128 => 128,
+        }
+    }
+}
+
+/// An identifier that specifies the address space that some operation
+/// should operate on. Special address spaces have an effect on code generation,
+/// depending on the target and the address spaces it implements.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct AddressSpace(pub u32);
+
+impl AddressSpace {
+    /// The default address space, corresponding to data space.
+    pub const DATA: Self = AddressSpace(0);
+}
+
+/// Inclusive wrap-around range of valid values (bitwise representation), that is, if
+/// start > end, it represents `start..=MAX`, followed by `0..=end`.
+///
+/// That is, for an i8 primitive, a range of `254..=2` means following
+/// sequence:
+///
+///    254 (-2), 255 (-1), 0, 1, 2
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct WrappingRange {
+    pub start: u128,
+    pub end: u128,
+}
+
+impl WrappingRange {
+    /// Returns `true` if `size` completely fills the range.
+    #[inline]
+    pub fn is_full(&self, size: Size) -> Result<bool, Error> {
+        let Some(max_value) = size.unsigned_int_max() else {
+            return Err(error!("Expected size <= 128 bits, but found {} instead", size.bits()));
+        };
+        if self.start <= max_value && self.end <= max_value {
+            Ok(self.start == 0 && max_value == self.end)
+        } else {
+            Err(error!("Range `{self:?}` out of bounds for size `{}` bits.", size.bits()))
+        }
+    }
+
+    /// Returns `true` if `v` is contained in the range.
+    #[inline(always)]
+    pub fn contains(&self, v: u128) -> bool {
+        if self.wraps_around() {
+            self.start <= v || v <= self.end
+        } else {
+            self.start <= v && v <= self.end
+        }
+    }
+
+    /// Returns `true` if the range wraps around.
+    /// I.e., the range represents the union of `self.start..=MAX` and `0..=self.end`.
+    /// Returns `false` if this is a non-wrapping range, i.e.: `self.start..=self.end`.
+    #[inline]
+    pub fn wraps_around(&self) -> bool {
+        self.start > self.end
+    }
+}
+
+impl Debug for WrappingRange {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if self.start > self.end {
+            write!(fmt, "(..={}) | ({}..)", self.end, self.start)?;
+        } else {
+            write!(fmt, "{}..={}", self.start, self.end)?;
+        }
+        Ok(())
+    }
+}
 
 /// General language calling conventions.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/compiler/stable_mir/src/error.rs b/compiler/stable_mir/src/error.rs
index 9e3f4936944..050752e41eb 100644
--- a/compiler/stable_mir/src/error.rs
+++ b/compiler/stable_mir/src/error.rs
@@ -5,12 +5,14 @@
 //! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
 
 use std::fmt::{Debug, Display, Formatter};
-use std::{error, fmt, io};
+use std::{fmt, io};
 
 macro_rules! error {
      ($fmt: literal $(,)?) => { Error(format!($fmt)) };
      ($fmt: literal, $($arg:tt)*) => { Error(format!($fmt, $($arg)*)) };
- }
+}
+
+pub(crate) use error;
 
 /// An error type used to represent an error that has already been reported by the compiler.
 #[derive(Clone, Copy, PartialEq, Eq)]
@@ -72,8 +74,9 @@ where
     }
 }
 
-impl error::Error for Error {}
-impl<T> error::Error for CompilerError<T> where T: Display + Debug {}
+impl std::error::Error for Error {}
+
+impl<T> std::error::Error for CompilerError<T> where T: Display + Debug {}
 
 impl From<io::Error> for Error {
     fn from(value: io::Error) -> Self {
diff --git a/compiler/stable_mir/src/target.rs b/compiler/stable_mir/src/target.rs
index 41ec205cfc7..3a9011a2ffe 100644
--- a/compiler/stable_mir/src/target.rs
+++ b/compiler/stable_mir/src/target.rs
@@ -30,21 +30,29 @@ pub enum Endian {
 }
 
 /// Represent the size of a component.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 pub struct MachineSize {
     num_bits: usize,
 }
 
 impl MachineSize {
+    #[inline(always)]
     pub fn bytes(self) -> usize {
         self.num_bits / 8
     }
 
+    #[inline(always)]
     pub fn bits(self) -> usize {
         self.num_bits
     }
 
+    #[inline(always)]
     pub fn from_bits(num_bits: usize) -> MachineSize {
         MachineSize { num_bits }
     }
+
+    #[inline]
+    pub fn unsigned_int_max(self) -> Option<u128> {
+        (self.num_bits <= 128).then(|| u128::MAX >> (128 - self.bits()))
+    }
 }
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index ed4a4290246..86cc748eaec 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -324,7 +324,9 @@ impl TyKind {
 
     #[inline]
     pub fn is_cstr(&self) -> bool {
-        let TyKind::RigidTy(RigidTy::Adt(def, _)) = self else { return false };
+        let TyKind::RigidTy(RigidTy::Adt(def, _)) = self else {
+            return false;
+        };
         with(|cx| cx.adt_is_cstr(*def))
     }
 
@@ -1032,10 +1034,13 @@ pub struct BoundTy {
 }
 
 pub type Bytes = Vec<Option<u8>>;
+
+/// Size in bytes.
 pub type Size = usize;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
 pub struct Prov(pub AllocId);
+
 pub type Align = u64;
 pub type Promoted = u32;
 pub type InitMaskMaterialized = Vec<u64>;
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 1ad81fcfcfe..aaedbed0d55 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -2519,7 +2519,7 @@ impl<T> [T] {
         cmp::SliceContains::slice_contains(x, self)
     }
 
-    /// Returns `true` if `needle` is a prefix of the slice.
+    /// Returns `true` if `needle` is a prefix of the slice or equal to the slice.
     ///
     /// # Examples
     ///
@@ -2527,6 +2527,7 @@ impl<T> [T] {
     /// let v = [10, 40, 30];
     /// assert!(v.starts_with(&[10]));
     /// assert!(v.starts_with(&[10, 40]));
+    /// assert!(v.starts_with(&v));
     /// assert!(!v.starts_with(&[50]));
     /// assert!(!v.starts_with(&[10, 50]));
     /// ```
@@ -2549,7 +2550,7 @@ impl<T> [T] {
         self.len() >= n && needle == &self[..n]
     }
 
-    /// Returns `true` if `needle` is a suffix of the slice.
+    /// Returns `true` if `needle` is a suffix of the slice or equal to the slice.
     ///
     /// # Examples
     ///
@@ -2557,6 +2558,7 @@ impl<T> [T] {
     /// let v = [10, 40, 30];
     /// assert!(v.ends_with(&[30]));
     /// assert!(v.ends_with(&[40, 30]));
+    /// assert!(v.ends_with(&v));
     /// assert!(!v.ends_with(&[50]));
     /// assert!(!v.ends_with(&[50, 30]));
     /// ```
@@ -2582,7 +2584,8 @@ impl<T> [T] {
     /// Returns a subslice with the prefix removed.
     ///
     /// If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`.
-    /// If `prefix` is empty, simply returns the original slice.
+    /// If `prefix` is empty, simply returns the original slice. If `prefix` is equal to the
+    /// original slice, returns an empty slice.
     ///
     /// If the slice does not start with `prefix`, returns `None`.
     ///
@@ -2592,6 +2595,7 @@ impl<T> [T] {
     /// let v = &[10, 40, 30];
     /// assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
     /// assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+    /// assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
     /// assert_eq!(v.strip_prefix(&[50]), None);
     /// assert_eq!(v.strip_prefix(&[10, 50]), None);
     ///
@@ -2620,7 +2624,8 @@ impl<T> [T] {
     /// Returns a subslice with the suffix removed.
     ///
     /// If the slice ends with `suffix`, returns the subslice before the suffix, wrapped in `Some`.
-    /// If `suffix` is empty, simply returns the original slice.
+    /// If `suffix` is empty, simply returns the original slice. If `suffix` is equal to the
+    /// original slice, returns an empty slice.
     ///
     /// If the slice does not end with `suffix`, returns `None`.
     ///
@@ -2630,6 +2635,7 @@ impl<T> [T] {
     /// let v = &[10, 40, 30];
     /// assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
     /// assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+    /// assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
     /// assert_eq!(v.strip_suffix(&[50]), None);
     /// assert_eq!(v.strip_suffix(&[50, 30]), None);
     /// ```
diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs
index 8e7b72f8372..9d1c1ba305b 100644
--- a/library/profiler_builtins/build.rs
+++ b/library/profiler_builtins/build.rs
@@ -26,6 +26,7 @@ fn main() {
         "InstrProfilingMerge.c",
         "InstrProfilingMergeFile.c",
         "InstrProfilingNameVar.c",
+        "InstrProfilingPlatformAIX.c",
         "InstrProfilingPlatformDarwin.c",
         "InstrProfilingPlatformFuchsia.c",
         "InstrProfilingPlatformLinux.c",
diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed
index 68c5a5c5ca4..c85f384fd6e 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.fixed
+++ b/src/tools/clippy/tests/ui/derivable_impls.fixed
@@ -19,12 +19,10 @@ struct FooDefault<'a> {
 }
 
 
-
 #[derive(Default)]
 struct TupleDefault(bool, i32, u64);
 
 
-
 struct FooND1 {
     a: bool,
 }
@@ -73,7 +71,6 @@ impl Default for FooNDVec {
 struct StrDefault<'a>(&'a str);
 
 
-
 #[derive(Default)]
 struct AlreadyDerived(i32, bool);
 
@@ -96,7 +93,6 @@ mac!(0);
 #[derive(Default)]
 struct Y(u32);
 
-
 struct RustIssue26925<T> {
     a: Option<T>,
 }
@@ -132,12 +128,10 @@ struct WithoutSelfCurly {
 }
 
 
-
 #[derive(Default)]
 struct WithoutSelfParan(bool);
 
 
-
 // https://github.com/rust-lang/rust-clippy/issues/7655
 
 pub struct SpecializedImpl2<T> {
@@ -184,7 +178,6 @@ pub struct RepeatDefault1 {
 }
 
 
-
 pub struct RepeatDefault2 {
     a: [i8; 33],
 }
@@ -216,7 +209,6 @@ pub enum SimpleEnum {
 }
 
 
-
 pub enum NonExhaustiveEnum {
     Foo,
     #[non_exhaustive]
diff --git a/src/tools/clippy/tests/ui/empty_drop.fixed b/src/tools/clippy/tests/ui/empty_drop.fixed
index 949d0d8b399..17cfdcdc9c6 100644
--- a/src/tools/clippy/tests/ui/empty_drop.fixed
+++ b/src/tools/clippy/tests/ui/empty_drop.fixed
@@ -5,7 +5,6 @@
 struct Foo;
 
 
-
 // shouldn't cause an error
 struct Bar;
 
@@ -19,5 +18,4 @@ impl Drop for Bar {
 struct Baz;
 
 
-
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/must_use_unit.fixed b/src/tools/clippy/tests/ui/must_use_unit.fixed
index 75f91e66824..f255cb66652 100644
--- a/src/tools/clippy/tests/ui/must_use_unit.fixed
+++ b/src/tools/clippy/tests/ui/must_use_unit.fixed
@@ -6,13 +6,10 @@
 extern crate proc_macros;
 use proc_macros::external;
 
-
 pub fn must_use_default() {}
 
-
 pub fn must_use_unit() -> () {}
 
-
 pub fn must_use_with_note() {}
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.fixed b/src/tools/clippy/tests/ui/single_component_path_imports.fixed
index fdff336c281..3e81bcd5e48 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports.fixed
+++ b/src/tools/clippy/tests/ui/single_component_path_imports.fixed
@@ -4,7 +4,6 @@
 use core;
 
 
-
 use serde as edres;
 
 pub use serde;
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 193be94796e..ea1a967538b 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -3797,9 +3797,9 @@
 "ui/rust-2018/uniform-paths/issue-56596-2.rs",
 "ui/rust-2018/uniform-paths/issue-56596.rs",
 "ui/rust-2018/uniform-paths/issue-87932.rs",
-"ui/sanitize/issue-111184-coroutine-witness.rs",
-"ui/sanitize/issue-114275-cfi-const-expr-in-arry-len.rs",
-"ui/sanitize/issue-72154-lifetime-markers.rs",
+"ui/sanitizer/issue-111184-cfi-coroutine-witness.rs",
+"ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs",
+"ui/sanitizer/issue-72154-address-lifetime-markers.rs",
 "ui/self/issue-61882-2.rs",
 "ui/self/issue-61882.rs",
 "ui/simd/intrinsic/issue-85855.rs",
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 307f7105dd2..619fda339a6 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -42,15 +42,11 @@
       }
   
       bb2: {
--         switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3];
+-         switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb4];
 +         switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17];
       }
   
       bb3: {
--         falseEdge -> [real: bb20, imaginary: bb4];
--     }
-- 
--     bb4: {
           StorageLive(_15);
           _15 = (_2.1: bool);
           StorageLive(_16);
@@ -59,8 +55,12 @@
 +         goto -> bb16;
       }
   
+      bb4: {
+-         falseEdge -> [real: bb20, imaginary: bb3];
+-     }
+- 
 -     bb5: {
--         falseEdge -> [real: bb13, imaginary: bb3];
+-         falseEdge -> [real: bb13, imaginary: bb4];
 -     }
 - 
 -     bb6: {
@@ -68,7 +68,6 @@
 -     }
 - 
 -     bb7: {
-+     bb4: {
           _0 = const 1_i32;
 -         drop(_7) -> [return: bb18, unwind: bb25];
 +         drop(_7) -> [return: bb15, unwind: bb22];
@@ -184,7 +183,7 @@
           StorageDead(_12);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb2, imaginary: bb3];
+-         falseEdge -> [real: bb2, imaginary: bb4];
 +         goto -> bb2;
       }
   
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 307f7105dd2..619fda339a6 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -42,15 +42,11 @@
       }
   
       bb2: {
--         switchInt((_2.0: bool)) -> [0: bb4, otherwise: bb3];
+-         switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb4];
 +         switchInt((_2.0: bool)) -> [0: bb3, otherwise: bb17];
       }
   
       bb3: {
--         falseEdge -> [real: bb20, imaginary: bb4];
--     }
-- 
--     bb4: {
           StorageLive(_15);
           _15 = (_2.1: bool);
           StorageLive(_16);
@@ -59,8 +55,12 @@
 +         goto -> bb16;
       }
   
+      bb4: {
+-         falseEdge -> [real: bb20, imaginary: bb3];
+-     }
+- 
 -     bb5: {
--         falseEdge -> [real: bb13, imaginary: bb3];
+-         falseEdge -> [real: bb13, imaginary: bb4];
 -     }
 - 
 -     bb6: {
@@ -68,7 +68,6 @@
 -     }
 - 
 -     bb7: {
-+     bb4: {
           _0 = const 1_i32;
 -         drop(_7) -> [return: bb18, unwind: bb25];
 +         drop(_7) -> [return: bb15, unwind: bb22];
@@ -184,7 +183,7 @@
           StorageDead(_12);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb2, imaginary: bb3];
+-         falseEdge -> [real: bb2, imaginary: bb4];
 +         goto -> bb2;
       }
   
diff --git a/tests/rustdoc-ui/doc-include-suggestion.rs b/tests/rustdoc-ui/doc-include-suggestion.rs
index 5c8d1efa76f..aff0a24ace8 100644
--- a/tests/rustdoc-ui/doc-include-suggestion.rs
+++ b/tests/rustdoc-ui/doc-include-suggestion.rs
@@ -1,10 +1,6 @@
-//@ check-pass
-
 #[doc(include = "external-cross-doc.md")]
-//~^ WARNING unknown `doc` attribute `include`
+//~^ ERROR unknown `doc` attribute `include`
 //~| HELP use `doc = include_str!` instead
 // FIXME(#85497): make this a deny instead so it's more clear what's happening
 //~| NOTE on by default
-//~| WARNING previously accepted
-//~| NOTE see issue #82730
 pub struct NeedMoreDocs;
diff --git a/tests/rustdoc-ui/doc-include-suggestion.stderr b/tests/rustdoc-ui/doc-include-suggestion.stderr
index fcc93d0532a..1b4b78a8f26 100644
--- a/tests/rustdoc-ui/doc-include-suggestion.stderr
+++ b/tests/rustdoc-ui/doc-include-suggestion.stderr
@@ -1,12 +1,10 @@
-warning: unknown `doc` attribute `include`
-  --> $DIR/doc-include-suggestion.rs:3:7
+error: unknown `doc` attribute `include`
+  --> $DIR/doc-include-suggestion.rs:1:7
    |
 LL | #[doc(include = "external-cross-doc.md")]
    | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-   = note: `#[warn(invalid_doc_attributes)]` on by default
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
-warning: 1 warning emitted
+error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.rs b/tests/rustdoc-ui/doctest/doc-test-attr.rs
index 46178ad865a..8570252c449 100644
--- a/tests/rustdoc-ui/doctest/doc-test-attr.rs
+++ b/tests/rustdoc-ui/doctest/doc-test-attr.rs
@@ -1,14 +1,10 @@
 #![crate_type = "lib"]
-#![deny(invalid_doc_attributes)]
 
 #![doc(test)]
 //~^ ERROR `#[doc(test(...)]` takes a list of attributes
-//~^^ WARN this was previously accepted by the compiler
 #![doc(test = "hello")]
 //~^ ERROR `#[doc(test(...)]` takes a list of attributes
-//~^^ WARN this was previously accepted by the compiler
 #![doc(test(a))]
 //~^ ERROR unknown `doc(test)` attribute `a`
-//~^^ WARN this was previously accepted by the compiler
 
 pub fn foo() {}
diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.stderr b/tests/rustdoc-ui/doctest/doc-test-attr.stderr
index 5e6014954a4..415251cc5e9 100644
--- a/tests/rustdoc-ui/doctest/doc-test-attr.stderr
+++ b/tests/rustdoc-ui/doctest/doc-test-attr.stderr
@@ -1,34 +1,22 @@
 error: `#[doc(test(...)]` takes a list of attributes
-  --> $DIR/doc-test-attr.rs:4:8
+  --> $DIR/doc-test-attr.rs:3:8
    |
 LL | #![doc(test)]
    |        ^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-note: the lint level is defined here
-  --> $DIR/doc-test-attr.rs:2:9
-   |
-LL | #![deny(invalid_doc_attributes)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error: `#[doc(test(...)]` takes a list of attributes
-  --> $DIR/doc-test-attr.rs:7:8
+  --> $DIR/doc-test-attr.rs:5:8
    |
 LL | #![doc(test = "hello")]
    |        ^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc(test)` attribute `a`
-  --> $DIR/doc-test-attr.rs:10:13
+  --> $DIR/doc-test-attr.rs:7:13
    |
 LL | #![doc(test(a))]
    |             ^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/rustdoc-ui/lints/doc-attr.rs b/tests/rustdoc-ui/lints/doc-attr.rs
index 980d1c0e207..666aeb55cbe 100644
--- a/tests/rustdoc-ui/lints/doc-attr.rs
+++ b/tests/rustdoc-ui/lints/doc-attr.rs
@@ -1,25 +1,17 @@
 #![crate_type = "lib"]
-#![deny(warnings)]
 #![doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~^^ WARN
 
 #[doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~^^ WARN
 pub fn foo() {}
 
 #[doc(123)]
 //~^ ERROR invalid `doc` attribute
-//~| WARN
 #[doc("hello", "bar")]
 //~^ ERROR invalid `doc` attribute
-//~| WARN
 //~| ERROR invalid `doc` attribute
-//~| WARN
 #[doc(foo::bar, crate::bar::baz = "bye")]
 //~^ ERROR unknown `doc` attribute
-//~| WARN
 //~| ERROR unknown `doc` attribute
-//~| WARN
 fn bar() {}
diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr
index 68df2771fd7..091ffc20d46 100644
--- a/tests/rustdoc-ui/lints/doc-attr.stderr
+++ b/tests/rustdoc-ui/lints/doc-attr.stderr
@@ -1,71 +1,46 @@
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:7:7
+  --> $DIR/doc-attr.rs:5:7
    |
 LL | #[doc(as_ptr)]
    |       ^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-note: the lint level is defined here
-  --> $DIR/doc-attr.rs:2:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error: invalid `doc` attribute
-  --> $DIR/doc-attr.rs:12:7
+  --> $DIR/doc-attr.rs:9:7
    |
 LL | #[doc(123)]
    |       ^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: invalid `doc` attribute
-  --> $DIR/doc-attr.rs:15:7
+  --> $DIR/doc-attr.rs:11:7
    |
 LL | #[doc("hello", "bar")]
    |       ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: invalid `doc` attribute
-  --> $DIR/doc-attr.rs:15:16
+  --> $DIR/doc-attr.rs:11:16
    |
 LL | #[doc("hello", "bar")]
    |                ^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `foo::bar`
-  --> $DIR/doc-attr.rs:20:7
+  --> $DIR/doc-attr.rs:14:7
    |
 LL | #[doc(foo::bar, crate::bar::baz = "bye")]
    |       ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `crate::bar::baz`
-  --> $DIR/doc-attr.rs:20:17
+  --> $DIR/doc-attr.rs:14:17
    |
 LL | #[doc(foo::bar, crate::bar::baz = "bye")]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:3:8
+  --> $DIR/doc-attr.rs:2:8
    |
 LL | #![doc(as_ptr)]
    |        ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.fixed b/tests/rustdoc-ui/lints/doc-spotlight.fixed
index 6de95a33589..0f8f11a9430 100644
--- a/tests/rustdoc-ui/lints/doc-spotlight.fixed
+++ b/tests/rustdoc-ui/lints/doc-spotlight.fixed
@@ -1,8 +1,6 @@
 //@ run-rustfix
-#![deny(warnings)]
 #![feature(doc_notable_trait)]
 
 #[doc(notable_trait)]
 //~^ ERROR unknown `doc` attribute `spotlight`
-//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 trait MyTrait {}
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.rs b/tests/rustdoc-ui/lints/doc-spotlight.rs
index 9823ea90522..c1f90dd442b 100644
--- a/tests/rustdoc-ui/lints/doc-spotlight.rs
+++ b/tests/rustdoc-ui/lints/doc-spotlight.rs
@@ -1,8 +1,6 @@
 //@ run-rustfix
-#![deny(warnings)]
 #![feature(doc_notable_trait)]
 
 #[doc(spotlight)]
 //~^ ERROR unknown `doc` attribute `spotlight`
-//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 trait MyTrait {}
diff --git a/tests/rustdoc-ui/lints/doc-spotlight.stderr b/tests/rustdoc-ui/lints/doc-spotlight.stderr
index 5d93b4132fc..9682a3c0c8b 100644
--- a/tests/rustdoc-ui/lints/doc-spotlight.stderr
+++ b/tests/rustdoc-ui/lints/doc-spotlight.stderr
@@ -1,19 +1,12 @@
 error: unknown `doc` attribute `spotlight`
-  --> $DIR/doc-spotlight.rs:5:7
+  --> $DIR/doc-spotlight.rs:4:7
    |
 LL | #[doc(spotlight)]
    |       ^^^^^^^^^ help: use `notable_trait` instead
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: `doc(spotlight)` was renamed to `doc(notable_trait)`
    = note: `doc(spotlight)` is now a no-op
-note: the lint level is defined here
-  --> $DIR/doc-spotlight.rs:2:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
index 5d8791748a0..9a8bce2a92a 100644
--- a/tests/rustdoc-ui/lints/doc_cfg_hide.rs
+++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs
@@ -1,11 +1,7 @@
 #![feature(doc_cfg_hide)]
-#![deny(warnings)]
 
 #![doc(cfg_hide = "test")] //~ ERROR
-//~^ WARN
 #![doc(cfg_hide)] //~ ERROR
-//~^ WARN
 
 #[doc(cfg_hide(doc))] //~ ERROR
-//~^ WARN
 pub fn foo() {}
diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
index ca6a14a42b8..0c9d0879b0a 100644
--- a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
+++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr
@@ -1,40 +1,27 @@
 error: this attribute can only be applied at the crate level
-  --> $DIR/doc_cfg_hide.rs:9:7
+  --> $DIR/doc_cfg_hide.rs:6:7
    |
 LL | #[doc(cfg_hide(doc))]
    |       ^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
-note: the lint level is defined here
-  --> $DIR/doc_cfg_hide.rs:2:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 help: to apply to the crate, use an inner attribute
    |
 LL | #![doc(cfg_hide(doc))]
    |  +
 
 error: `#[doc(cfg_hide(...))]` takes a list of attributes
-  --> $DIR/doc_cfg_hide.rs:4:8
+  --> $DIR/doc_cfg_hide.rs:3:8
    |
 LL | #![doc(cfg_hide = "test")]
    |        ^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: `#[doc(cfg_hide(...))]` takes a list of attributes
-  --> $DIR/doc_cfg_hide.rs:6:8
+  --> $DIR/doc_cfg_hide.rs:4:8
    |
 LL | #![doc(cfg_hide)]
    |        ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs
index 16b12cca5a0..e1cc08ca242 100644
--- a/tests/rustdoc-ui/lints/invalid-doc-attr.rs
+++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs
@@ -1,32 +1,25 @@
 #![crate_type = "lib"]
-#![deny(warnings)]
 #![feature(doc_masked)]
 
 #![doc(masked)]
 //~^ ERROR this attribute can only be applied to an `extern crate` item
-//~| WARN is being phased out
 
 #[doc(test(no_crate_inject))]
 //~^ ERROR can only be applied at the crate level
-//~| WARN is being phased out
 //~| HELP to apply to the crate, use an inner attribute
 //~| SUGGESTION !
 #[doc(inline)]
 //~^ ERROR can only be applied to a `use` item
-//~| WARN is being phased out
 pub fn foo() {}
 
 pub mod bar {
     #![doc(test(no_crate_inject))]
     //~^ ERROR can only be applied at the crate level
-    //~| WARN is being phased out
 
     #[doc(test(no_crate_inject))]
     //~^ ERROR can only be applied at the crate level
-    //~| WARN is being phased out
     #[doc(inline)]
     //~^ ERROR can only be applied to a `use` item
-    //~| WARN is being phased out
     pub fn baz() {}
 }
 
@@ -38,10 +31,8 @@ pub use bar::baz;
 
 #[doc(masked)]
 //~^ ERROR this attribute can only be applied to an `extern crate` item
-//~| WARN is being phased out
 pub struct Masked;
 
 #[doc(masked)]
 //~^ ERROR this attribute cannot be applied to an `extern crate self` item
-//~| WARN is being phased out
 pub extern crate self as reexport;
diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr
index 82ea33e1d89..7621999a8ca 100644
--- a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr
+++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr
@@ -1,48 +1,37 @@
 error: this attribute can only be applied at the crate level
-  --> $DIR/invalid-doc-attr.rs:9:7
+  --> $DIR/invalid-doc-attr.rs:7:7
    |
 LL | #[doc(test(no_crate_inject))]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
-note: the lint level is defined here
-  --> $DIR/invalid-doc-attr.rs:2:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 help: to apply to the crate, use an inner attribute
    |
 LL | #![doc(test(no_crate_inject))]
    |  +
 
 error: this attribute can only be applied to a `use` item
-  --> $DIR/invalid-doc-attr.rs:14:7
+  --> $DIR/invalid-doc-attr.rs:11:7
    |
 LL | #[doc(inline)]
    |       ^^^^^^ only applicable on `use` items
-...
+LL |
 LL | pub fn foo() {}
    | ------------ not a `use` item
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
 
 error: this attribute can only be applied at the crate level
-  --> $DIR/invalid-doc-attr.rs:20:12
+  --> $DIR/invalid-doc-attr.rs:16:12
    |
 LL |     #![doc(test(no_crate_inject))]
    |            ^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 
 error: conflicting doc inlining attributes
-  --> $DIR/invalid-doc-attr.rs:33:7
+  --> $DIR/invalid-doc-attr.rs:26:7
    |
 LL | #[doc(inline)]
    |       ^^^^^^ this attribute...
@@ -52,61 +41,50 @@ LL | #[doc(no_inline)]
    = help: remove one of the conflicting attributes
 
 error: this attribute can only be applied to an `extern crate` item
-  --> $DIR/invalid-doc-attr.rs:39:7
+  --> $DIR/invalid-doc-attr.rs:32:7
    |
 LL | #[doc(masked)]
    |       ^^^^^^ only applicable on `extern crate` items
-...
+LL |
 LL | pub struct Masked;
    | ----------------- not an `extern crate` item
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information
 
 error: this attribute cannot be applied to an `extern crate self` item
-  --> $DIR/invalid-doc-attr.rs:44:7
+  --> $DIR/invalid-doc-attr.rs:36:7
    |
 LL | #[doc(masked)]
    |       ^^^^^^ not applicable on `extern crate self` items
-...
+LL |
 LL | pub extern crate self as reexport;
    | --------------------------------- `extern crate self` defined here
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: this attribute can only be applied to an `extern crate` item
-  --> $DIR/invalid-doc-attr.rs:5:8
+  --> $DIR/invalid-doc-attr.rs:4:8
    |
 LL | #![doc(masked)]
    |        ^^^^^^ only applicable on `extern crate` items
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information
 
 error: this attribute can only be applied at the crate level
-  --> $DIR/invalid-doc-attr.rs:24:11
+  --> $DIR/invalid-doc-attr.rs:19:11
    |
 LL |     #[doc(test(no_crate_inject))]
    |           ^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 
 error: this attribute can only be applied to a `use` item
-  --> $DIR/invalid-doc-attr.rs:27:11
+  --> $DIR/invalid-doc-attr.rs:21:11
    |
 LL |     #[doc(inline)]
    |           ^^^^^^ only applicable on `use` items
-...
+LL |
 LL |     pub fn baz() {}
    |     ------------ not a `use` item
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
 
 error: aborting due to 9 previous errors
diff --git a/tests/ui-fulldeps/stable-mir/check_abi.rs b/tests/ui-fulldeps/stable-mir/check_abi.rs
index c345987955e..74801e007c4 100644
--- a/tests/ui-fulldeps/stable-mir/check_abi.rs
+++ b/tests/ui-fulldeps/stable-mir/check_abi.rs
@@ -19,8 +19,12 @@ extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_smir::rustc_internal;
-use stable_mir::abi::{ArgAbi, CallConvention, FieldsShape, PassMode, VariantsShape};
+use stable_mir::abi::{
+    ArgAbi, CallConvention, FieldsShape, IntegerLength, PassMode, Primitive, Scalar, ValueAbi,
+    VariantsShape,
+};
 use stable_mir::mir::mono::Instance;
+use stable_mir::target::MachineInfo;
 use stable_mir::{CrateDef, CrateItem, CrateItems, ItemKind};
 use std::assert_matches::assert_matches;
 use std::convert::TryFrom;
@@ -39,11 +43,12 @@ fn test_stable_mir() -> ControlFlow<()> {
     let instance = Instance::try_from(target_fn).unwrap();
     let fn_abi = instance.fn_abi().unwrap();
     assert_eq!(fn_abi.conv, CallConvention::Rust);
-    assert_eq!(fn_abi.args.len(), 2);
+    assert_eq!(fn_abi.args.len(), 3);
 
     check_ignore(&fn_abi.args[0]);
     check_primitive(&fn_abi.args[1]);
-    check_result(fn_abi.ret);
+    check_niche(&fn_abi.args[2]);
+    check_result(&fn_abi.ret);
 
     // Test variadic function.
     let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap();
@@ -85,7 +90,7 @@ fn check_primitive(abi: &ArgAbi) {
 }
 
 /// Check the return value: `Result<usize, &str>`.
-fn check_result(abi: ArgAbi) {
+fn check_result(abi: &ArgAbi) {
     assert!(abi.ty.kind().is_enum());
     assert_matches!(abi.mode, PassMode::Indirect { .. });
     let layout = abi.layout.shape();
@@ -94,6 +99,25 @@ fn check_result(abi: ArgAbi) {
     assert_matches!(layout.variants, VariantsShape::Multiple { .. })
 }
 
+/// Check the niche information about: `NonZeroU8`
+fn check_niche(abi: &ArgAbi) {
+    assert!(abi.ty.kind().is_struct());
+    assert_matches!(abi.mode, PassMode::Direct { .. });
+    let layout = abi.layout.shape();
+    assert!(layout.is_sized());
+    assert_eq!(layout.size.bytes(), 1);
+
+    let ValueAbi::Scalar(scalar) = layout.abi else { unreachable!() };
+    assert!(scalar.has_niche(&MachineInfo::target()), "Opps: {:?}", scalar);
+
+    let Scalar::Initialized { value, valid_range } = scalar else { unreachable!() };
+    assert_matches!(value, Primitive::Int { length: IntegerLength::I8, signed: false });
+    assert_eq!(valid_range.start, 1);
+    assert_eq!(valid_range.end, u8::MAX.into());
+    assert!(!valid_range.contains(0));
+    assert!(!valid_range.wraps_around());
+}
+
 fn get_item<'a>(
     items: &'a CrateItems,
     item: (ItemKind, &str),
@@ -126,11 +150,16 @@ fn generate_input(path: &str) -> std::io::Result<()> {
         #![feature(c_variadic)]
         #![allow(unused_variables)]
 
-        pub fn fn_abi(ignore: [u8; 0], primitive: char) -> Result<usize, &'static str> {{
-            // We only care about the signature.
-            todo!()
-        }}
+        use std::num::NonZeroU8;
 
+        pub fn fn_abi(
+            ignore: [u8; 0],
+            primitive: char,
+            niche: NonZeroU8,
+        ) -> Result<usize, &'static str> {{
+                // We only care about the signature.
+                todo!()
+        }}
 
         pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
             0
diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr
index 50ce69b3381..bde3675b48c 100644
--- a/tests/ui/associated-consts/issue-105330.stderr
+++ b/tests/ui/associated-consts/issue-105330.stderr
@@ -55,7 +55,6 @@ error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
 LL |     foo::<Demo>()();
    |           ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
    |
-   = help: the trait `TraitWAssocConst` is implemented for `{type error}`
 note: required by a bound in `foo`
   --> $DIR/issue-105330.rs:11:11
    |
@@ -92,7 +91,6 @@ error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
 LL |     foo::<Demo>();
    |           ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
    |
-   = help: the trait `TraitWAssocConst` is implemented for `{type error}`
 note: required by a bound in `foo`
   --> $DIR/issue-105330.rs:11:11
    |
diff --git a/tests/ui/associated-types/impl-wf-cycle-6.fixed b/tests/ui/associated-types/impl-wf-cycle-6.fixed
index 45143be1e74..ce98b9c2f02 100644
--- a/tests/ui/associated-types/impl-wf-cycle-6.fixed
+++ b/tests/ui/associated-types/impl-wf-cycle-6.fixed
@@ -21,7 +21,6 @@ impl Grault for () {
 
 impl<T: Grault> Grault for (T,)
 //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
-
 {
     type A = ();
     type B = bool;
diff --git a/tests/ui/attributes/doc-attr.rs b/tests/ui/attributes/doc-attr.rs
index 980d1c0e207..666aeb55cbe 100644
--- a/tests/ui/attributes/doc-attr.rs
+++ b/tests/ui/attributes/doc-attr.rs
@@ -1,25 +1,17 @@
 #![crate_type = "lib"]
-#![deny(warnings)]
 #![doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~^^ WARN
 
 #[doc(as_ptr)]
 //~^ ERROR unknown `doc` attribute
-//~^^ WARN
 pub fn foo() {}
 
 #[doc(123)]
 //~^ ERROR invalid `doc` attribute
-//~| WARN
 #[doc("hello", "bar")]
 //~^ ERROR invalid `doc` attribute
-//~| WARN
 //~| ERROR invalid `doc` attribute
-//~| WARN
 #[doc(foo::bar, crate::bar::baz = "bye")]
 //~^ ERROR unknown `doc` attribute
-//~| WARN
 //~| ERROR unknown `doc` attribute
-//~| WARN
 fn bar() {}
diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr
index 68df2771fd7..091ffc20d46 100644
--- a/tests/ui/attributes/doc-attr.stderr
+++ b/tests/ui/attributes/doc-attr.stderr
@@ -1,71 +1,46 @@
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:7:7
+  --> $DIR/doc-attr.rs:5:7
    |
 LL | #[doc(as_ptr)]
    |       ^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-note: the lint level is defined here
-  --> $DIR/doc-attr.rs:2:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error: invalid `doc` attribute
-  --> $DIR/doc-attr.rs:12:7
+  --> $DIR/doc-attr.rs:9:7
    |
 LL | #[doc(123)]
    |       ^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: invalid `doc` attribute
-  --> $DIR/doc-attr.rs:15:7
+  --> $DIR/doc-attr.rs:11:7
    |
 LL | #[doc("hello", "bar")]
    |       ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: invalid `doc` attribute
-  --> $DIR/doc-attr.rs:15:16
+  --> $DIR/doc-attr.rs:11:16
    |
 LL | #[doc("hello", "bar")]
    |                ^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `foo::bar`
-  --> $DIR/doc-attr.rs:20:7
+  --> $DIR/doc-attr.rs:14:7
    |
 LL | #[doc(foo::bar, crate::bar::baz = "bye")]
    |       ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `crate::bar::baz`
-  --> $DIR/doc-attr.rs:20:17
+  --> $DIR/doc-attr.rs:14:17
    |
 LL | #[doc(foo::bar, crate::bar::baz = "bye")]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:3:8
+  --> $DIR/doc-attr.rs:2:8
    |
 LL | #![doc(as_ptr)]
    |        ^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/attributes/doc-test-literal.rs b/tests/ui/attributes/doc-test-literal.rs
index a06a1afcb3f..92fe7846f14 100644
--- a/tests/ui/attributes/doc-test-literal.rs
+++ b/tests/ui/attributes/doc-test-literal.rs
@@ -1,7 +1,4 @@
-#![deny(warnings)]
-
 #![doc(test(""))]
 //~^ ERROR `#![doc(test(...)]` does not take a literal
-//~^^ WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 fn main() {}
diff --git a/tests/ui/attributes/doc-test-literal.stderr b/tests/ui/attributes/doc-test-literal.stderr
index ed2964825c7..39e109a76ce 100644
--- a/tests/ui/attributes/doc-test-literal.stderr
+++ b/tests/ui/attributes/doc-test-literal.stderr
@@ -1,17 +1,10 @@
 error: `#![doc(test(...)]` does not take a literal
-  --> $DIR/doc-test-literal.rs:3:13
+  --> $DIR/doc-test-literal.rs:1:13
    |
 LL | #![doc(test(""))]
    |             ^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-note: the lint level is defined here
-  --> $DIR/doc-test-literal.rs:1:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/future-incompatible-lint-group.rs b/tests/ui/future-incompatible-lint-group.rs
index bbd0e33d719..c84538318f7 100644
--- a/tests/ui/future-incompatible-lint-group.rs
+++ b/tests/ui/future-incompatible-lint-group.rs
@@ -11,8 +11,7 @@ trait Tr {
 pub mod submodule {
     // Error since this is a `future_incompatible` lint
     #![doc(test(some_test))]
-        //~^ ERROR this attribute can only be applied at the crate level
-        //~| WARN this was previously accepted by the compiler
+    //~^ ERROR this attribute can only be applied at the crate level
 }
 
 fn main() {}
diff --git a/tests/ui/future-incompatible-lint-group.stderr b/tests/ui/future-incompatible-lint-group.stderr
index 161fe82e373..4e6c434fa29 100644
--- a/tests/ui/future-incompatible-lint-group.stderr
+++ b/tests/ui/future-incompatible-lint-group.stderr
@@ -14,15 +14,8 @@ error: this attribute can only be applied at the crate level
 LL |     #![doc(test(some_test))]
    |            ^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
    = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
-note: the lint level is defined here
-  --> $DIR/future-incompatible-lint-group.rs:3:9
-   |
-LL | #![deny(future_incompatible)]
-   |         ^^^^^^^^^^^^^^^^^^^
-   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]`
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/generics/generic-no-mangle.fixed b/tests/ui/generics/generic-no-mangle.fixed
index f20ea0edaa6..69db712f9dc 100644
--- a/tests/ui/generics/generic-no-mangle.fixed
+++ b/tests/ui/generics/generic-no-mangle.fixed
@@ -2,10 +2,8 @@
 #![allow(dead_code)]
 #![deny(no_mangle_generic_items)]
 
-
 pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
 
-
 pub extern "C" fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
 
 #[no_mangle]
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr b/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr
index 6155579c9fa..9b0efe9abe6 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Bar well-form
 LL |     for<'a> &'a mut Self:;
    |             ^^^^^^^^^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95230`)
 note: required by a bound in `Bar`
   --> $DIR/issue-95230.rs:9:13
    |
diff --git a/tests/ui/imports/issue-52891.fixed b/tests/ui/imports/issue-52891.fixed
index 9faef1703ac..0382960db2f 100644
--- a/tests/ui/imports/issue-52891.fixed
+++ b/tests/ui/imports/issue-52891.fixed
@@ -27,10 +27,8 @@ use issue_52891::{l,
 use issue_52891::a::inner;
 use issue_52891::b::inner as other_inner; //~ ERROR `inner` is defined multiple times
 
-
 //~^ ERROR `issue_52891` is defined multiple times
 
-
 #[macro_use]
 use issue_52891::n; //~ ERROR `n` is defined multiple times
 
diff --git a/tests/ui/imports/unused-import-issue-87973.fixed b/tests/ui/imports/unused-import-issue-87973.fixed
index 96508fa3ea2..d1167d7d486 100644
--- a/tests/ui/imports/unused-import-issue-87973.fixed
+++ b/tests/ui/imports/unused-import-issue-87973.fixed
@@ -2,7 +2,6 @@
 #![deny(unused_imports)]
 
 // Check that attributes get removed too. See #87973.
-
 //~^ ERROR unused import
 
 fn main() {}
diff --git a/tests/ui/inference/stmts-as-exp-105431.rs b/tests/ui/inference/stmts-as-exp-105431.rs
new file mode 100644
index 00000000000..b5adb4a2b66
--- /dev/null
+++ b/tests/ui/inference/stmts-as-exp-105431.rs
@@ -0,0 +1,76 @@
+#![allow(unused)]
+
+fn test_if() -> i32 {
+    let x = if true {
+        eprintln!("hello");
+        3;
+    }
+    else {
+        4;
+    };
+    x //~ ERROR mismatched types
+}
+
+fn test_if_without_binding() -> i32 {
+    if true { //~ ERROR mismatched types
+        eprintln!("hello");
+        3;
+    }
+    else { //~ ERROR mismatched types
+        4;
+    }
+}
+
+fn test_match() -> i32 {
+    let v = 1;
+    let res = match v {
+        1 => { 1; }
+        _ => { 2; }
+    };
+    res //~ ERROR mismatched types
+}
+
+fn test_match_match_without_binding() -> i32 {
+    let v = 1;
+    match v {
+        1 => { 1; } //~ ERROR mismatched types
+        _ => { 2; } //~ ERROR mismatched types
+    }
+}
+
+fn test_match_arm_different_types() -> i32 {
+    let v = 1;
+    let res = match v {
+        1 => { if 1 < 2 { 1 } else { 2 } }
+        _ => { 2; } //~ ERROR `match` arms have incompatible types
+    };
+    res
+}
+
+fn test_if_match_mixed() -> i32 {
+    let x = if true {
+        3;
+    } else {
+        match 1 {
+            1 => { 1 }
+            _ => { 2 }
+        };
+    };
+    x //~ ERROR mismatched types
+}
+
+fn test_if_match_mixed_failed() -> i32 {
+    let x = if true {
+        3;
+    } else {
+        // because this is a tailed expr, so we won't check deeper
+        match 1 {
+            1 => { 33; }
+            _ => { 44; }
+        }
+    };
+    x //~ ERROR mismatched types
+}
+
+
+fn main() {}
diff --git a/tests/ui/inference/stmts-as-exp-105431.stderr b/tests/ui/inference/stmts-as-exp-105431.stderr
new file mode 100644
index 00000000000..f3da04b39a3
--- /dev/null
+++ b/tests/ui/inference/stmts-as-exp-105431.stderr
@@ -0,0 +1,129 @@
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:11:5
+   |
+LL | fn test_if() -> i32 {
+   |                 --- expected `i32` because of return type
+...
+LL |     x
+   |     ^ expected `i32`, found `()`
+   |
+help: remove this semicolon to return this value
+   |
+LL -         3;
+LL +         3
+   |
+help: remove this semicolon to return this value
+   |
+LL -         4;
+LL +         4
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:15:13
+   |
+LL |       if true {
+   |  _____________^
+LL | |         eprintln!("hello");
+LL | |         3;
+   | |          - help: remove this semicolon to return this value
+LL | |     }
+   | |_____^ expected `i32`, found `()`
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:19:10
+   |
+LL |       else {
+   |  __________^
+LL | |         4;
+   | |          - help: remove this semicolon to return this value
+LL | |     }
+   | |_____^ expected `i32`, found `()`
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:30:5
+   |
+LL | fn test_match() -> i32 {
+   |                    --- expected `i32` because of return type
+...
+LL |     res
+   |     ^^^ expected `i32`, found `()`
+   |
+help: remove this semicolon to return this value
+   |
+LL -         1 => { 1; }
+LL +         1 => { 1 }
+   |
+help: remove this semicolon to return this value
+   |
+LL -         _ => { 2; }
+LL +         _ => { 2 }
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:36:14
+   |
+LL |         1 => { 1; }
+   |              ^^^-^^
+   |              |  |
+   |              |  help: remove this semicolon to return this value
+   |              expected `i32`, found `()`
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:37:14
+   |
+LL |         _ => { 2; }
+   |              ^^^-^^
+   |              |  |
+   |              |  help: remove this semicolon to return this value
+   |              expected `i32`, found `()`
+
+error[E0308]: `match` arms have incompatible types
+  --> $DIR/stmts-as-exp-105431.rs:45:16
+   |
+LL |       let res = match v {
+   |  _______________-
+LL | |         1 => { if 1 < 2 { 1 } else { 2 } }
+   | |                ------------------------- this is found to be of type `{integer}`
+LL | |         _ => { 2; }
+   | |                ^-
+   | |                ||
+   | |                |help: consider removing this semicolon
+   | |                expected integer, found `()`
+LL | |     };
+   | |_____- `match` arms have incompatible types
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:59:5
+   |
+LL | fn test_if_match_mixed() -> i32 {
+   |                             --- expected `i32` because of return type
+...
+LL |     x
+   |     ^ expected `i32`, found `()`
+   |
+help: remove this semicolon to return this value
+   |
+LL -         3;
+LL +         3
+   |
+help: remove this semicolon to return this value
+   |
+LL -         };
+LL +         }
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/stmts-as-exp-105431.rs:72:5
+   |
+LL | fn test_if_match_mixed_failed() -> i32 {
+   |                                    --- expected `i32` because of return type
+LL |     let x = if true {
+LL |         3;
+   |          - help: remove this semicolon to return this value
+...
+LL |     x
+   |     ^ expected `i32`, found `()`
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
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 85e8061f173..80377bf6c20 100644
--- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
+++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
@@ -3,8 +3,6 @@ error[E0275]: overflow evaluating the requirement `Loop == _`
    |
 LL | impl Loop {}
    |      ^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
 
 error[E0392]: type parameter `T` is never used
   --> $DIR/inherent-impls-overflow.rs:13:12
diff --git a/tests/ui/lazy-type-alias/leading-where-clause.fixed b/tests/ui/lazy-type-alias/leading-where-clause.fixed
index ca0ab7b5c7d..003eaa6c54e 100644
--- a/tests/ui/lazy-type-alias/leading-where-clause.fixed
+++ b/tests/ui/lazy-type-alias/leading-where-clause.fixed
@@ -7,11 +7,9 @@
 // Check that we *reject* leading where-clauses on lazy type aliases.
 
 pub type Leading0<T>
-
 = T where String: From<T>;
 
 pub type Leading1<T, U>
-
 = (T, U)
 where
     U: Copy, String: From<T>;
diff --git a/tests/ui/lint/suggestions.fixed b/tests/ui/lint/suggestions.fixed
index b017438a8bd..66d097b121f 100644
--- a/tests/ui/lint/suggestions.fixed
+++ b/tests/ui/lint/suggestions.fixed
@@ -7,7 +7,6 @@
 //~^ ERROR const items should never be `#[no_mangle]`
 //~| HELP try a static value
 
-
 //~^ HELP remove this attribute
 pub fn defiant<T>(_t: T) {}
 //~^ WARN functions generic over types or consts must be mangled
diff --git a/tests/ui/lint/unused/import_remove_line.fixed b/tests/ui/lint/unused/import_remove_line.fixed
new file mode 100644
index 00000000000..45876cd4ebc
--- /dev/null
+++ b/tests/ui/lint/unused/import_remove_line.fixed
@@ -0,0 +1,11 @@
+//@ run-rustfix
+//@ check-pass
+
+#![crate_type = "lib"]
+#![warn(unused_imports)]
+
+//~^ WARN unused imports
+//~^ WARN unused import
+
+//~^ WARN unused import
+//~| WARN unused import
diff --git a/tests/ui/lint/unused/import_remove_line.rs b/tests/ui/lint/unused/import_remove_line.rs
new file mode 100644
index 00000000000..fd45f04eb80
--- /dev/null
+++ b/tests/ui/lint/unused/import_remove_line.rs
@@ -0,0 +1,13 @@
+//@ run-rustfix
+//@ check-pass
+
+#![crate_type = "lib"]
+#![warn(unused_imports)]
+
+use std::time::{Duration, Instant};
+//~^ WARN unused imports
+use std::time::SystemTime;
+//~^ WARN unused import
+use std::time::SystemTimeError;use std::time::TryFromFloatSecsError;
+//~^ WARN unused import
+//~| WARN unused import
diff --git a/tests/ui/lint/unused/import_remove_line.stderr b/tests/ui/lint/unused/import_remove_line.stderr
new file mode 100644
index 00000000000..0e8c5de3558
--- /dev/null
+++ b/tests/ui/lint/unused/import_remove_line.stderr
@@ -0,0 +1,32 @@
+warning: unused imports: `Duration`, `Instant`
+  --> $DIR/import_remove_line.rs:7:17
+   |
+LL | use std::time::{Duration, Instant};
+   |                 ^^^^^^^^  ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/import_remove_line.rs:5:9
+   |
+LL | #![warn(unused_imports)]
+   |         ^^^^^^^^^^^^^^
+
+warning: unused import: `std::time::SystemTime`
+  --> $DIR/import_remove_line.rs:9:5
+   |
+LL | use std::time::SystemTime;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused import: `std::time::SystemTimeError`
+  --> $DIR/import_remove_line.rs:11:5
+   |
+LL | use std::time::SystemTimeError;use std::time::TryFromFloatSecsError;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused import: `std::time::TryFromFloatSecsError`
+  --> $DIR/import_remove_line.rs:11:36
+   |
+LL | use std::time::SystemTimeError;use std::time::TryFromFloatSecsError;
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs
index 785ffb1e0f4..77f2a68537b 100644
--- a/tests/ui/repr/invalid_repr_list_help.rs
+++ b/tests/ui/repr/invalid_repr_list_help.rs
@@ -17,6 +17,5 @@ pub enum OwO4 {
 }
 
 #[repr(uwu)] //~ERROR: unrecognized representation hint
-#[doc(owo)]  //~WARN: unknown `doc` attribute
-             //~^ WARN: this was previously
+#[doc(owo)]  //~ERROR: unknown `doc` attribute
 pub struct Owo5;
diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr
index 7ffe1287eb3..e87cbd37a99 100644
--- a/tests/ui/repr/invalid_repr_list_help.stderr
+++ b/tests/ui/repr/invalid_repr_list_help.stderr
@@ -30,15 +30,13 @@ LL | #[repr(uwu, u8)]
    |
    = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
-warning: unknown `doc` attribute `owo`
+error: unknown `doc` attribute `owo`
   --> $DIR/invalid_repr_list_help.rs:20:7
    |
 LL | #[doc(owo)]
    |       ^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-   = note: `#[warn(invalid_doc_attributes)]` on by default
+   = note: `#[deny(invalid_doc_attributes)]` on by default
 
 error[E0552]: unrecognized representation hint
   --> $DIR/invalid_repr_list_help.rs:19:8
@@ -48,6 +46,6 @@ LL | #[repr(uwu)]
    |
    = help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
 
-error: aborting due to 5 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0552`.
diff --git a/tests/ui/resolve/resolve-conflict-import-vs-import.fixed b/tests/ui/resolve/resolve-conflict-import-vs-import.fixed
index 2ebf2a194b8..d981d629c46 100644
--- a/tests/ui/resolve/resolve-conflict-import-vs-import.fixed
+++ b/tests/ui/resolve/resolve-conflict-import-vs-import.fixed
@@ -2,7 +2,6 @@
 
 #[allow(unused_imports)]
 use std::mem::transmute;
-
 //~^ ERROR the name `transmute` is defined multiple times
 
 fn main() {
diff --git a/tests/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed b/tests/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
index fcab56ac819..ca8422c03a3 100644
--- a/tests/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
+++ b/tests/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
@@ -9,7 +9,6 @@
 #![deny(rust_2018_idioms)]
 #![allow(dead_code)]
 
-
 //~^ ERROR unused extern crate
 
 // Shouldn't suggest changing to `use`, as `bar`
diff --git a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
index 2625cdc8b48..75b3918be1d 100644
--- a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
+++ b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
@@ -8,7 +8,6 @@
 
 // The suggestion span should include the attribute.
 
-
 //~^ ERROR unused extern crate
 
 fn main() {}
diff --git a/tests/ui/rustdoc/deny-invalid-doc-attrs.rs b/tests/ui/rustdoc/deny-invalid-doc-attrs.rs
index 02e9c67915f..15bfd723424 100644
--- a/tests/ui/rustdoc/deny-invalid-doc-attrs.rs
+++ b/tests/ui/rustdoc/deny-invalid-doc-attrs.rs
@@ -2,6 +2,4 @@
 //~^ NOTE defined here
 #![doc(x)]
 //~^ ERROR unknown `doc` attribute `x`
-//~| WARNING will become a hard error
-//~| NOTE see issue #82730
 fn main() {}
diff --git a/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr b/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr
index bf104f48be0..0884e9c8bb2 100644
--- a/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr
+++ b/tests/ui/rustdoc/deny-invalid-doc-attrs.stderr
@@ -4,8 +4,6 @@ error: unknown `doc` attribute `x`
 LL | #![doc(x)]
    |        ^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/deny-invalid-doc-attrs.rs:1:9
    |
diff --git a/tests/ui/rustdoc/doc-primitive.rs b/tests/ui/rustdoc/doc-primitive.rs
index 4336961e3b5..fbb1e1bc1fa 100644
--- a/tests/ui/rustdoc/doc-primitive.rs
+++ b/tests/ui/rustdoc/doc-primitive.rs
@@ -2,7 +2,6 @@
 
 #[doc(primitive = "foo")]
 //~^ ERROR unknown `doc` attribute `primitive`
-//~| WARN
 mod bar {}
 
 fn main() {}
diff --git a/tests/ui/rustdoc/doc-primitive.stderr b/tests/ui/rustdoc/doc-primitive.stderr
index 5f535206d26..8f6f330b3e5 100644
--- a/tests/ui/rustdoc/doc-primitive.stderr
+++ b/tests/ui/rustdoc/doc-primitive.stderr
@@ -4,8 +4,6 @@ error: unknown `doc` attribute `primitive`
 LL | #[doc(primitive = "foo")]
    |       ^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/doc-primitive.rs:1:9
    |
diff --git a/tests/ui/rustdoc/doc-test-attr.rs b/tests/ui/rustdoc/doc-test-attr.rs
index 46178ad865a..fb3db6a80fa 100644
--- a/tests/ui/rustdoc/doc-test-attr.rs
+++ b/tests/ui/rustdoc/doc-test-attr.rs
@@ -3,12 +3,9 @@
 
 #![doc(test)]
 //~^ ERROR `#[doc(test(...)]` takes a list of attributes
-//~^^ WARN this was previously accepted by the compiler
 #![doc(test = "hello")]
 //~^ ERROR `#[doc(test(...)]` takes a list of attributes
-//~^^ WARN this was previously accepted by the compiler
 #![doc(test(a))]
 //~^ ERROR unknown `doc(test)` attribute `a`
-//~^^ WARN this was previously accepted by the compiler
 
 pub fn foo() {}
diff --git a/tests/ui/rustdoc/doc-test-attr.stderr b/tests/ui/rustdoc/doc-test-attr.stderr
index 5e6014954a4..51672314a43 100644
--- a/tests/ui/rustdoc/doc-test-attr.stderr
+++ b/tests/ui/rustdoc/doc-test-attr.stderr
@@ -4,8 +4,6 @@ error: `#[doc(test(...)]` takes a list of attributes
 LL | #![doc(test)]
    |        ^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/doc-test-attr.rs:2:9
    |
@@ -13,22 +11,16 @@ LL | #![deny(invalid_doc_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[doc(test(...)]` takes a list of attributes
-  --> $DIR/doc-test-attr.rs:7:8
+  --> $DIR/doc-test-attr.rs:6:8
    |
 LL | #![doc(test = "hello")]
    |        ^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: unknown `doc(test)` attribute `a`
-  --> $DIR/doc-test-attr.rs:10:13
+  --> $DIR/doc-test-attr.rs:8:13
    |
 LL | #![doc(test(a))]
    |             ^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/sanitize/address.rs b/tests/ui/sanitizer/address.rs
index 7a5e767687c..7a5e767687c 100644
--- a/tests/ui/sanitize/address.rs
+++ b/tests/ui/sanitizer/address.rs
diff --git a/tests/ui/sanitize/badfree.rs b/tests/ui/sanitizer/badfree.rs
index ecbb58eba00..ecbb58eba00 100644
--- a/tests/ui/sanitize/badfree.rs
+++ b/tests/ui/sanitizer/badfree.rs
diff --git a/tests/ui/sanitize/cfg-kasan.rs b/tests/ui/sanitizer/cfg-kasan.rs
index 394bf216581..394bf216581 100644
--- a/tests/ui/sanitize/cfg-kasan.rs
+++ b/tests/ui/sanitizer/cfg-kasan.rs
diff --git a/tests/ui/sanitize/cfg.rs b/tests/ui/sanitizer/cfg.rs
index 942141bd3fe..942141bd3fe 100644
--- a/tests/ui/sanitize/cfg.rs
+++ b/tests/ui/sanitizer/cfg.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.rs b/tests/ui/sanitizer/cfi-canonical-jump-tables-requires-cfi.rs
index 10c5bf6ea5e..10c5bf6ea5e 100644
--- a/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.rs
+++ b/tests/ui/sanitizer/cfi-canonical-jump-tables-requires-cfi.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.stderr b/tests/ui/sanitizer/cfi-canonical-jump-tables-requires-cfi.stderr
index de67d6a6b7f..de67d6a6b7f 100644
--- a/tests/ui/sanitize/sanitizer-cfi-canonical-jump-tables-require-cfi.stderr
+++ b/tests/ui/sanitizer/cfi-canonical-jump-tables-requires-cfi.stderr
diff --git a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-attr-cfg.rs b/tests/ui/sanitizer/cfi-generalize-pointers-attr-cfg.rs
index d46002c69fd..d46002c69fd 100644
--- a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-attr-cfg.rs
+++ b/tests/ui/sanitizer/cfi-generalize-pointers-attr-cfg.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.rs b/tests/ui/sanitizer/cfi-generalize-pointers-requires-cfi.rs
index 8ba13bd3639..8ba13bd3639 100644
--- a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.rs
+++ b/tests/ui/sanitizer/cfi-generalize-pointers-requires-cfi.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.stderr b/tests/ui/sanitizer/cfi-generalize-pointers-requires-cfi.stderr
index 621708de241..621708de241 100644
--- a/tests/ui/sanitize/sanitizer-cfi-generalize-pointers-require-cfi.stderr
+++ b/tests/ui/sanitizer/cfi-generalize-pointers-requires-cfi.stderr
diff --git a/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.rs b/tests/ui/sanitizer/cfi-invalid-attr-cfi-encoding.rs
index 7ef6bd2f0ac..7ef6bd2f0ac 100644
--- a/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.rs
+++ b/tests/ui/sanitizer/cfi-invalid-attr-cfi-encoding.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.stderr b/tests/ui/sanitizer/cfi-invalid-attr-cfi-encoding.stderr
index b9e9722da23..93ec134241e 100644
--- a/tests/ui/sanitize/sanitizer-cfi-invalid-attr-cfi-encoding.stderr
+++ b/tests/ui/sanitizer/cfi-invalid-attr-cfi-encoding.stderr
@@ -1,5 +1,5 @@
 error: malformed `cfi_encoding` attribute input
-  --> $DIR/sanitizer-cfi-invalid-attr-cfi-encoding.rs:10:1
+  --> $DIR/cfi-invalid-attr-cfi-encoding.rs:10:1
    |
 LL | #[cfi_encoding]
    | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.aarch64.stderr b/tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.aarch64.stderr
index 1006c3bc17e..1006c3bc17e 100644
--- a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.aarch64.stderr
+++ b/tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.aarch64.stderr
diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.rs b/tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.rs
index c628709d7a1..c628709d7a1 100644
--- a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.rs
+++ b/tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.x86_64.stderr b/tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.x86_64.stderr
index 1006c3bc17e..1006c3bc17e 100644
--- a/tests/ui/sanitize/sanitizer-cfi-is-incompatible-with-sanitizer-kcfi.x86_64.stderr
+++ b/tests/ui/sanitizer/cfi-is-incompatible-with-kcfi.x86_64.stderr
diff --git a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-attr-cfg.rs b/tests/ui/sanitizer/cfi-normalize-integers-attr-cfg.rs
index 24c2c2c13da..24c2c2c13da 100644
--- a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-attr-cfg.rs
+++ b/tests/ui/sanitizer/cfi-normalize-integers-attr-cfg.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.rs b/tests/ui/sanitizer/cfi-normalize-integers-requires-cfi.rs
index a7ecefbf7ef..a7ecefbf7ef 100644
--- a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.rs
+++ b/tests/ui/sanitizer/cfi-normalize-integers-requires-cfi.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.stderr b/tests/ui/sanitizer/cfi-normalize-integers-requires-cfi.stderr
index 748fb60dad9..748fb60dad9 100644
--- a/tests/ui/sanitize/sanitizer-cfi-normalize-integers-require-cfi.stderr
+++ b/tests/ui/sanitizer/cfi-normalize-integers-requires-cfi.stderr
diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs b/tests/ui/sanitizer/cfi-requires-lto.rs
index 5a34f696e05..5a34f696e05 100644
--- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
+++ b/tests/ui/sanitizer/cfi-requires-lto.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr b/tests/ui/sanitizer/cfi-requires-lto.stderr
index efc0c43138e..efc0c43138e 100644
--- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
+++ b/tests/ui/sanitizer/cfi-requires-lto.stderr
diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs b/tests/ui/sanitizer/cfi-with-rustc-lto-requires-single-codegen-unit.rs
index 954e4ec3b85..954e4ec3b85 100644
--- a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs
+++ b/tests/ui/sanitizer/cfi-with-rustc-lto-requires-single-codegen-unit.rs
diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr b/tests/ui/sanitizer/cfi-with-rustc-lto-requires-single-codegen-unit.stderr
index 8d6dc1d8f1e..8d6dc1d8f1e 100644
--- a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr
+++ b/tests/ui/sanitizer/cfi-with-rustc-lto-requires-single-codegen-unit.stderr
diff --git a/tests/ui/sanitize/crt-static.rs b/tests/ui/sanitizer/crt-static.rs
index c24faeca3dc..c24faeca3dc 100644
--- a/tests/ui/sanitize/crt-static.rs
+++ b/tests/ui/sanitizer/crt-static.rs
diff --git a/tests/ui/sanitize/crt-static.stderr b/tests/ui/sanitizer/crt-static.stderr
index 98b0ed82e80..98b0ed82e80 100644
--- a/tests/ui/sanitize/crt-static.stderr
+++ b/tests/ui/sanitizer/crt-static.stderr
diff --git a/tests/ui/sanitize/hwaddress.rs b/tests/ui/sanitizer/hwaddress.rs
index e5939eb734b..e5939eb734b 100644
--- a/tests/ui/sanitize/hwaddress.rs
+++ b/tests/ui/sanitizer/hwaddress.rs
diff --git a/tests/ui/sanitize/incompatible.rs b/tests/ui/sanitizer/incompatible.rs
index d000abb26ac..d000abb26ac 100644
--- a/tests/ui/sanitize/incompatible.rs
+++ b/tests/ui/sanitizer/incompatible.rs
diff --git a/tests/ui/sanitize/incompatible.stderr b/tests/ui/sanitizer/incompatible.stderr
index 4dff813ee1b..4dff813ee1b 100644
--- a/tests/ui/sanitize/incompatible.stderr
+++ b/tests/ui/sanitizer/incompatible.stderr
diff --git a/tests/ui/sanitize/inline-always.rs b/tests/ui/sanitizer/inline-always.rs
index d92daee3026..d92daee3026 100644
--- a/tests/ui/sanitize/inline-always.rs
+++ b/tests/ui/sanitizer/inline-always.rs
diff --git a/tests/ui/sanitize/inline-always.stderr b/tests/ui/sanitizer/inline-always.stderr
index 74fba3c0e0e..74fba3c0e0e 100644
--- a/tests/ui/sanitize/inline-always.stderr
+++ b/tests/ui/sanitizer/inline-always.stderr
diff --git a/tests/ui/sanitize/issue-111184-coroutine-witness.rs b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
index e5b1e032257..e5b1e032257 100644
--- a/tests/ui/sanitize/issue-111184-coroutine-witness.rs
+++ b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
diff --git a/tests/ui/sanitize/issue-114275-cfi-const-expr-in-arry-len.rs b/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
index b1b7487fa2a..b1b7487fa2a 100644
--- a/tests/ui/sanitize/issue-114275-cfi-const-expr-in-arry-len.rs
+++ b/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
diff --git a/tests/ui/sanitize/issue-72154-lifetime-markers.rs b/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
index aa0c19db9a1..aa0c19db9a1 100644
--- a/tests/ui/sanitize/issue-72154-lifetime-markers.rs
+++ b/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
diff --git a/tests/ui/sanitize/leak.rs b/tests/ui/sanitizer/leak.rs
index 65915ec24b7..65915ec24b7 100644
--- a/tests/ui/sanitize/leak.rs
+++ b/tests/ui/sanitizer/leak.rs
diff --git a/tests/ui/sanitize/memory-eager.rs b/tests/ui/sanitizer/memory-eager.rs
index 9e7889fa1bc..9e7889fa1bc 100644
--- a/tests/ui/sanitize/memory-eager.rs
+++ b/tests/ui/sanitizer/memory-eager.rs
diff --git a/tests/ui/sanitize/memory-passing.rs b/tests/ui/sanitizer/memory-passing.rs
index c8ab64bfaf8..c8ab64bfaf8 100644
--- a/tests/ui/sanitize/memory-passing.rs
+++ b/tests/ui/sanitizer/memory-passing.rs
diff --git a/tests/ui/sanitize/memory.rs b/tests/ui/sanitizer/memory.rs
index bd2d6771749..bd2d6771749 100644
--- a/tests/ui/sanitize/memory.rs
+++ b/tests/ui/sanitizer/memory.rs
diff --git a/tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
index b7dd4a43782..b7dd4a43782 100644
--- a/tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs
+++ b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
diff --git a/tests/ui/sanitize/split-lto-unit-requires-lto.rs b/tests/ui/sanitizer/split-lto-unit-requires-lto.rs
index 35e610f0307..35e610f0307 100644
--- a/tests/ui/sanitize/split-lto-unit-requires-lto.rs
+++ b/tests/ui/sanitizer/split-lto-unit-requires-lto.rs
diff --git a/tests/ui/sanitize/split-lto-unit-requires-lto.stderr b/tests/ui/sanitizer/split-lto-unit-requires-lto.stderr
index 0da06b7f8b1..0da06b7f8b1 100644
--- a/tests/ui/sanitize/split-lto-unit-requires-lto.stderr
+++ b/tests/ui/sanitizer/split-lto-unit-requires-lto.stderr
diff --git a/tests/ui/sanitize/thread.rs b/tests/ui/sanitizer/thread.rs
index 9d9ad6ee518..9d9ad6ee518 100644
--- a/tests/ui/sanitize/thread.rs
+++ b/tests/ui/sanitizer/thread.rs
diff --git a/tests/ui/sanitize/unsupported-target.rs b/tests/ui/sanitizer/unsupported-target.rs
index 7c7dc24b5d9..7c7dc24b5d9 100644
--- a/tests/ui/sanitize/unsupported-target.rs
+++ b/tests/ui/sanitizer/unsupported-target.rs
diff --git a/tests/ui/sanitize/unsupported-target.stderr b/tests/ui/sanitizer/unsupported-target.stderr
index bebbf3884ae..bebbf3884ae 100644
--- a/tests/ui/sanitize/unsupported-target.stderr
+++ b/tests/ui/sanitizer/unsupported-target.stderr
diff --git a/tests/ui/sanitize/use-after-scope.rs b/tests/ui/sanitizer/use-after-scope.rs
index 4d7f6f6c2f2..4d7f6f6c2f2 100644
--- a/tests/ui/sanitize/use-after-scope.rs
+++ b/tests/ui/sanitizer/use-after-scope.rs
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
index 2408e05728a..a5c2f215134 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `String: Copy`
 LL |     type Item = String where String: Copy;
    |                                      ^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 note: the requirement `String: Copy` appears on the `impl`'s associated type `Item` but not on the corresponding trait's associated type
   --> $DIR/alias-bound-unsound.rs:8:10
    |
@@ -18,32 +17,24 @@ error[E0275]: overflow evaluating the requirement `String <: <() as Foo>::Item`
    |
 LL |     drop(<() as Foo>::copy_me(&x));
    |                               ^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 
 error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
   --> $DIR/alias-bound-unsound.rs:24:10
    |
 LL |     drop(<() as Foo>::copy_me(&x));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 
 error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
   --> $DIR/alias-bound-unsound.rs:24:31
    |
 LL |     drop(<() as Foo>::copy_me(&x));
    |                               ^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 
 error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed`
   --> $DIR/alias-bound-unsound.rs:24:10
    |
 LL |     drop(<() as Foo>::copy_me(&x));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 
 error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
   --> $DIR/alias-bound-unsound.rs:24:10
@@ -51,7 +42,6 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
 LL |     drop(<() as Foo>::copy_me(&x));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 6 previous errors
diff --git a/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr
index 406c0ccca97..57cba790b55 100644
--- a/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence-fulfill-overflow.stderr
@@ -5,6 +5,9 @@ LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
    | ------------------------------------- first implementation here
 LL | impl<T: ?Sized + TwoW> Trait for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
+   |
+   = note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>: TwoW`
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
index fc145b81196..a04fa1ab8a1 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -6,6 +6,9 @@ LL | impl<T: Copy> Trait for T {}
 LL | struct LocalTy;
 LL | impl Trait for <LocalTy as Overflow>::Assoc {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+   |
+   = note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc`
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`)
 
 error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized`
   --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
index 150100f2c53..8d7d8cee08a 100644
--- a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
 LL |     impls::<W<_>>();
    |             ^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
 note: required by a bound in `impls`
   --> $DIR/fixpoint-exponential-growth.rs:30:13
    |
diff --git a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
index a3404da51f0..7cedb4d36c9 100644
--- a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
+++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): Trait`
 LL |     impls_trait::<()>();
    |                   ^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
 note: required by a bound in `impls_trait`
   --> $DIR/double-cycle-inductive-coinductive.rs:17:19
    |
@@ -17,7 +16,6 @@ error[E0275]: overflow evaluating the requirement `(): TraitRev`
 LL |     impls_trait_rev::<()>();
    |                       ^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
 note: required by a bound in `impls_trait_rev`
   --> $DIR/double-cycle-inductive-coinductive.rs:29:23
    |
diff --git a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
index 42451920744..a2a5c028cf8 100644
--- a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
 LL |     impls_trait::<W<_>>();
    |                   ^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_fixpoint_hang`)
 note: required by a bound in `impls_trait`
   --> $DIR/inductive-fixpoint-hang.rs:28:19
    |
diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
index 859b3f3f1c7..e9cc6bc6c81 100644
--- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): A`
 LL |     impls_a::<()>();
    |               ^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
 note: required by a bound in `impls_a`
   --> $DIR/inductive-not-on-stack.rs:25:15
    |
@@ -17,7 +16,6 @@ error[E0275]: overflow evaluating the requirement `(): AR`
 LL |     impls_ar::<()>();
    |                ^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
 note: required by a bound in `impls_ar`
   --> $DIR/inductive-not-on-stack.rs:38:16
    |
diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr
index e828bdeb16b..17544eb1da5 100644
--- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr
+++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): A`
 LL |     impls_a::<()>();
    |               ^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`mixed_cycles_1`)
 note: required by a bound in `impls_a`
   --> $DIR/mixed-cycles-1.rs:34:15
    |
diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr
index ec13093f707..a9be1016c74 100644
--- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr
+++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): A`
 LL |     impls_a::<()>();
    |               ^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`mixed_cycles_2`)
 note: required by a bound in `impls_a`
   --> $DIR/mixed-cycles-2.rs:27:15
    |
diff --git a/tests/ui/traits/next-solver/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize-param-env-2.stderr
index 86729eb8a4b..74a0a90885d 100644
--- a/tests/ui/traits/next-solver/normalize-param-env-2.stderr
+++ b/tests/ui/traits/next-solver/normalize-param-env-2.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
 LL |         Self::Assoc: A<T>,
    |                      ^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
 note: the requirement `<() as A<T>>::Assoc: A<T>` appears on the `impl`'s method `f` but not on the corresponding trait's method
   --> $DIR/normalize-param-env-2.rs:12:8
    |
@@ -19,24 +18,18 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
    |
 LL |         Self::Assoc: A<T>,
    |                      ^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
 
 error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
   --> $DIR/normalize-param-env-2.rs:24:22
    |
 LL |         Self::Assoc: A<T>,
    |                      ^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
 
 error[E0275]: overflow evaluating the requirement `(): A<T>`
   --> $DIR/normalize-param-env-2.rs:27:10
    |
 LL |         <() as A<T>>::f();
    |          ^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
 
 error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
   --> $DIR/normalize-param-env-2.rs:27:9
@@ -44,7 +37,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
 LL |         <() as A<T>>::f();
    |         ^^^^^^^^^^^^^^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
 note: required by a bound in `A::f`
   --> $DIR/normalize-param-env-2.rs:14:22
    |
diff --git a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
index 2a017fac104..1bee8ee88ff 100644
--- a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
+++ b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
@@ -3,16 +3,12 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
    |
 LL |     <T as Trait>::Assoc: Trait,
    |                          ^^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
 
 error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed`
   --> $DIR/normalize-param-env-4.rs:18:26
    |
 LL |     <T as Trait>::Assoc: Trait,
    |                          ^^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
 
 error[E0275]: overflow evaluating the requirement `T: Trait`
   --> $DIR/normalize-param-env-4.rs:31:19
@@ -20,7 +16,6 @@ error[E0275]: overflow evaluating the requirement `T: Trait`
 LL |     impls_trait::<T>();
    |                   ^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
 note: required by a bound in `impls_trait`
   --> $DIR/normalize-param-env-4.rs:14:19
    |
diff --git a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
index 90b54b1e789..b032ae3e740 100644
--- a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
+++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
@@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
 LL |     impls::<W<_>>();
    |             ^^^^
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`exponential_trait_goals`)
 note: required by a bound in `impls`
   --> $DIR/exponential-trait-goals.rs:14:13
    |
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
index fb668f83b01..1b80287d9da 100644
--- a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
@@ -1,12 +1,7 @@
-//~ ERROR overflow evaluating the requirement `Self well-formed`
-//~| ERROR overflow evaluating the requirement `Self: Trait`
-
 // This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
 //@ compile-flags: -Znext-solver --crate-type=lib
-//@ check-fail
+//@ check-pass
 
 #![recursion_limit = "0"]
 trait Trait {}
 impl Trait for u32 {}
-//~^ ERROR overflow evaluating the requirement `u32: Trait`
-//~| ERROR overflow evaluating the requirement `u32 well-formed`
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
deleted file mode 100644
index 16b25d90ace..00000000000
--- a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0275]: overflow evaluating the requirement `Self: Trait`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
-
-error[E0275]: overflow evaluating the requirement `Self well-formed`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
-
-error[E0275]: overflow evaluating the requirement `u32: Trait`
-  --> $DIR/recursion-limit-zero-issue-115351.rs:10:16
-   |
-LL | impl Trait for u32 {}
-   |                ^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
-
-error[E0275]: overflow evaluating the requirement `u32 well-formed`
-  --> $DIR/recursion-limit-zero-issue-115351.rs:10:16
-   |
-LL | impl Trait for u32 {}
-   |                ^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0275`.