about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock33
-rw-r--r--compiler/rustc_abi/src/layout.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs19
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs5
-rw-r--r--compiler/rustc_attr/src/builtin.rs6
-rw-r--r--compiler/rustc_borrowck/src/constraint_generation.rs248
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs4
-rw-r--r--compiler/rustc_borrowck/src/lib.rs28
-rw-r--r--compiler/rustc_borrowck/src/nll.rs193
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_invalidations.rs (renamed from compiler/rustc_borrowck/src/invalidation.rs)45
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_kills.rs147
-rw-r--r--compiler/rustc_borrowck/src/polonius/mod.rs188
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs12
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs62
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/mod.rs84
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs70
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/alloc_error_handler.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs21
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs50
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs4
-rw-r--r--compiler/rustc_const_eval/src/errors.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs8
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs6
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs6
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs10
-rw-r--r--compiler/rustc_errors/src/lib.rs116
-rw-r--r--compiler/rustc_expand/src/base.rs15
-rw-r--r--compiler/rustc_expand/src/expand.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs4
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs23
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs2
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs4
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/object_safety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs6
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs6
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs4
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs4
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs12
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs12
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_interface/src/queries.rs6
-rw-r--r--compiler/rustc_lint/src/context.rs4
-rw-r--r--compiler/rustc_lint/src/early.rs2
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp9
-rw-r--r--compiler/rustc_metadata/messages.ftl2
-rw-r--r--compiler/rustc_metadata/src/creader.rs22
-rw-r--r--compiler/rustc_metadata/src/fs.rs5
-rw-r--r--compiler/rustc_metadata/src/locator.rs4
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs12
-rw-r--r--compiler/rustc_middle/src/macros.rs10
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs2
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs6
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs17
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs12
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_middle/src/util/bug.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs4
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs6
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs4
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs3
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs7
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs19
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs18
-rw-r--r--compiler/rustc_parse/src/parser/item.rs17
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs8
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs4
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs29
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs2
-rw-r--r--compiler/rustc_query_system/src/query/job.rs2
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs4
-rw-r--r--compiler/rustc_resolve/messages.ftl4
-rw-r--r--compiler/rustc_resolve/src/ident.rs2
-rw-r--r--compiler/rustc_resolve/src/imports.rs20
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_resolve/src/macros.rs2
-rw-r--r--compiler/rustc_session/src/config.rs107
-rw-r--r--compiler/rustc_session/src/cstore.rs19
-rw-r--r--compiler/rustc_session/src/filesearch.rs6
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/options.rs8
-rw-r--r--compiler/rustc_session/src/output.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs2
-rw-r--r--compiler/rustc_session/src/session.rs76
-rw-r--r--compiler/rustc_session/src/utils.rs11
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs11
-rw-r--r--compiler/rustc_span/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs30
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs191
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs2
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs4
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs8
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs2
-rw-r--r--compiler/stable_mir/src/mir/body.rs82
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs15
-rw-r--r--compiler/stable_mir/src/mir/visit.rs5
-rw-r--r--library/std/src/fs/tests.rs2
-rw-r--r--src/bootstrap/src/core/builder.rs11
-rw-r--r--src/bootstrap/src/core/config/config.rs4
-rw-r--r--src/bootstrap/src/core/download.rs6
-rw-r--r--src/bootstrap/src/lib.rs4
-rw-r--r--src/bootstrap/src/utils/helpers.rs4
-rw-r--r--src/doc/unstable-book/src/language-features/link-arg-attribute.md21
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/render/mod.rs17
-rw-r--r--src/librustdoc/html/render/print_item.rs14
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css17
-rw-r--r--src/librustdoc/html/static/js/search.js31
-rw-r--r--src/librustdoc/html/templates/item_union.html4
-rw-r--r--src/librustdoc/html/templates/type_layout.html2
-rw-r--r--src/tools/clippy/src/driver.rs2
-rw-r--r--src/tools/clippy/tests/integration.rs8
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.stderr14
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr30
-rw-r--r--src/tools/compiletest/src/runtest.rs70
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/diagnostics.rs6
-rw-r--r--src/tools/miri/src/eval.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs2
-rw-r--r--tests/assembly/thin-lto.rs8
-rw-r--r--tests/codegen/thin-lto.rs7
-rw-r--r--tests/coverage/thin-lto.cov-map8
-rw-r--r--tests/coverage/thin-lto.coverage5
-rw-r--r--tests/coverage/thin-lto.rs4
-rw-r--r--tests/incremental/delayed_span_bug.rs4
-rw-r--r--tests/run-make/no-builtins-lto/Makefile18
-rw-r--r--tests/run-make/no-builtins-lto/filecheck.lto.txt17
-rw-r--r--tests/run-make/no-builtins-lto/foo.rs33
-rw-r--r--tests/run-make/no-builtins-lto/main.rs28
-rw-r--r--tests/run-make/no-builtins-lto/no_builtins.rs13
-rw-r--r--tests/run-make/pass-linker-flags-flavor/Makefile9
-rw-r--r--tests/run-make/pass-linker-flags-flavor/attribute.rs12
-rw-r--r--tests/run-make/pass-linker-flags-flavor/empty.rs (renamed from tests/run-make/pass-linker-flags-flavor/rs.rs)0
-rw-r--r--tests/run-make/pass-linker-flags-from-dep/Makefile6
-rw-r--r--tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs14
-rw-r--r--tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs (renamed from tests/run-make/pass-linker-flags-from-dep/rust_dep.rs)0
-rw-r--r--tests/run-make/pass-linker-flags/Makefile3
-rw-r--r--tests/run-make/pass-linker-flags/attribute.rs11
-rw-r--r--tests/run-make/pass-linker-flags/empty.rs (renamed from tests/run-make/pass-linker-flags/rs.rs)0
-rw-r--r--tests/run-make/valid-print-requests/valid-print-requests.stderr2
-rw-r--r--tests/run-make/wasm-builtins-import/Makefile (renamed from tests/run-make/wasm-spurious-import/Makefile)0
-rw-r--r--tests/run-make/wasm-builtins-import/main.rs (renamed from tests/run-make/wasm-spurious-import/main.rs)5
-rw-r--r--tests/run-make/wasm-builtins-import/verify.js (renamed from tests/run-make/wasm-spurious-import/verify.js)0
-rw-r--r--tests/rustdoc-gui/font-weight.goml2
-rw-r--r--tests/rustdoc-gui/headers-color.goml2
-rw-r--r--tests/rustdoc-gui/where-whitespace.goml8
-rw-r--r--tests/rustdoc-js-std/parser-errors.js45
-rw-r--r--tests/rustdoc-js-std/parser-paths.js48
-rw-r--r--tests/rustdoc-js-std/parser-separators.js22
-rw-r--r--tests/rustdoc-js-std/parser-weird-queries.js4
-rw-r--r--tests/rustdoc-ui/error-in-impl-trait/README.md2
-rw-r--r--tests/rustdoc-ui/unescaped_backticks.rs2
-rw-r--r--tests/rustdoc-ui/unescaped_backticks.stderr14
-rw-r--r--tests/rustdoc/async-fn-opaque-item.rs4
-rw-r--r--tests/rustdoc/compiler-derive-proc-macro.rs6
-rw-r--r--tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs4
-rw-r--r--tests/rustdoc/issue-105735-overlapping-reexport-2.rs6
-rw-r--r--tests/rustdoc/issue-105735-overlapping-reexport.rs6
-rw-r--r--tests/rustdoc/issue-109258-missing-private-inlining.rs10
-rw-r--r--tests/rustdoc/issue-109449-doc-hidden-reexports.rs12
-rw-r--r--tests/rustdoc/issue-110422-inner-private.rs18
-rw-r--r--tests/rustdoc/issue-60522-duplicated-glob-reexport.rs4
-rw-r--r--tests/rustdoc/nested-items-issue-111415.rs8
-rw-r--r--tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html2
-rw-r--r--tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html2
-rw-r--r--tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html2
-rw-r--r--tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html2
-rw-r--r--tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html2
-rw-r--r--tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs8
-rw-r--r--tests/rustdoc/rfc-2632-const-trait-impl.rs10
-rw-r--r--tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs6
-rw-r--r--tests/rustdoc/typedef-inner-variants.rs4
-rw-r--r--tests/rustdoc/where.SWhere_Echo_impl.html4
-rw-r--r--tests/rustdoc/where.bravo_trait_decl.html4
-rw-r--r--tests/rustdoc/where.charlie_fn_decl.html4
-rw-r--r--tests/rustdoc/where.golf_type_alias_decl.html4
-rw-r--r--tests/rustdoc/whitespace-after-where-clause.enum.html4
-rw-r--r--tests/rustdoc/whitespace-after-where-clause.struct.html4
-rw-r--r--tests/rustdoc/whitespace-after-where-clause.trait.html4
-rw-r--r--tests/rustdoc/whitespace-after-where-clause.union.html4
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr2
-rw-r--r--tests/ui/associated-item/associated-item-duplicate-bounds.stderr2
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.min.stderr46
-rw-r--r--tests/ui/const-generics/const-argument-if-length.min.stderr2
-rw-r--r--tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr2
-rw-r--r--tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr4
-rw-r--r--tests/ui/const-generics/early/macro_rules-braces.stderr8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-74713.stderr2
-rw-r--r--tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr2
-rw-r--r--tests/ui/const-generics/issue-46511.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-67375.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-67945-1.min.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-67945-3.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-67945-4.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-68366.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-80062.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-80375.stderr2
-rw-r--r--tests/ui/const-generics/legacy-const-generics-bad.stderr2
-rw-r--r--tests/ui/const-generics/min_const_generics/complex-expression.stderr14
-rw-r--r--tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr4
-rw-r--r--tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr2
-rw-r--r--tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr2
-rw-r--r--tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr2
-rw-r--r--tests/ui/consts/const-eval/size-of-t.stderr2
-rw-r--r--tests/ui/consts/raw-ptr-const.rs2
-rw-r--r--tests/ui/error-codes/E0458.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-link-arg-attribute.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr12
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88382.stderr4
-rw-r--r--tests/ui/generics/param-in-ct-in-ty-param-default.stderr2
-rw-r--r--tests/ui/impl-trait/equality-in-canonical-query.clone.stderr2
-rw-r--r--tests/ui/imports/no-pub-reexports-but-used.rs15
-rw-r--r--tests/ui/imports/no-pub-reexports-but-used.stderr20
-rw-r--r--tests/ui/imports/reexports.rs2
-rw-r--r--tests/ui/imports/reexports.stderr9
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.stderr4
-rw-r--r--tests/ui/issues/issue-76077.stderr2
-rw-r--r--tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr2
-rw-r--r--tests/ui/mismatched_types/E0631.stderr8
-rw-r--r--tests/ui/mismatched_types/closure-ref-114180.stderr4
-rw-r--r--tests/ui/mismatched_types/fn-variance-1.stderr8
-rw-r--r--tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr4
-rw-r--r--tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr8
-rw-r--r--tests/ui/mismatched_types/suggest-option-asderef.fixed39
-rw-r--r--tests/ui/mismatched_types/suggest-option-asderef.rs6
-rw-r--r--tests/ui/mismatched_types/suggest-option-asderef.stderr22
-rw-r--r--tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr4
-rw-r--r--tests/ui/native-library-link-flags/link-arg-from-rs.rs9
-rw-r--r--tests/ui/native-library-link-flags/link-arg-from-rs.stderr18
-rw-r--r--tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs46
-rw-r--r--tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr26
-rw-r--r--tests/ui/privacy/issue-79593.stderr2
-rw-r--r--tests/ui/privacy/private-variant-reexport.stderr8
-rw-r--r--tests/ui/privacy/suggest-box-new.stderr4
-rw-r--r--tests/ui/proc-macro/literal-to-string.rs1
-rw-r--r--tests/ui/proc-macro/literal-to-string.stdout30
-rw-r--r--tests/ui/resolve/issue-39559.stderr2
-rw-r--r--tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs2
-rw-r--r--tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs15
-rw-r--r--tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr21
-rw-r--r--tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rsbin623 -> 594 bytes
-rw-r--r--tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderrbin674 -> 674 bytes
-rw-r--r--tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs2
-rw-r--r--tests/ui/suggestions/enum-variant-arg-mismatch.stderr4
-rw-r--r--tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr4
-rw-r--r--tests/ui/traits/subtype-recursion-limit.rs17
-rw-r--r--tests/ui/traits/subtype-recursion-limit.stderr9
-rw-r--r--tests/ui/traits/well-formed-recursion-limit.rs27
-rw-r--r--tests/ui/traits/well-formed-recursion-limit.stderr22
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.rs (renamed from tests/ui/treat-err-as-bug/delay_span_bug.rs)4
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.stderr (renamed from tests/ui/treat-err-as-bug/delay_span_bug.stderr)6
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr2
-rw-r--r--tests/ui/type-inference/generalize-subtyped-variables.rs25
-rw-r--r--tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr2
-rw-r--r--tests/ui/typeck/mismatched-map-under-self.stderr4
-rw-r--r--tests/ui/typeck/missing-private-fields-in-struct-literal.stderr2
-rw-r--r--triagebot.toml2
371 files changed, 2474 insertions, 1831 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1296468b4e2..75c5f78e2b6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -509,9 +509,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.3.1"
+version = "4.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f6b5c519bab3ea61843a7923d074b04245624bb84a64a8c150f5deb014e388b"
+checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae"
 dependencies = [
  "clap",
 ]
@@ -580,7 +580,7 @@ dependencies = [
  "clap",
  "indoc",
  "itertools",
- "opener",
+ "opener 0.5.2",
  "shell-escape",
  "walkdir",
 ]
@@ -2340,9 +2340,9 @@ dependencies = [
 
 [[package]]
 name = "mdbook"
-version = "0.4.31"
+version = "0.4.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b67ee4a744f36e6280792016c17e69921b51df357181d1eb17d620fcc3609f3"
+checksum = "80992cb0e05f22cc052c99f8e883f1593b891014b96a8b4637fd274d7030c85e"
 dependencies = [
  "ammonia",
  "anyhow",
@@ -2355,7 +2355,8 @@ dependencies = [
  "log",
  "memchr",
  "once_cell",
- "opener",
+ "opener 0.6.1",
+ "pathdiff",
  "pulldown-cmark",
  "regex",
  "serde",
@@ -2545,6 +2546,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "normpath"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5"
+dependencies = [
+ "windows-sys 0.48.0",
+]
+
+[[package]]
 name = "ntapi"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2632,6 +2642,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "opener"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788"
+dependencies = [
+ "bstr",
+ "normpath",
+ "winapi",
+]
+
+[[package]]
 name = "openssl"
 version = "0.10.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 815edcc0dc4..050366b081f 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -14,7 +14,7 @@ use crate::{
 pub trait LayoutCalculator {
     type TargetDataLayoutRef: Borrow<TargetDataLayout>;
 
-    fn delay_bug(&self, txt: String);
+    fn delayed_bug(&self, txt: String);
     fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
 
     fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>(
@@ -792,7 +792,7 @@ pub trait LayoutCalculator {
         let only_variant = &variants[VariantIdx::new(0)];
         for field in only_variant {
             if field.is_unsized() {
-                self.delay_bug("unsized field in union".to_string());
+                self.delayed_bug("unsized field in union".to_string());
             }
 
             align = align.max(field.align);
@@ -1038,7 +1038,7 @@ fn univariant<
     for &i in &inverse_memory_index {
         let field = &fields[i];
         if !sized {
-            this.delay_bug(format!(
+            this.delayed_bug(format!(
                 "univariant: field #{} comes after unsized field",
                 offsets.len(),
             ));
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index be5671f1bf7..5b07299d411 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -327,7 +327,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ),
                 ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
                 ExprKind::Err => hir::ExprKind::Err(
-                    self.tcx.sess.delay_span_bug(e.span, "lowered ExprKind::Err"),
+                    self.tcx.sess.span_delayed_bug(e.span, "lowered ExprKind::Err"),
                 ),
                 ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
 
@@ -799,7 +799,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 self.expr_ident_mut(span, task_context_ident, task_context_hid)
             } else {
                 // Use of `await` outside of an async context, we cannot use `task_context` here.
-                self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no task_context hir id"))
+                self.expr_err(span, self.tcx.sess.span_delayed_bug(span, "no task_context hir id"))
             };
             let new_unchecked = self.expr_call_lang_item_fn_mut(
                 span,
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index b6202be4f52..8fa2cae43bf 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -267,7 +267,7 @@ fn make_count<'hir>(
                 ctx.expr(
                     sp,
                     hir::ExprKind::Err(
-                        ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count"),
+                        ctx.tcx.sess.span_delayed_bug(sp, "lowered bad format_args count"),
                     ),
                 )
             }
@@ -306,7 +306,7 @@ fn make_format_spec<'hir>(
         }
         Err(_) => ctx.expr(
             sp,
-            hir::ExprKind::Err(ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count")),
+            hir::ExprKind::Err(ctx.tcx.sess.span_delayed_bug(sp, "lowered bad format_args count")),
         ),
     };
     let &FormatOptions {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c47c5fc8fcc..fbbb9d7a52a 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -256,7 +256,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
                         None => {
-                            let guar = this.tcx.sess.delay_span_bug(
+                            let guar = this.tcx.sess.span_delayed_bug(
                                 span,
                                 "expected to lower type alias type, but it was missing",
                             );
@@ -863,7 +863,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
                         None => {
-                            let guar = this.tcx.sess.delay_span_bug(
+                            let guar = this.tcx.sess.span_delayed_bug(
                                 i.span,
                                 "expected to lower associated type, but it was missing",
                             );
@@ -996,7 +996,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
         match block {
             Some(block) => self.lower_block_expr(block),
-            None => self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no block")),
+            None => self.expr_err(span, self.tcx.sess.span_delayed_bug(span, "no block")),
         }
     }
 
@@ -1006,7 +1006,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 &[],
                 match expr {
                     Some(expr) => this.lower_expr_mut(expr),
-                    None => this.expr_err(span, this.tcx.sess.delay_span_bug(span, "no block")),
+                    None => this.expr_err(span, this.tcx.sess.span_delayed_bug(span, "no block")),
                 },
             )
         })
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 4abd0f135c6..eb6d11a72e6 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -54,7 +54,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey};
+use rustc_errors::{DiagnosticArgFromDisplay, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -763,10 +763,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.resolver.get_import_res(id).present_items()
     }
 
-    fn diagnostic(&self) -> &Handler {
-        self.tcx.sess.diagnostic()
-    }
-
     /// Reuses the span but adds information like the kind of the desugaring and features that are
     /// allowed inside this span.
     fn mark_span_with_reason(
@@ -1326,7 +1322,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let kind = match &t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => {
-                hir::TyKind::Err(self.tcx.sess.delay_span_bug(t.span, "TyKind::Err lowered"))
+                hir::TyKind::Err(self.tcx.sess.span_delayed_bug(t.span, "TyKind::Err lowered"))
             }
             // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
             #[allow(rustc::untranslatable_diagnostic)]
@@ -1510,7 +1506,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
             TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
             TyKind::CVarArgs => {
-                let guar = self.tcx.sess.delay_span_bug(
+                let guar = self.tcx.sess.span_delayed_bug(
                     t.span,
                     "`TyKind::CVarArgs` should have been handled elsewhere",
                 );
@@ -1653,7 +1649,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     } else {
                         self.tcx
                             .sess
-                            .delay_span_bug(lifetime.ident.span, "no def-id for fresh lifetime");
+                            .span_delayed_bug(lifetime.ident.span, "no def-id for fresh lifetime");
                         continue;
                     }
                 }
@@ -2515,9 +2511,10 @@ impl<'hir> GenericArgsCtor<'hir> {
         let hir_id = lcx.next_id();
 
         let Some(host_param_id) = lcx.host_param_id else {
-            lcx.tcx
-                .sess
-                .delay_span_bug(span, "no host param id for call in const yet no errors reported");
+            lcx.tcx.sess.span_delayed_bug(
+                span,
+                "no host param id for call in const yet no errors reported",
+            );
             return;
         };
 
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 8050f5826aa..db8ca7c3643 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -139,7 +139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         // We should've returned in the for loop above.
 
-        self.diagnostic().span_bug(
+        self.tcx.sess.diagnostic().span_bug(
             p.span,
             format!(
                 "lower_qpath: no final extension segment in {}..{}",
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 8851fbd28f0..897f35a5c4a 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -102,7 +102,7 @@ impl<'a> PostExpansionVisitor<'a> {
             }
             Err(abi::AbiDisabled::Unrecognized) => {
                 if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
-                    self.sess.parse_sess.span_diagnostic.delay_span_bug(
+                    self.sess.diagnostic().span_delayed_bug(
                         span,
                         format!(
                             "unrecognized ABI not caught in lowering: {}",
@@ -515,7 +515,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
             }
         };
     }
-    gate_all!(c_str_literals, "`c\"..\"` literals are experimental");
     gate_all!(
         if_let_guard,
         "`if let` guards are experimental",
@@ -628,7 +627,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
             if all_stable {
                 err.sugg = Some(attr.span);
             }
-            sess.parse_sess.span_diagnostic.emit_err(err);
+            sess.diagnostic().emit_err(err);
         }
     }
 }
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 609d75733b2..a6930fe0a17 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -945,7 +945,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
     assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}");
     use ReprAttr::*;
     let mut acc = Vec::new();
-    let diagnostic = &sess.parse_sess.span_diagnostic;
+    let diagnostic = sess.diagnostic();
 
     if let Some(items) = attr.meta_item_list() {
         for item in items {
@@ -1060,9 +1060,9 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
                 // Not a word we recognize. This will be caught and reported by
                 // the `check_mod_attrs` pass, but this pass doesn't always run
                 // (e.g. if we only pretty-print the source), so we have to gate
-                // the `delay_span_bug` call as follows:
+                // the `span_delayed_bug` call as follows:
                 if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) {
-                    diagnostic.delay_span_bug(item.span(), "unrecognized representation hint");
+                    diagnostic.span_delayed_bug(item.span(), "unrecognized representation hint");
                 }
             }
         }
diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs
deleted file mode 100644
index 21d367c40cb..00000000000
--- a/compiler/rustc_borrowck/src/constraint_generation.rs
+++ /dev/null
@@ -1,248 +0,0 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-use rustc_infer::infer::InferCtxt;
-use rustc_middle::mir::visit::TyContext;
-use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{
-    Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, SourceInfo, Statement,
-    StatementKind, Terminator, TerminatorKind, UserTypeProjection,
-};
-use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::GenericArgsRef;
-use rustc_middle::ty::{self, Ty, TyCtxt};
-
-use crate::{
-    borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict,
-    region_infer::values::LivenessValues,
-};
-
-pub(super) fn generate_constraints<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    liveness_constraints: &mut LivenessValues,
-    all_facts: &mut Option<AllFacts>,
-    location_table: &LocationTable,
-    body: &Body<'tcx>,
-    borrow_set: &BorrowSet<'tcx>,
-) {
-    let mut cg = ConstraintGeneration {
-        borrow_set,
-        infcx,
-        liveness_constraints,
-        location_table,
-        all_facts,
-        body,
-    };
-
-    for (bb, data) in body.basic_blocks.iter_enumerated() {
-        cg.visit_basic_block_data(bb, data);
-    }
-}
-
-/// 'cg = the duration of the constraint generation process itself.
-struct ConstraintGeneration<'cg, 'tcx> {
-    infcx: &'cg InferCtxt<'tcx>,
-    all_facts: &'cg mut Option<AllFacts>,
-    location_table: &'cg LocationTable,
-    liveness_constraints: &'cg mut LivenessValues,
-    borrow_set: &'cg BorrowSet<'tcx>,
-    body: &'cg Body<'tcx>,
-}
-
-impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
-    /// We sometimes have `args` within an rvalue, or within a
-    /// call. Make them live at the location where they appear.
-    fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
-        self.add_regular_live_constraint(*args, location);
-        self.super_args(args);
-    }
-
-    /// We sometimes have `region` within an rvalue, or within a
-    /// call. Make them live at the location where they appear.
-    fn visit_region(&mut self, region: ty::Region<'tcx>, location: Location) {
-        self.add_regular_live_constraint(region, location);
-        self.super_region(region);
-    }
-
-    /// We sometimes have `ty` within an rvalue, or within a
-    /// call. Make them live at the location where they appear.
-    fn visit_ty(&mut self, ty: Ty<'tcx>, ty_context: TyContext) {
-        match ty_context {
-            TyContext::ReturnTy(SourceInfo { span, .. })
-            | TyContext::YieldTy(SourceInfo { span, .. })
-            | TyContext::UserTy(span)
-            | TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => {
-                span_bug!(span, "should not be visiting outside of the CFG: {:?}", ty_context);
-            }
-            TyContext::Location(location) => {
-                self.add_regular_live_constraint(ty, location);
-            }
-        }
-
-        self.super_ty(ty);
-    }
-
-    fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
-        if let Some(all_facts) = self.all_facts {
-            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
-            all_facts.cfg_edge.push((
-                self.location_table.start_index(location),
-                self.location_table.mid_index(location),
-            ));
-
-            all_facts.cfg_edge.push((
-                self.location_table.mid_index(location),
-                self.location_table.start_index(location.successor_within_block()),
-            ));
-
-            // If there are borrows on this now dead local, we need to record them as `killed`.
-            if let StatementKind::StorageDead(local) = statement.kind {
-                record_killed_borrows_for_local(
-                    all_facts,
-                    self.borrow_set,
-                    self.location_table,
-                    local,
-                    location,
-                );
-            }
-        }
-
-        self.super_statement(statement, location);
-    }
-
-    fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
-        // When we see `X = ...`, then kill borrows of
-        // `(*X).foo` and so forth.
-        self.record_killed_borrows_for_place(*place, location);
-
-        self.super_assign(place, rvalue, location);
-    }
-
-    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
-        if let Some(all_facts) = self.all_facts {
-            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
-            all_facts.cfg_edge.push((
-                self.location_table.start_index(location),
-                self.location_table.mid_index(location),
-            ));
-
-            let successor_blocks = terminator.successors();
-            all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
-            for successor_block in successor_blocks {
-                all_facts.cfg_edge.push((
-                    self.location_table.mid_index(location),
-                    self.location_table.start_index(successor_block.start_location()),
-                ));
-            }
-        }
-
-        // A `Call` terminator's return value can be a local which has borrows,
-        // so we need to record those as `killed` as well.
-        if let TerminatorKind::Call { destination, .. } = terminator.kind {
-            self.record_killed_borrows_for_place(destination, location);
-        }
-
-        self.super_terminator(terminator, location);
-    }
-
-    fn visit_ascribe_user_ty(
-        &mut self,
-        _place: &Place<'tcx>,
-        _variance: ty::Variance,
-        _user_ty: &UserTypeProjection,
-        _location: Location,
-    ) {
-    }
-}
-
-impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> {
-    /// Some variable with type `live_ty` is "regular live" at
-    /// `location` -- i.e., it may be used later. This means that all
-    /// regions appearing in the type `live_ty` must be live at
-    /// `location`.
-    fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location)
-    where
-        T: TypeVisitable<TyCtxt<'tcx>>,
-    {
-        debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location);
-
-        self.infcx.tcx.for_each_free_region(&live_ty, |live_region| {
-            let vid = live_region.as_var();
-            self.liveness_constraints.add_location(vid, location);
-        });
-    }
-
-    /// When recording facts for Polonius, records the borrows on the specified place
-    /// as `killed`. For example, when assigning to a local, or on a call's return destination.
-    fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
-        if let Some(all_facts) = self.all_facts {
-            let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
-
-            // Depending on the `Place` we're killing:
-            // - if it's a local, or a single deref of a local,
-            //   we kill all the borrows on the local.
-            // - if it's a deeper projection, we have to filter which
-            //   of the borrows are killed: the ones whose `borrowed_place`
-            //   conflicts with the `place`.
-            match place.as_ref() {
-                PlaceRef { local, projection: &[] }
-                | PlaceRef { local, projection: &[ProjectionElem::Deref] } => {
-                    debug!(
-                        "Recording `killed` facts for borrows of local={:?} at location={:?}",
-                        local, location
-                    );
-
-                    record_killed_borrows_for_local(
-                        all_facts,
-                        self.borrow_set,
-                        self.location_table,
-                        local,
-                        location,
-                    );
-                }
-
-                PlaceRef { local, projection: &[.., _] } => {
-                    // Kill conflicting borrows of the innermost local.
-                    debug!(
-                        "Recording `killed` facts for borrows of \
-                            innermost projected local={:?} at location={:?}",
-                        local, location
-                    );
-
-                    if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
-                        for &borrow_index in borrow_indices {
-                            let places_conflict = places_conflict::places_conflict(
-                                self.infcx.tcx,
-                                self.body,
-                                self.borrow_set[borrow_index].borrowed_place,
-                                place,
-                                places_conflict::PlaceConflictBias::NoOverlap,
-                            );
-
-                            if places_conflict {
-                                let location_index = self.location_table.mid_index(location);
-                                all_facts.loan_killed_at.push((borrow_index, location_index));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-/// When recording facts for Polonius, records the borrows on the specified local as `killed`.
-fn record_killed_borrows_for_local(
-    all_facts: &mut AllFacts,
-    borrow_set: &BorrowSet<'_>,
-    location_table: &LocationTable,
-    local: Local,
-    location: Location,
-) {
-    if let Some(borrow_indices) = borrow_set.local_map.get(&local) {
-        all_facts.loan_killed_at.reserve(borrow_indices.len());
-        for &borrow_index in borrow_indices {
-            let location_index = location_table.mid_index(location);
-            all_facts.loan_killed_at.push((borrow_index, location_index));
-        }
-    }
-}
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index b3d14c1beb5..54f161ea9b4 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -432,7 +432,8 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
 
             assert_eq!(
                 borrows_out_of_scope_at_location, polonius_prec.loans_out_of_scope_at_location,
-                "the loans out of scope must be the same as the borrows out of scope"
+                "polonius loan scopes differ from NLL borrow scopes, for body {:?}",
+                body.span,
             );
 
             borrows_out_of_scope_at_location = polonius_prec.loans_out_of_scope_at_location;
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 03172ef34b9..924e68fa91d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -385,7 +385,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
     error_region: Option<ty::Region<'tcx>>,
 ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
     // We generally shouldn't have errors here because the query was
-    // already run, but there's no point using `delay_span_bug`
+    // already run, but there's no point using `span_delayed_bug`
     // when we're going to emit an error here anyway.
     let _errors = ocx.select_all_or_error();
     let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index ef4bf543454..7bcad92ff33 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1135,7 +1135,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             });
         } else {
             issued_spans.var_subdiag(
-                Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic),
+                Some(self.infcx.tcx.sess.diagnostic()),
                 &mut err,
                 Some(issued_borrow.kind),
                 |kind, var_span| {
@@ -1152,7 +1152,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             );
 
             borrow_spans.var_subdiag(
-                Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic),
+                Some(self.infcx.tcx.sess.diagnostic()),
                 &mut err,
                 Some(gen_borrow_kind),
                 |kind, var_span| {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index e37457f48df..4deed98d002 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -124,7 +124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         let did = did.expect_local();
                         if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
                             diag.eager_subdiagnostic(
-                                &self.infcx.tcx.sess.parse_sess.span_diagnostic,
+                                self.infcx.tcx.sess.diagnostic(),
                                 OnClosureNote::InvokedTwice {
                                     place_name: &ty::place_to_string_for_capture(
                                         self.infcx.tcx,
@@ -146,7 +146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 let did = did.expect_local();
                 if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
                     diag.eager_subdiagnostic(
-                        &self.infcx.tcx.sess.parse_sess.span_diagnostic,
+                        self.infcx.tcx.sess.diagnostic(),
                         OnClosureNote::MovedTwice {
                             place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place),
                             span: *span,
@@ -1119,7 +1119,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             && self.infcx.can_eq(self.param_env, ty, self_ty)
                         {
                             err.eager_subdiagnostic(
-                                &self.infcx.tcx.sess.parse_sess.span_diagnostic,
+                                self.infcx.tcx.sess.diagnostic(),
                                 CaptureReasonSuggest::FreshReborrow {
                                     span: move_span.shrink_to_hi(),
                                 },
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 40bbc5e7c41..759f5e910f7 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -84,7 +84,7 @@ impl<'tcx> RegionErrors<'tcx> {
     #[track_caller]
     pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
         let val = val.into();
-        self.1.sess.delay_span_bug(DUMMY_SP, format!("{val:?}"));
+        self.1.sess.span_delayed_bug(DUMMY_SP, format!("{val:?}"));
         self.0.push(val);
     }
     pub fn is_empty(&self) -> bool {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 730b65898bc..977a5d5d50d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -619,8 +619,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     _,
                 ) => {
                     // HIR lowering sometimes doesn't catch this in erroneous
-                    // programs, so we need to use delay_span_bug here. See #82126.
-                    self.infcx.tcx.sess.delay_span_bug(
+                    // programs, so we need to use span_delayed_bug here. See #82126.
+                    self.infcx.tcx.sess.span_delayed_bug(
                         hir_arg.span(),
                         format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
                     );
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 6e44f44dc18..3d3fd412ae0 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -65,19 +65,18 @@ use self::path_utils::*;
 
 pub mod borrow_set;
 mod borrowck_errors;
-mod constraint_generation;
 mod constraints;
 mod dataflow;
 mod def_use;
 mod diagnostics;
 mod facts;
-mod invalidation;
 mod location;
 mod member_constraints;
 mod nll;
 mod path_utils;
 mod place_ext;
 mod places_conflict;
+mod polonius;
 mod prefixes;
 mod region_infer;
 mod renumber;
@@ -195,8 +194,7 @@ fn do_mir_borrowck<'tcx>(
         nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted);
     let body = &body_owned; // no further changes
 
-    let location_table_owned = LocationTable::new(body);
-    let location_table = &location_table_owned;
+    let location_table = LocationTable::new(body);
 
     let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
     let promoted_move_data = promoted
@@ -228,7 +226,7 @@ fn do_mir_borrowck<'tcx>(
         free_regions,
         body,
         &promoted,
-        location_table,
+        &location_table,
         param_env,
         &mut flow_inits,
         &mdpe.move_data,
@@ -292,7 +290,7 @@ fn do_mir_borrowck<'tcx>(
             param_env,
             body: promoted_body,
             move_data: &move_data,
-            location_table, // no need to create a real one for the promoted, it is not used
+            location_table: &location_table, // no need to create a real one for the promoted, it is not used
             movable_coroutine,
             fn_self_span_reported: Default::default(),
             locals_are_invalidated_at_exit,
@@ -333,7 +331,7 @@ fn do_mir_borrowck<'tcx>(
         param_env,
         body,
         move_data: &mdpe.move_data,
-        location_table,
+        location_table: &location_table,
         movable_coroutine,
         locals_are_invalidated_at_exit,
         fn_self_span_reported: Default::default(),
@@ -435,7 +433,7 @@ fn do_mir_borrowck<'tcx>(
             promoted,
             borrow_set,
             region_inference_context: regioncx,
-            location_table: polonius_input.as_ref().map(|_| location_table_owned),
+            location_table: polonius_input.as_ref().map(|_| location_table),
             input_facts: polonius_input,
             output_facts,
         }))
@@ -1020,9 +1018,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         flow_state: &Flows<'cx, 'tcx>,
     ) -> bool {
         let mut error_reported = false;
-        let tcx = self.infcx.tcx;
-        let body = self.body;
-        let borrow_set = self.borrow_set.clone();
+        let borrow_set = Rc::clone(&self.borrow_set);
 
         // Use polonius output if it has been enabled.
         let mut polonius_output;
@@ -1039,8 +1035,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         each_borrow_involving_path(
             self,
-            tcx,
-            body,
+            self.infcx.tcx,
+            self.body,
             location,
             (sd, place_span.0),
             &borrow_set,
@@ -2134,11 +2130,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     && !self.has_buffered_errors()
                 {
                     // rust-lang/rust#46908: In pure NLL mode this code path should be
-                    // unreachable, but we use `delay_span_bug` because we can hit this when
+                    // unreachable, but we use `span_delayed_bug` because we can hit this when
                     // dereferencing a non-Copy raw pointer *and* have `-Ztreat-err-as-bug`
                     // enabled. We don't want to ICE for that case, as other errors will have
                     // been emitted (#52262).
-                    self.infcx.tcx.sess.delay_span_bug(
+                    self.infcx.tcx.sess.span_delayed_bug(
                         span,
                         format!(
                             "Accessing `{place:?}` with the kind `{kind:?}` shouldn't be possible",
@@ -2432,7 +2428,7 @@ mod error {
 
         pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
             if let None = self.tainted_by_errors {
-                self.tainted_by_errors = Some(self.tcx.sess.delay_span_bug(
+                self.tainted_by_errors = Some(self.tcx.sess.span_delayed_bug(
                     t.span.clone_ignoring_labels(),
                     "diagnostic buffered but not emitted",
                 ))
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 480358ef997..c88d9d81fe1 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -2,16 +2,17 @@
 #![deny(rustc::diagnostic_outside_of_impl)]
 //! The entry point of the NLL borrow checker.
 
+use polonius_engine::{Algorithm, Output};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::IndexSlice;
 use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
-use rustc_middle::mir::{
-    Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, Promoted,
-    START_BLOCK,
-};
+use rustc_middle::mir::{Body, ClosureOutlivesSubject, ClosureRegionRequirements, Promoted};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
+use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
+use rustc_mir_dataflow::move_paths::MoveData;
+use rustc_mir_dataflow::ResultsCursor;
 use rustc_span::symbol::sym;
 use std::env;
 use std::io;
@@ -19,20 +20,13 @@ use std::path::PathBuf;
 use std::rc::Rc;
 use std::str::FromStr;
 
-use polonius_engine::{Algorithm, Output};
-
-use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
-use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
-use rustc_mir_dataflow::ResultsCursor;
-
 use crate::{
     borrow_set::BorrowSet,
-    constraint_generation,
     consumers::ConsumerOptions,
     diagnostics::RegionErrors,
     facts::{AllFacts, AllFactsExt, RustcFacts},
-    invalidation,
     location::LocationTable,
+    polonius,
     region_infer::{values::RegionValueElements, RegionInferenceContext},
     renumber,
     type_check::{self, MirTypeckRegionConstraints, MirTypeckResults},
@@ -78,81 +72,6 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
     universal_regions
 }
 
-// This function populates an AllFacts instance with base facts related to
-// MovePaths and needed for the move analysis.
-fn populate_polonius_move_facts(
-    all_facts: &mut AllFacts,
-    move_data: &MoveData<'_>,
-    location_table: &LocationTable,
-    body: &Body<'_>,
-) {
-    all_facts
-        .path_is_var
-        .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l)));
-
-    for (child, move_path) in move_data.move_paths.iter_enumerated() {
-        if let Some(parent) = move_path.parent {
-            all_facts.child_path.push((child, parent));
-        }
-    }
-
-    let fn_entry_start =
-        location_table.start_index(Location { block: START_BLOCK, statement_index: 0 });
-
-    // initialized_at
-    for init in move_data.inits.iter() {
-        match init.location {
-            InitLocation::Statement(location) => {
-                let block_data = &body[location.block];
-                let is_terminator = location.statement_index == block_data.statements.len();
-
-                if is_terminator && init.kind == InitKind::NonPanicPathOnly {
-                    // We are at the terminator of an init that has a panic path,
-                    // and where the init should not happen on panic
-
-                    for successor in block_data.terminator().successors() {
-                        if body[successor].is_cleanup {
-                            continue;
-                        }
-
-                        // The initialization happened in (or rather, when arriving at)
-                        // the successors, but not in the unwind block.
-                        let first_statement = Location { block: successor, statement_index: 0 };
-                        all_facts
-                            .path_assigned_at_base
-                            .push((init.path, location_table.start_index(first_statement)));
-                    }
-                } else {
-                    // In all other cases, the initialization just happens at the
-                    // midpoint, like any other effect.
-                    all_facts
-                        .path_assigned_at_base
-                        .push((init.path, location_table.mid_index(location)));
-                }
-            }
-            // Arguments are initialized on function entry
-            InitLocation::Argument(local) => {
-                assert!(body.local_kind(local) == LocalKind::Arg);
-                all_facts.path_assigned_at_base.push((init.path, fn_entry_start));
-            }
-        }
-    }
-
-    for (local, path) in move_data.rev_lookup.iter_locals_enumerated() {
-        if body.local_kind(local) != LocalKind::Arg {
-            // Non-arguments start out deinitialised; we simulate this with an
-            // initial move:
-            all_facts.path_moved_at_base.push((path, fn_entry_start));
-        }
-    }
-
-    // moved_out_at
-    // deinitialisation is assumed to always happen!
-    all_facts
-        .path_moved_at_base
-        .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source))));
-}
-
 /// Computes the (non-lexical) regions from the input MIR.
 ///
 /// This may result in errors being reported.
@@ -182,67 +101,23 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
     let elements = &Rc::new(RegionValueElements::new(body));
 
     // Run the MIR type-checker.
-    let MirTypeckResults {
-        constraints,
-        universal_region_relations,
-        opaque_type_values,
-        live_loans,
-    } = type_check::type_check(
-        infcx,
-        param_env,
-        body,
-        promoted,
-        &universal_regions,
-        location_table,
-        borrow_set,
-        &mut all_facts,
-        flow_inits,
-        move_data,
-        elements,
-        upvars,
-        polonius_input,
-    );
-
-    if let Some(all_facts) = &mut all_facts {
-        let _prof_timer = infcx.tcx.prof.generic_activity("polonius_fact_generation");
-        all_facts.universal_region.extend(universal_regions.universal_regions());
-        populate_polonius_move_facts(all_facts, move_data, location_table, body);
-
-        // Emit universal regions facts, and their relations, for Polonius.
-        //
-        // 1: universal regions are modeled in Polonius as a pair:
-        // - the universal region vid itself.
-        // - a "placeholder loan" associated to this universal region. Since they don't exist in
-        //   the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
-        //   added to the existing number of loans, as if they succeeded them in the set.
-        //
-        let borrow_count = borrow_set.len();
-        debug!(
-            "compute_regions: polonius placeholders, num_universals={}, borrow_count={}",
-            universal_regions.len(),
-            borrow_count
+    let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
+        type_check::type_check(
+            infcx,
+            param_env,
+            body,
+            promoted,
+            &universal_regions,
+            location_table,
+            borrow_set,
+            &mut all_facts,
+            flow_inits,
+            move_data,
+            elements,
+            upvars,
+            polonius_input,
         );
 
-        for universal_region in universal_regions.universal_regions() {
-            let universal_region_idx = universal_region.index();
-            let placeholder_loan_idx = borrow_count + universal_region_idx;
-            all_facts.placeholder.push((universal_region, placeholder_loan_idx.into()));
-        }
-
-        // 2: the universal region relations `outlives` constraints are emitted as
-        //  `known_placeholder_subset` facts.
-        for (fr1, fr2) in universal_region_relations.known_outlives() {
-            if fr1 != fr2 {
-                debug!(
-                    "compute_regions: emitting polonius `known_placeholder_subset` \
-                     fr1={:?}, fr2={:?}",
-                    fr1, fr2
-                );
-                all_facts.known_placeholder_subset.push((fr1, fr2));
-            }
-        }
-    }
-
     // Create the region inference context, taking ownership of the
     // region inference data that was contained in `infcx`, and the
     // base constraints generated by the type-check.
@@ -250,7 +125,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
     let MirTypeckRegionConstraints {
         placeholder_indices,
         placeholder_index_to_region: _,
-        mut liveness_constraints,
+        liveness_constraints,
         outlives_constraints,
         member_constraints,
         universe_causes,
@@ -258,13 +133,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
     } = constraints;
     let placeholder_indices = Rc::new(placeholder_indices);
 
-    constraint_generation::generate_constraints(
-        infcx,
-        &mut liveness_constraints,
+    // If requested, emit legacy polonius facts.
+    polonius::emit_facts(
         &mut all_facts,
+        infcx.tcx,
         location_table,
         body,
         borrow_set,
+        move_data,
+        &universal_regions,
+        &universal_region_relations,
     );
 
     let mut regioncx = RegionInferenceContext::new(
@@ -279,17 +157,12 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
         type_tests,
         liveness_constraints,
         elements,
-        live_loans,
     );
 
-    // Generate various additional constraints.
-    invalidation::generate_invalidates(infcx.tcx, &mut all_facts, location_table, body, borrow_set);
-
-    let def_id = body.source.def_id();
-
-    // Dump facts if requested.
+    // If requested: dump NLL facts, and run legacy polonius analysis.
     let polonius_output = all_facts.as_ref().and_then(|all_facts| {
         if infcx.tcx.sess.opts.unstable_opts.nll_facts {
+            let def_id = body.source.def_id();
             let def_path = infcx.tcx.def_path(def_id);
             let dir_path = PathBuf::from(&infcx.tcx.sess.opts.unstable_opts.nll_facts_dir)
                 .join(def_path.to_filename_friendly_no_crate());
@@ -314,7 +187,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
 
     if !nll_errors.is_empty() {
         // Suppress unhelpful extra errors in `infer_opaque_types`.
-        infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
+        infcx.set_tainted_by_errors(infcx.tcx.sess.span_delayed_bug(
             body.span,
             "`compute_regions` tainted `infcx` with errors but did not emit any errors",
         ));
@@ -407,7 +280,7 @@ pub(super) fn dump_annotation<'tcx>(
 
     let def_span = tcx.def_span(body.source.def_id());
     let mut err = if let Some(closure_region_requirements) = closure_region_requirements {
-        let mut err = tcx.sess.diagnostic().span_note_diag(def_span, "external requirements");
+        let mut err = tcx.sess.diagnostic().struct_span_note(def_span, "external requirements");
 
         regioncx.annotate(tcx, &mut err);
 
@@ -426,7 +299,7 @@ pub(super) fn dump_annotation<'tcx>(
 
         err
     } else {
-        let mut err = tcx.sess.diagnostic().span_note_diag(def_span, "no external requirements");
+        let mut err = tcx.sess.diagnostic().struct_span_note(def_span, "no external requirements");
         regioncx.annotate(tcx, &mut err);
 
         err
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
index a3db101311f..232bd741825 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
@@ -14,34 +14,21 @@ use crate::{
     ReadOrWrite, Reservation, Shallow, Write, WriteKind,
 };
 
-pub(super) fn generate_invalidates<'tcx>(
+/// Emit `loan_invalidated_at` facts.
+pub(super) fn emit_loan_invalidations<'tcx>(
     tcx: TyCtxt<'tcx>,
-    all_facts: &mut Option<AllFacts>,
+    all_facts: &mut AllFacts,
     location_table: &LocationTable,
     body: &Body<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
 ) {
-    if all_facts.is_none() {
-        // Nothing to do if we don't have any facts
-        return;
-    }
-
-    if let Some(all_facts) = all_facts {
-        let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
-        let dominators = body.basic_blocks.dominators();
-        let mut ig = InvalidationGenerator {
-            all_facts,
-            borrow_set,
-            tcx,
-            location_table,
-            body: body,
-            dominators,
-        };
-        ig.visit_body(body);
-    }
+    let dominators = body.basic_blocks.dominators();
+    let mut visitor =
+        LoanInvalidationsGenerator { all_facts, borrow_set, tcx, location_table, body, dominators };
+    visitor.visit_body(body);
 }
 
-struct InvalidationGenerator<'cx, 'tcx> {
+struct LoanInvalidationsGenerator<'cx, 'tcx> {
     tcx: TyCtxt<'tcx>,
     all_facts: &'cx mut AllFacts,
     location_table: &'cx LocationTable,
@@ -52,7 +39,7 @@ struct InvalidationGenerator<'cx, 'tcx> {
 
 /// Visits the whole MIR and generates `invalidates()` facts.
 /// Most of the code implementing this was stolen from `borrow_check/mod.rs`.
-impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
+impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
         self.check_activations(location);
 
@@ -214,7 +201,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
+impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> {
     /// Simulates mutation of a place.
     fn mutate_place(&mut self, location: Location, place: Place<'tcx>, kind: AccessDepth) {
         self.access_place(
@@ -348,20 +335,16 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
         rw: ReadOrWrite,
     ) {
         debug!(
-            "invalidation::check_access_for_conflict(location={:?}, place={:?}, sd={:?}, \
-             rw={:?})",
+            "check_access_for_conflict(location={:?}, place={:?}, sd={:?}, rw={:?})",
             location, place, sd, rw,
         );
-        let tcx = self.tcx;
-        let body = self.body;
-        let borrow_set = self.borrow_set;
         each_borrow_involving_path(
             self,
-            tcx,
-            body,
+            self.tcx,
+            self.body,
             location,
             (sd, place),
-            borrow_set,
+            self.borrow_set,
             |_| true,
             |this, borrow_index, borrow| {
                 match (rw, borrow.kind) {
diff --git a/compiler/rustc_borrowck/src/polonius/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/loan_kills.rs
new file mode 100644
index 00000000000..5df94383702
--- /dev/null
+++ b/compiler/rustc_borrowck/src/polonius/loan_kills.rs
@@ -0,0 +1,147 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{
+    Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind,
+    Terminator, TerminatorKind,
+};
+use rustc_middle::ty::TyCtxt;
+
+use crate::{borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict};
+
+/// Emit `loan_killed_at` and `cfg_edge` facts at the same time.
+pub(super) fn emit_loan_kills<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    all_facts: &mut AllFacts,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+) {
+    let mut visitor = LoanKillsGenerator { borrow_set, tcx, location_table, all_facts, body };
+    for (bb, data) in body.basic_blocks.iter_enumerated() {
+        visitor.visit_basic_block_data(bb, data);
+    }
+}
+
+struct LoanKillsGenerator<'cx, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    all_facts: &'cx mut AllFacts,
+    location_table: &'cx LocationTable,
+    borrow_set: &'cx BorrowSet<'tcx>,
+    body: &'cx Body<'tcx>,
+}
+
+impl<'cx, 'tcx> Visitor<'tcx> for LoanKillsGenerator<'cx, 'tcx> {
+    fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
+        // Also record CFG facts here.
+        self.all_facts.cfg_edge.push((
+            self.location_table.start_index(location),
+            self.location_table.mid_index(location),
+        ));
+
+        self.all_facts.cfg_edge.push((
+            self.location_table.mid_index(location),
+            self.location_table.start_index(location.successor_within_block()),
+        ));
+
+        // If there are borrows on this now dead local, we need to record them as `killed`.
+        if let StatementKind::StorageDead(local) = statement.kind {
+            self.record_killed_borrows_for_local(local, location);
+        }
+
+        self.super_statement(statement, location);
+    }
+
+    fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
+        // When we see `X = ...`, then kill borrows of
+        // `(*X).foo` and so forth.
+        self.record_killed_borrows_for_place(*place, location);
+        self.super_assign(place, rvalue, location);
+    }
+
+    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
+        // Also record CFG facts here.
+        self.all_facts.cfg_edge.push((
+            self.location_table.start_index(location),
+            self.location_table.mid_index(location),
+        ));
+
+        let successor_blocks = terminator.successors();
+        self.all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
+        for successor_block in successor_blocks {
+            self.all_facts.cfg_edge.push((
+                self.location_table.mid_index(location),
+                self.location_table.start_index(successor_block.start_location()),
+            ));
+        }
+
+        // A `Call` terminator's return value can be a local which has borrows,
+        // so we need to record those as `killed` as well.
+        if let TerminatorKind::Call { destination, .. } = terminator.kind {
+            self.record_killed_borrows_for_place(destination, location);
+        }
+
+        self.super_terminator(terminator, location);
+    }
+}
+
+impl<'tcx> LoanKillsGenerator<'_, 'tcx> {
+    /// Records the borrows on the specified place as `killed`. For example, when assigning to a
+    /// local, or on a call's return destination.
+    fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
+        // Depending on the `Place` we're killing:
+        // - if it's a local, or a single deref of a local,
+        //   we kill all the borrows on the local.
+        // - if it's a deeper projection, we have to filter which
+        //   of the borrows are killed: the ones whose `borrowed_place`
+        //   conflicts with the `place`.
+        match place.as_ref() {
+            PlaceRef { local, projection: &[] }
+            | PlaceRef { local, projection: &[ProjectionElem::Deref] } => {
+                debug!(
+                    "Recording `killed` facts for borrows of local={:?} at location={:?}",
+                    local, location
+                );
+
+                self.record_killed_borrows_for_local(local, location);
+            }
+
+            PlaceRef { local, projection: &[.., _] } => {
+                // Kill conflicting borrows of the innermost local.
+                debug!(
+                    "Recording `killed` facts for borrows of \
+                            innermost projected local={:?} at location={:?}",
+                    local, location
+                );
+
+                if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
+                    for &borrow_index in borrow_indices {
+                        let places_conflict = places_conflict::places_conflict(
+                            self.tcx,
+                            self.body,
+                            self.borrow_set[borrow_index].borrowed_place,
+                            place,
+                            places_conflict::PlaceConflictBias::NoOverlap,
+                        );
+
+                        if places_conflict {
+                            let location_index = self.location_table.mid_index(location);
+                            self.all_facts.loan_killed_at.push((borrow_index, location_index));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /// Records the borrows on the specified local as `killed`.
+    fn record_killed_borrows_for_local(&mut self, local: Local, location: Location) {
+        if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
+            let location_index = self.location_table.mid_index(location);
+            self.all_facts.loan_killed_at.reserve(borrow_indices.len());
+            for &borrow_index in borrow_indices {
+                self.all_facts.loan_killed_at.push((borrow_index, location_index));
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs
new file mode 100644
index 00000000000..40126d50d57
--- /dev/null
+++ b/compiler/rustc_borrowck/src/polonius/mod.rs
@@ -0,0 +1,188 @@
+//! Functions dedicated to fact generation for the `-Zpolonius=legacy` datalog implementation.
+//!
+//! Will be removed in the future, once the in-tree `-Zpolonius=next` implementation reaches feature
+//! parity.
+
+use rustc_middle::mir::{Body, LocalKind, Location, START_BLOCK};
+use rustc_middle::ty::TyCtxt;
+use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
+
+use crate::borrow_set::BorrowSet;
+use crate::facts::AllFacts;
+use crate::location::LocationTable;
+use crate::type_check::free_region_relations::UniversalRegionRelations;
+use crate::universal_regions::UniversalRegions;
+
+mod loan_invalidations;
+mod loan_kills;
+
+/// When requested, emit most of the facts needed by polonius:
+/// - moves and assignments
+/// - universal regions and their relations
+/// - CFG points and edges
+/// - loan kills
+/// - loan invalidations
+///
+/// The rest of the facts are emitted during typeck and liveness.
+pub(crate) fn emit_facts<'tcx>(
+    all_facts: &mut Option<AllFacts>,
+    tcx: TyCtxt<'tcx>,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+    move_data: &MoveData<'_>,
+    universal_regions: &UniversalRegions<'_>,
+    universal_region_relations: &UniversalRegionRelations<'_>,
+) {
+    let Some(all_facts) = all_facts else {
+        // We don't do anything if there are no facts to fill.
+        return;
+    };
+    let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
+    emit_move_facts(all_facts, move_data, location_table, body);
+    emit_universal_region_facts(
+        all_facts,
+        borrow_set,
+        &universal_regions,
+        &universal_region_relations,
+    );
+    emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set);
+    emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set);
+}
+
+/// Emit facts needed for move/init analysis: moves and assignments.
+fn emit_move_facts(
+    all_facts: &mut AllFacts,
+    move_data: &MoveData<'_>,
+    location_table: &LocationTable,
+    body: &Body<'_>,
+) {
+    all_facts
+        .path_is_var
+        .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(l, r)| (r, l)));
+
+    for (child, move_path) in move_data.move_paths.iter_enumerated() {
+        if let Some(parent) = move_path.parent {
+            all_facts.child_path.push((child, parent));
+        }
+    }
+
+    let fn_entry_start =
+        location_table.start_index(Location { block: START_BLOCK, statement_index: 0 });
+
+    // initialized_at
+    for init in move_data.inits.iter() {
+        match init.location {
+            InitLocation::Statement(location) => {
+                let block_data = &body[location.block];
+                let is_terminator = location.statement_index == block_data.statements.len();
+
+                if is_terminator && init.kind == InitKind::NonPanicPathOnly {
+                    // We are at the terminator of an init that has a panic path,
+                    // and where the init should not happen on panic
+
+                    for successor in block_data.terminator().successors() {
+                        if body[successor].is_cleanup {
+                            continue;
+                        }
+
+                        // The initialization happened in (or rather, when arriving at)
+                        // the successors, but not in the unwind block.
+                        let first_statement = Location { block: successor, statement_index: 0 };
+                        all_facts
+                            .path_assigned_at_base
+                            .push((init.path, location_table.start_index(first_statement)));
+                    }
+                } else {
+                    // In all other cases, the initialization just happens at the
+                    // midpoint, like any other effect.
+                    all_facts
+                        .path_assigned_at_base
+                        .push((init.path, location_table.mid_index(location)));
+                }
+            }
+            // Arguments are initialized on function entry
+            InitLocation::Argument(local) => {
+                assert!(body.local_kind(local) == LocalKind::Arg);
+                all_facts.path_assigned_at_base.push((init.path, fn_entry_start));
+            }
+        }
+    }
+
+    for (local, path) in move_data.rev_lookup.iter_locals_enumerated() {
+        if body.local_kind(local) != LocalKind::Arg {
+            // Non-arguments start out deinitialised; we simulate this with an
+            // initial move:
+            all_facts.path_moved_at_base.push((path, fn_entry_start));
+        }
+    }
+
+    // moved_out_at
+    // deinitialisation is assumed to always happen!
+    all_facts
+        .path_moved_at_base
+        .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source))));
+}
+
+/// Emit universal regions facts, and their relations.
+fn emit_universal_region_facts(
+    all_facts: &mut AllFacts,
+    borrow_set: &BorrowSet<'_>,
+    universal_regions: &UniversalRegions<'_>,
+    universal_region_relations: &UniversalRegionRelations<'_>,
+) {
+    // 1: universal regions are modeled in Polonius as a pair:
+    // - the universal region vid itself.
+    // - a "placeholder loan" associated to this universal region. Since they don't exist in
+    //   the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
+    //   added to the existing number of loans, as if they succeeded them in the set.
+    //
+    all_facts.universal_region.extend(universal_regions.universal_regions());
+    let borrow_count = borrow_set.len();
+    debug!(
+        "emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}",
+        universal_regions.len(),
+        borrow_count
+    );
+
+    for universal_region in universal_regions.universal_regions() {
+        let universal_region_idx = universal_region.index();
+        let placeholder_loan_idx = borrow_count + universal_region_idx;
+        all_facts.placeholder.push((universal_region, placeholder_loan_idx.into()));
+    }
+
+    // 2: the universal region relations `outlives` constraints are emitted as
+    //  `known_placeholder_subset` facts.
+    for (fr1, fr2) in universal_region_relations.known_outlives() {
+        if fr1 != fr2 {
+            debug!(
+                "emit_universal_region_facts: emitting polonius `known_placeholder_subset` \
+                     fr1={:?}, fr2={:?}",
+                fr1, fr2
+            );
+            all_facts.known_placeholder_subset.push((fr1, fr2));
+        }
+    }
+}
+
+/// Emit facts about loan invalidations.
+fn emit_loan_invalidations_facts<'tcx>(
+    all_facts: &mut AllFacts,
+    tcx: TyCtxt<'tcx>,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+) {
+    loan_invalidations::emit_loan_invalidations(tcx, all_facts, location_table, body, borrow_set);
+}
+
+/// Emit facts about CFG points and edges, as well as locations where loans are killed.
+fn emit_cfg_and_loan_kills_facts<'tcx>(
+    all_facts: &mut AllFacts,
+    tcx: TyCtxt<'tcx>,
+    location_table: &LocationTable,
+    body: &Body<'tcx>,
+    borrow_set: &BorrowSet<'tcx>,
+) {
+    loan_kills::emit_loan_kills(tcx, all_facts, location_table, body, borrow_set);
+}
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 1c082b7a56c..b308cd82e54 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -7,7 +7,6 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::CRATE_DEF_ID;
-use rustc_index::bit_set::SparseBitMatrix;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_infer::infer::outlives::test_type_match;
 use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
@@ -31,8 +30,8 @@ use crate::{
     nll::PoloniusOutput,
     region_infer::reverse_sccs::ReverseSccGraph,
     region_infer::values::{
-        LivenessValues, PlaceholderIndices, PointIndex, RegionElement, RegionValueElements,
-        RegionValues, ToElementIndex,
+        LivenessValues, PlaceholderIndices, RegionElement, RegionValueElements, RegionValues,
+        ToElementIndex,
     },
     type_check::{free_region_relations::UniversalRegionRelations, Locations},
     universal_regions::UniversalRegions,
@@ -120,9 +119,6 @@ pub struct RegionInferenceContext<'tcx> {
     /// Information about how the universally quantified regions in
     /// scope on this function relate to one another.
     universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
-
-    /// The set of loans that are live at a given point in the CFG, when using `-Zpolonius=next`.
-    live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
 }
 
 /// Each time that `apply_member_constraint` is successful, it appends
@@ -335,7 +331,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         type_tests: Vec<TypeTest<'tcx>>,
         liveness_constraints: LivenessValues,
         elements: &Rc<RegionValueElements>,
-        live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
     ) -> Self {
         debug!("universal_regions: {:#?}", universal_regions);
         debug!("outlives constraints: {:#?}", outlives_constraints);
@@ -389,7 +384,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             type_tests,
             universal_regions,
             universal_region_relations,
-            live_loans,
         };
 
         result.init_free_and_bound_regions();
@@ -2325,7 +2319,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// Note: for now, the sets of live loans is only available when using `-Zpolonius=next`.
     pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, location: Location) -> bool {
         let point = self.liveness_constraints.point_from_location(location);
-        self.live_loans.contains(point, loan_idx)
+        self.liveness_constraints.is_loan_live_at(loan_idx, point)
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index 41ae65268f2..dc3ee849d00 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -11,6 +11,8 @@ use rustc_middle::ty::{self, RegionVid};
 use std::fmt::Debug;
 use std::rc::Rc;
 
+use crate::dataflow::BorrowIndex;
+
 /// Maps between a `Location` and a `PointIndex` (and vice versa).
 pub(crate) struct RegionValueElements {
     /// For each basic block, how many points are contained within?
@@ -120,14 +122,45 @@ pub(crate) enum RegionElement {
 /// Records the CFG locations where each region is live. When we initially compute liveness, we use
 /// an interval matrix storing liveness ranges for each region-vid.
 pub(crate) struct LivenessValues {
+    /// The map from locations to points.
     elements: Rc<RegionValueElements>,
+
+    /// For each region: the points where it is live.
     points: SparseIntervalMatrix<RegionVid, PointIndex>,
+
+    /// When using `-Zpolonius=next`, for each point: the loans flowing into the live regions at
+    /// that point.
+    pub(crate) loans: Option<LiveLoans>,
+}
+
+/// Data used to compute the loans that are live at a given point in the CFG, when using
+/// `-Zpolonius=next`.
+pub(crate) struct LiveLoans {
+    /// The set of loans that flow into a given region. When individual regions are marked as live
+    /// in the CFG, these inflowing loans are recorded as live.
+    pub(crate) inflowing_loans: SparseBitMatrix<RegionVid, BorrowIndex>,
+
+    /// The set of loans that are live at a given point in the CFG.
+    pub(crate) live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
+}
+
+impl LiveLoans {
+    pub(crate) fn new(num_loans: usize) -> Self {
+        LiveLoans {
+            live_loans: SparseBitMatrix::new(num_loans),
+            inflowing_loans: SparseBitMatrix::new(num_loans),
+        }
+    }
 }
 
 impl LivenessValues {
     /// Create an empty map of regions to locations where they're live.
     pub(crate) fn new(elements: Rc<RegionValueElements>) -> Self {
-        Self { points: SparseIntervalMatrix::new(elements.num_points), elements }
+        LivenessValues {
+            points: SparseIntervalMatrix::new(elements.num_points),
+            elements,
+            loans: None,
+        }
     }
 
     /// Iterate through each region that has a value in this set.
@@ -140,12 +173,30 @@ impl LivenessValues {
         debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
         let point = self.elements.point_from_location(location);
         self.points.insert(region, point);
+
+        // When available, record the loans flowing into this region as live at the given point.
+        if let Some(loans) = self.loans.as_mut() {
+            if let Some(inflowing) = loans.inflowing_loans.row(region) {
+                loans.live_loans.union_row(point, inflowing);
+            }
+        }
     }
 
     /// Records `region` as being live at all the given `points`.
     pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) {
         debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
         self.points.union_row(region, points);
+
+        // When available, record the loans flowing into this region as live at the given points.
+        if let Some(loans) = self.loans.as_mut() {
+            if let Some(inflowing) = loans.inflowing_loans.row(region) {
+                if !inflowing.is_empty() {
+                    for point in points.iter() {
+                        loans.live_loans.union_row(point, inflowing);
+                    }
+                }
+            }
+        }
     }
 
     /// Records `region` as being live at all the control-flow points.
@@ -185,6 +236,15 @@ impl LivenessValues {
     pub(crate) fn point_from_location(&self, location: Location) -> PointIndex {
         self.elements.point_from_location(location)
     }
+
+    /// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`.
+    pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, point: PointIndex) -> bool {
+        self.loans
+            .as_ref()
+            .expect("Accessing live loans requires `-Zpolonius=next`")
+            .live_loans
+            .contains(point, loan_idx)
+    }
 }
 
 /// Maps from `ty::PlaceholderRegion` values that are used in the rest of
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 28cc8be8ac9..8e141bb3864 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -77,7 +77,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             if argument_index + 1 >= body.local_decls.len() {
                 self.tcx()
                     .sess
-                    .delay_span_bug(body.span, "found more normalized_input_ty than local_decls");
+                    .span_delayed_bug(body.span, "found more normalized_input_ty than local_decls");
                 break;
             }
 
@@ -101,10 +101,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         );
 
         // We will not have a universal_regions.yield_ty if we yield (by accident)
-        // outside of a coroutine and return an `impl Trait`, so emit a delay_span_bug
+        // outside of a coroutine and return an `impl Trait`, so emit a span_delayed_bug
         // because we don't want to panic in an assert here if we've already got errors.
         if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() {
-            self.tcx().sess.delay_span_bug(
+            self.tcx().sess.span_delayed_bug(
                 body.span,
                 format!(
                     "Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})",
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index a970dadc479..dc4695fd2b0 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -1,7 +1,9 @@
 use itertools::{Either, Itertools};
 use rustc_data_structures::fx::FxHashSet;
-use rustc_middle::mir::{Body, Local};
-use rustc_middle::ty::{RegionVid, TyCtxt};
+use rustc_middle::mir::visit::{TyContext, Visitor};
+use rustc_middle::mir::{Body, Local, Location, SourceInfo};
+use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt};
 use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
 use rustc_mir_dataflow::move_paths::MoveData;
 use rustc_mir_dataflow::ResultsCursor;
@@ -11,7 +13,7 @@ use crate::{
     constraints::OutlivesConstraintSet,
     facts::{AllFacts, AllFactsExt},
     location::LocationTable,
-    region_infer::values::RegionValueElements,
+    region_infer::values::{LivenessValues, RegionValueElements},
     universal_regions::UniversalRegions,
 };
 
@@ -65,6 +67,14 @@ pub(super) fn generate<'mir, 'tcx>(
         boring_locals,
         polonius_drop_used,
     );
+
+    // Mark regions that should be live where they appear within rvalues or within a call: like
+    // args, regions, and types.
+    record_regular_live_regions(
+        typeck.tcx(),
+        &mut typeck.borrowck_context.constraints.liveness_constraints,
+        body,
+    );
 }
 
 // The purpose of `compute_relevant_live_locals` is to define the subset of `Local`
@@ -132,3 +142,71 @@ fn regions_that_outlive_free_regions<'tcx>(
     // Return the final set of things we visited.
     outlives_free_region
 }
+
+/// Some variables are "regular live" at `location` -- i.e., they may be used later. This means that
+/// all regions appearing in their type must be live at `location`.
+fn record_regular_live_regions<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    liveness_constraints: &mut LivenessValues,
+    body: &Body<'tcx>,
+) {
+    let mut visitor = LiveVariablesVisitor { tcx, liveness_constraints };
+    for (bb, data) in body.basic_blocks.iter_enumerated() {
+        visitor.visit_basic_block_data(bb, data);
+    }
+}
+
+/// Visitor looking for regions that should be live within rvalues or calls.
+struct LiveVariablesVisitor<'cx, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    liveness_constraints: &'cx mut LivenessValues,
+}
+
+impl<'cx, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'cx, 'tcx> {
+    /// We sometimes have `args` within an rvalue, or within a
+    /// call. Make them live at the location where they appear.
+    fn visit_args(&mut self, args: &GenericArgsRef<'tcx>, location: Location) {
+        self.record_regions_live_at(*args, location);
+        self.super_args(args);
+    }
+
+    /// We sometimes have `region`s within an rvalue, or within a
+    /// call. Make them live at the location where they appear.
+    fn visit_region(&mut self, region: Region<'tcx>, location: Location) {
+        self.record_regions_live_at(region, location);
+        self.super_region(region);
+    }
+
+    /// We sometimes have `ty`s within an rvalue, or within a
+    /// call. Make them live at the location where they appear.
+    fn visit_ty(&mut self, ty: Ty<'tcx>, ty_context: TyContext) {
+        match ty_context {
+            TyContext::ReturnTy(SourceInfo { span, .. })
+            | TyContext::YieldTy(SourceInfo { span, .. })
+            | TyContext::UserTy(span)
+            | TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => {
+                span_bug!(span, "should not be visiting outside of the CFG: {:?}", ty_context);
+            }
+            TyContext::Location(location) => {
+                self.record_regions_live_at(ty, location);
+            }
+        }
+
+        self.super_ty(ty);
+    }
+}
+
+impl<'cx, 'tcx> LiveVariablesVisitor<'cx, 'tcx> {
+    /// Some variable is "regular live" at `location` -- i.e., it may be used later. This means that
+    /// all regions appearing in the type of `value` must be live at `location`.
+    fn record_regions_live_at<T>(&mut self, value: T, location: Location)
+    where
+        T: TypeVisitable<TyCtxt<'tcx>>,
+    {
+        debug!("record_regions_live_at(value={:?}, location={:?})", value, location);
+        self.tcx.for_each_free_region(&value, |live_region| {
+            let live_region_vid = live_region.as_var();
+            self.liveness_constraints.add_location(live_region_vid, location);
+        });
+    }
+}
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 02ccf928d8e..c718d57bec3 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -1,12 +1,12 @@
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::graph::WithSuccessors;
-use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix};
+use rustc_index::bit_set::HybridBitSet;
 use rustc_index::interval::IntervalSet;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::for_liveness;
 use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
 use rustc_middle::traits::query::DropckOutlivesResult;
-use rustc_middle::ty::{RegionVid, Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
 use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
@@ -16,9 +16,8 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
 use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex};
 use rustc_mir_dataflow::ResultsCursor;
 
-use crate::dataflow::BorrowIndex;
 use crate::{
-    region_infer::values::{self, PointIndex, RegionValueElements},
+    region_infer::values::{self, LiveLoans, PointIndex, RegionValueElements},
     type_check::liveness::local_use_map::LocalUseMap,
     type_check::liveness::polonius,
     type_check::NormalizeLocation,
@@ -49,22 +48,17 @@ pub(super) fn trace<'mir, 'tcx>(
     boring_locals: Vec<Local>,
     polonius_drop_used: Option<Vec<(Local, Location)>>,
 ) {
-    debug!("trace()");
-
     let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body);
 
     // When using `-Zpolonius=next`, compute the set of loans that can reach a given region.
-    let num_loans = typeck.borrowck_context.borrow_set.len();
-    let mut inflowing_loans = SparseBitMatrix::new(num_loans);
     if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() {
-        let borrowck_context = &typeck.borrowck_context;
+        let borrowck_context = &mut typeck.borrowck_context;
         let borrow_set = &borrowck_context.borrow_set;
-        let constraint_set = &borrowck_context.constraints.outlives_constraints;
-
-        let num_region_vars = typeck.infcx.num_region_vars();
-        let graph = constraint_set.graph(num_region_vars);
+        let mut live_loans = LiveLoans::new(borrow_set.len());
+        let outlives_constraints = &borrowck_context.constraints.outlives_constraints;
+        let graph = outlives_constraints.graph(typeck.infcx.num_region_vars());
         let region_graph =
-            graph.region_graph(constraint_set, borrowck_context.universal_regions.fr_static);
+            graph.region_graph(outlives_constraints, borrowck_context.universal_regions.fr_static);
 
         // Traverse each issuing region's constraints, and record the loan as flowing into the
         // outlived region.
@@ -75,9 +69,13 @@ pub(super) fn trace<'mir, 'tcx>(
                     continue;
                 }
 
-                inflowing_loans.insert(succ, loan);
+                live_loans.inflowing_loans.insert(succ, loan);
             }
         }
+
+        // Store the inflowing loans in the liveness constraints: they will be used to compute live
+        // loans when liveness data is recorded there.
+        borrowck_context.constraints.liveness_constraints.loans = Some(live_loans);
     };
 
     let cx = LivenessContext {
@@ -88,7 +86,6 @@ pub(super) fn trace<'mir, 'tcx>(
         local_use_map,
         move_data,
         drop_data: FxIndexMap::default(),
-        inflowing_loans,
     };
 
     let mut results = LivenessResults::new(cx);
@@ -126,9 +123,6 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
     /// Index indicating where each variable is assigned, used, or
     /// dropped.
     local_use_map: &'me LocalUseMap,
-
-    /// Set of loans that flow into a given region, when using `-Zpolonius=next`.
-    inflowing_loans: SparseBitMatrix<RegionVid, BorrowIndex>,
 }
 
 struct DropData<'tcx> {
@@ -519,14 +513,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
         live_at: &IntervalSet<PointIndex>,
     ) {
         debug!("add_use_live_facts_for(value={:?})", value);
-
-        Self::make_all_regions_live(
-            self.elements,
-            self.typeck,
-            value,
-            live_at,
-            &self.inflowing_loans,
-        );
+        Self::make_all_regions_live(self.elements, self.typeck, value, live_at);
     }
 
     /// Some variable with type `live_ty` is "drop live" at `location`
@@ -577,14 +564,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
         // All things in the `outlives` array may be touched by
         // the destructor and must be live at this point.
         for &kind in &drop_data.dropck_result.kinds {
-            Self::make_all_regions_live(
-                self.elements,
-                self.typeck,
-                kind,
-                live_at,
-                &self.inflowing_loans,
-            );
-
+            Self::make_all_regions_live(self.elements, self.typeck, kind, live_at);
             polonius::add_drop_of_var_derefs_origin(self.typeck, dropped_local, &kind);
         }
     }
@@ -594,7 +574,6 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
         typeck: &mut TypeChecker<'_, 'tcx>,
         value: impl TypeVisitable<TyCtxt<'tcx>>,
         live_at: &IntervalSet<PointIndex>,
-        inflowing_loans: &SparseBitMatrix<RegionVid, BorrowIndex>,
     ) {
         debug!("make_all_regions_live(value={:?})", value);
         debug!(
@@ -602,12 +581,6 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
             values::pretty_print_points(elements, live_at.iter()),
         );
 
-        // When using `-Zpolonius=next`, we want to record the loans that flow into this value's
-        // regions as being live at the given `live_at` points: this will be used to compute the
-        // location where a loan goes out of scope.
-        let num_loans = typeck.borrowck_context.borrow_set.len();
-        let value_loans = &mut HybridBitSet::new_empty(num_loans);
-
         value.visit_with(&mut for_liveness::FreeRegionsVisitor {
             tcx: typeck.tcx(),
             param_env: typeck.param_env,
@@ -619,21 +592,8 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
                     .constraints
                     .liveness_constraints
                     .add_points(live_region_vid, live_at);
-
-                // There can only be inflowing loans for this region when we are using
-                // `-Zpolonius=next`.
-                if let Some(inflowing) = inflowing_loans.row(live_region_vid) {
-                    value_loans.union(inflowing);
-                }
             },
         });
-
-        // Record the loans reaching the value.
-        if !value_loans.is_empty() {
-            for point in live_at.iter() {
-                typeck.borrowck_context.live_loans.union_row(point, value_loans);
-            }
-        }
     }
 
     fn compute_drop_data(
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index d4fd1a3cf2a..ecc9905e33e 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -14,7 +14,6 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::lang_items::LangItem;
-use rustc_index::bit_set::SparseBitMatrix;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
@@ -51,8 +50,6 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
 use rustc_mir_dataflow::move_paths::MoveData;
 use rustc_mir_dataflow::ResultsCursor;
 
-use crate::dataflow::BorrowIndex;
-use crate::region_infer::values::PointIndex;
 use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst};
 use crate::{
     borrow_set::BorrowSet,
@@ -166,9 +163,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
 
     debug!(?normalized_inputs_and_output);
 
-    // When using `-Zpolonius=next`, liveness will record the set of live loans per point.
-    let mut live_loans = SparseBitMatrix::new(borrow_set.len());
-
     let mut borrowck_context = BorrowCheckContext {
         universal_regions,
         location_table,
@@ -176,7 +170,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
         all_facts,
         constraints: &mut constraints,
         upvars,
-        live_loans: &mut live_loans,
     };
 
     let mut checker = TypeChecker::new(
@@ -232,7 +225,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
             let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
             trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
             if hidden_type.has_non_region_infer() {
-                let reported = infcx.tcx.sess.delay_span_bug(
+                let reported = infcx.tcx.sess.span_delayed_bug(
                     decl.hidden_type.span,
                     format!("could not resolve {:#?}", hidden_type.ty.kind()),
                 );
@@ -243,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
         })
         .collect();
 
-    MirTypeckResults { constraints, universal_region_relations, opaque_type_values, live_loans }
+    MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
 }
 
 fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
@@ -274,9 +267,9 @@ fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
 #[track_caller]
 fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: String) {
     // We sometimes see MIR failures (notably predicate failures) due to
-    // the fact that we check rvalue sized predicates here. So use `delay_span_bug`
+    // the fact that we check rvalue sized predicates here. So use `span_delayed_bug`
     // to avoid reporting bugs in those cases.
-    tcx.sess.diagnostic().delay_span_bug(span, msg);
+    tcx.sess.diagnostic().span_delayed_bug(span, msg);
 }
 
 enum FieldAccessError {
@@ -858,10 +851,6 @@ struct BorrowCheckContext<'a, 'tcx> {
     borrow_set: &'a BorrowSet<'tcx>,
     pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
     upvars: &'a [&'a ty::CapturedPlace<'tcx>],
-
-    /// The set of loans that are live at a given point in the CFG, filled in by `liveness::trace`,
-    /// when using `-Zpolonius=next`.
-    pub(crate) live_loans: &'a mut SparseBitMatrix<PointIndex, BorrowIndex>,
 }
 
 /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions
@@ -870,9 +859,6 @@ pub(crate) struct MirTypeckResults<'tcx> {
     pub(crate) constraints: MirTypeckRegionConstraints<'tcx>,
     pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
     pub(crate) opaque_type_values: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
-
-    /// The set of loans that are live at a given point in the CFG, when using `-Zpolonius=next`.
-    pub(crate) live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
 }
 
 /// A collection of region constraints that must be satisfied for the
@@ -1082,7 +1068,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         );
 
         if result.is_err() {
-            self.infcx.tcx.sess.delay_span_bug(
+            self.infcx.tcx.sess.span_delayed_bug(
                 self.body.span,
                 "failed re-defining predefined opaques in mir typeck",
             );
diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
index 070d50708ff..e13d217ef01 100644
--- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
+++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs
@@ -31,10 +31,7 @@ pub fn expand(
     {
         (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
     } else {
-        ecx.sess
-            .parse_sess
-            .span_diagnostic
-            .emit_err(errors::AllocErrorMustBeFn { span: item.span() });
+        ecx.sess.diagnostic().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
         return vec![orig_item];
     };
 
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 5499852e177..96e9584c209 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -19,8 +19,8 @@ fn invalid_type_err(
     let snippet = cx.sess.source_map().span_to_snippet(span).ok();
     match ast::LitKind::from_token_lit(token_lit) {
         Ok(ast::LitKind::CStr(_, _)) => {
-            // FIXME(c_str_literals): should concatenation of C string literals
-            // include the null bytes in the end?
+            // Avoid ambiguity in handling of terminal `NUL` by refusing to
+            // concatenate C string literals as bytes.
             cx.emit_err(errors::ConcatCStrLit { span: span });
         }
         Ok(ast::LitKind::Char(_)) => {
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 33392edf060..6dc75e3ba4c 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -34,10 +34,7 @@ pub fn expand(
     {
         (item, true, ecx.with_def_site_ctxt(ty.span))
     } else {
-        ecx.sess
-            .parse_sess
-            .span_diagnostic
-            .emit_err(errors::AllocMustStatics { span: item.span() });
+        ecx.sess.diagnostic().emit_err(errors::AllocMustStatics { span: item.span() });
         return vec![orig_item];
     };
 
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index c0055380c25..bf1e1ebf5dd 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -389,7 +389,7 @@ pub fn expand_test_or_bench(
 }
 
 fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
-    let diag = &cx.sess.parse_sess.span_diagnostic;
+    let diag = cx.sess.diagnostic();
     let msg = "the `#[test]` attribute may only be used on a non-associated function";
     let mut err = match item.map(|i| &i.kind) {
         // These were a warning before #92959 and need to continue being that to avoid breaking
@@ -466,7 +466,7 @@ fn should_ignore_message(i: &ast::Item) -> Option<Symbol> {
 fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
     match attr::find_by_name(&i.attrs, sym::should_panic) {
         Some(attr) => {
-            let sd = &cx.sess.parse_sess.span_diagnostic;
+            let sd = cx.sess.diagnostic();
 
             match attr.meta_item_list() {
                 // Handle #[should_panic(expected = "foo")]
@@ -535,7 +535,7 @@ fn check_test_signature(
     f: &ast::Fn,
 ) -> Result<(), ErrorGuaranteed> {
     let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
-    let sd = &cx.sess.parse_sess.span_diagnostic;
+    let sd = cx.sess.diagnostic();
 
     if let ast::Unsafe::Yes(span) = f.sig.header.unsafety {
         return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
@@ -579,7 +579,7 @@ fn check_bench_signature(
     // N.B., inadequate check, but we're running
     // well before resolve, can't get too deep.
     if f.sig.decl.inputs.len() != 1 {
-        return Err(cx.sess.parse_sess.span_diagnostic.emit_err(errors::BenchSig { span: i.span }));
+        return Err(cx.sess.diagnostic().emit_err(errors::BenchSig { span: i.span }));
     }
     Ok(())
 }
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 8655aeec13d..db297425b03 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -25,6 +25,7 @@ use std::ffi::{CStr, CString};
 use std::fs::File;
 use std::io;
 use std::iter;
+use std::mem::ManuallyDrop;
 use std::path::Path;
 use std::slice;
 use std::sync::Arc;
@@ -734,7 +735,7 @@ pub unsafe fn optimize_thin_module(
     let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
     let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _;
     let mut module = ModuleCodegen {
-        module_llvm: ModuleLlvm { llmod_raw, llcx, tm },
+        module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
         name: thin_module.name().to_string(),
         kind: ModuleKind::Regular,
     };
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 3a8b8e1ad11..1a567c0fce8 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -571,7 +571,6 @@ pub(crate) unsafe fn llvm_optimize(
         unroll_loops,
         config.vectorize_slp,
         config.vectorize_loop,
-        config.no_builtins,
         config.emit_lifetime_markers,
         sanitizer_options.as_ref(),
         pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
@@ -686,7 +685,6 @@ pub(crate) unsafe fn codegen(
         unsafe fn with_codegen<'ll, F, R>(
             tm: &'ll llvm::TargetMachine,
             llmod: &'ll llvm::Module,
-            no_builtins: bool,
             f: F,
         ) -> R
         where
@@ -694,7 +692,7 @@ pub(crate) unsafe fn codegen(
         {
             let cpm = llvm::LLVMCreatePassManager();
             llvm::LLVMAddAnalysisPasses(tm, cpm);
-            llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
+            llvm::LLVMRustAddLibraryInfo(cpm, llmod);
             f(cpm)
         }
 
@@ -797,7 +795,7 @@ pub(crate) unsafe fn codegen(
             } else {
                 llmod
             };
-            with_codegen(tm, llmod, config.no_builtins, |cpm| {
+            with_codegen(tm, llmod, |cpm| {
                 write_output_file(
                     diag_handler,
                     tm,
@@ -832,7 +830,7 @@ pub(crate) unsafe fn codegen(
                     (_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
                 };
 
-                with_codegen(tm, llmod, config.no_builtins, |cpm| {
+                with_codegen(tm, llmod, |cpm| {
                     write_output_file(
                         diag_handler,
                         tm,
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index f8a0423e9b1..915cf31de08 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -52,6 +52,7 @@ use rustc_span::symbol::Symbol;
 use std::any::Any;
 use std::ffi::CStr;
 use std::io::Write;
+use std::mem::ManuallyDrop;
 
 mod back {
     pub mod archive;
@@ -407,8 +408,9 @@ pub struct ModuleLlvm {
     llcx: &'static mut llvm::Context,
     llmod_raw: *const llvm::Module,
 
-    // independent from llcx and llmod_raw, resources get disposed by drop impl
-    tm: OwnedTargetMachine,
+    // This field is `ManuallyDrop` because it is important that the `TargetMachine`
+    // is disposed prior to the `Context` being disposed otherwise UAFs can occur.
+    tm: ManuallyDrop<OwnedTargetMachine>,
 }
 
 unsafe impl Send for ModuleLlvm {}
@@ -419,7 +421,11 @@ impl ModuleLlvm {
         unsafe {
             let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
             let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
-            ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, mod_name) }
+            ModuleLlvm {
+                llmod_raw,
+                llcx,
+                tm: ManuallyDrop::new(create_target_machine(tcx, mod_name)),
+            }
         }
     }
 
@@ -427,7 +433,11 @@ impl ModuleLlvm {
         unsafe {
             let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
             let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
-            ModuleLlvm { llmod_raw, llcx, tm: create_informational_target_machine(tcx.sess) }
+            ModuleLlvm {
+                llmod_raw,
+                llcx,
+                tm: ManuallyDrop::new(create_informational_target_machine(tcx.sess)),
+            }
         }
     }
 
@@ -448,7 +458,7 @@ impl ModuleLlvm {
                 }
             };
 
-            Ok(ModuleLlvm { llmod_raw, llcx, tm })
+            Ok(ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) })
         }
     }
 
@@ -460,6 +470,7 @@ impl ModuleLlvm {
 impl Drop for ModuleLlvm {
     fn drop(&mut self) {
         unsafe {
+            ManuallyDrop::drop(&mut self.tm);
             llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index d701b20e953..6c3ccc9cf0d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2163,13 +2163,8 @@ extern "C" {
         ArgsCstrBuff: *const c_char,
         ArgsCstrBuffLen: usize,
     ) -> *mut TargetMachine;
-
     pub fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine);
-    pub fn LLVMRustAddLibraryInfo<'a>(
-        PM: &PassManager<'a>,
-        M: &'a Module,
-        DisableSimplifyLibCalls: bool,
-    );
+    pub fn LLVMRustAddLibraryInfo<'a>(PM: &PassManager<'a>, M: &'a Module);
     pub fn LLVMRustWriteOutputFile<'a>(
         T: &'a TargetMachine,
         PM: &PassManager<'a>,
@@ -2191,7 +2186,6 @@ extern "C" {
         UnrollLoops: bool,
         SLPVectorize: bool,
         LoopVectorize: bool,
-        DisableSimplifyLibCalls: bool,
         EmitLifetimeMarkers: bool,
         SanitizerOptions: Option<&SanitizerOptions>,
         PGOGenPath: *const c_char,
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index be895417bbe..000b2748e4f 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -143,7 +143,7 @@ pub fn link_binary<'a>(
                 }
             }
             if sess.opts.json_artifact_notifications {
-                sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename, "link");
+                sess.diagnostic().emit_artifact_notification(&out_filename, "link");
             }
 
             if sess.prof.enabled() {
@@ -270,8 +270,14 @@ pub fn each_linked_rlib(
 
     for &cnum in crates {
         match fmts.get(cnum.as_usize() - 1) {
-            Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
-            Some(_) => {}
+            Some(&Linkage::NotLinked | &Linkage::Dynamic) => continue,
+            Some(&Linkage::IncludedFromDylib) => {
+                // We always link crate `compiler_builtins` statically. When enabling LTO, we include it as well.
+                if info.compiler_builtins != Some(cnum) {
+                    continue;
+                }
+            }
+            Some(&Linkage::Static) => {}
             None => return Err(errors::LinkRlibError::MissingFormat),
         }
         let crate_name = info.crate_name[&cnum];
@@ -520,8 +526,7 @@ fn link_staticlib<'a>(
         &codegen_results.crate_info,
         Some(CrateType::Staticlib),
         &mut |cnum, path| {
-            let lto = are_upstream_rust_objects_already_included(sess)
-                && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
+            let lto = are_upstream_rust_objects_already_included(sess);
 
             let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
             let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
@@ -1256,24 +1261,6 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
     }
 }
 
-/// Returns a boolean indicating whether the specified crate should be ignored
-/// during LTO.
-///
-/// Crates ignored during LTO are not lumped together in the "massive object
-/// file" that we create and are linked in their normal rlib states. See
-/// comments below for what crates do not participate in LTO.
-///
-/// It's unusual for a crate to not participate in LTO. Typically only
-/// compiler-specific and unstable crates have a reason to not participate in
-/// LTO.
-pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool {
-    // If our target enables builtin function lowering in LLVM then the
-    // crates providing these functions don't participate in LTO (e.g.
-    // no_builtins or compiler builtins crates).
-    !sess.target.no_builtins
-        && (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum))
-}
-
 /// This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use
 pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
     fn infer_from(
@@ -1477,7 +1464,7 @@ fn print_native_static_libs(
                 sess.emit_note(errors::StaticLibraryNativeArtifacts);
                 // Prefix for greppability
                 // Note: This must not be translated as tools are allowed to depend on this exact string.
-                sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
+                sess.note(format!("native-static-libs: {}", &lib_args.join(" ")));
             }
         }
     }
@@ -2739,10 +2726,6 @@ fn rehome_sysroot_lib_dir<'a>(sess: &'a Session, lib_dir: &Path) -> PathBuf {
 // symbols). We must continue to include the rest of the rlib, however, as
 // it may contain static native libraries which must be linked in.
 //
-// (*) Crates marked with `#![no_builtins]` don't participate in LTO and
-// their bytecode wasn't included. The object files in those libraries must
-// still be passed to the linker.
-//
 // Note, however, that if we're not doing LTO we can just pass the rlib
 // blindly to the linker (fast) because it's fine if it's not actually
 // included as we're at the end of the dependency chain.
@@ -2768,9 +2751,7 @@ fn add_static_crate<'a>(
         cmd.link_rlib(&rlib_path);
     };
 
-    if !are_upstream_rust_objects_already_included(sess)
-        || ignored_for_lto(sess, &codegen_results.crate_info, cnum)
-    {
+    if !are_upstream_rust_objects_already_included(sess) {
         link_upstream(cratepath);
         return;
     }
@@ -2784,8 +2765,6 @@ fn add_static_crate<'a>(
         let canonical_name = name.replace('-', "_");
         let upstream_rust_objects_already_included =
             are_upstream_rust_objects_already_included(sess);
-        let is_builtins =
-            sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum);
 
         let mut archive = archive_builder_builder.new_archive_builder(sess);
         if let Err(error) = archive.add_archive(
@@ -2802,9 +2781,8 @@ fn add_static_crate<'a>(
 
                 // If we're performing LTO and this is a rust-generated object
                 // file, then we don't need the object file as it's part of the
-                // LTO module. Note that `#![no_builtins]` is excluded from LTO,
-                // though, so we let that object file slide.
-                if upstream_rust_objects_already_included && is_rust_object && is_builtins {
+                // LTO module.
+                if upstream_rust_objects_already_included && is_rust_object {
                     return true;
                 }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index d716774690a..3e26e3653ea 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,9 +12,9 @@ use object::{
 
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
+use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::fs::METADATA_FILENAME;
 use rustc_metadata::EncodedMetadata;
-use rustc_session::cstore::MetadataLoader;
 use rustc_session::Session;
 use rustc_span::sym;
 use rustc_target::abi::Endian;
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index b12ac881100..5f2fad0536b 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -54,8 +54,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
     // export level, however, as they're just implementation details.
     // Down below we'll hardwire all of the symbols to the `Rust` export
     // level instead.
-    let special_runtime_crate =
-        tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE);
+    let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE);
+    let special_runtime_crate = tcx.is_panic_runtime(LOCAL_CRATE) || is_compiler_builtins;
 
     let mut reachable_non_generics: DefIdMap<_> = tcx
         .reachable_set(())
@@ -107,7 +107,11 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
         .map(|def_id| {
             // We won't link right if this symbol is stripped during LTO.
             let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
-            let used = name == "rust_eh_personality";
+            // We have to preserve the symbols of the built-in functions during LTO.
+            let is_builtin_fn = is_compiler_builtins
+                && symbol_export_level(tcx, def_id.to_def_id())
+                    .is_below_threshold(SymbolExportLevel::C);
+            let used = is_builtin_fn || name == "rust_eh_personality";
 
             let export_level = if special_runtime_crate {
                 SymbolExportLevel::Rust
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 8f17e4ea0bd..618a72272e5 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -148,23 +148,12 @@ impl ModuleConfig {
 
         let emit_obj = if !should_emit_obj {
             EmitObj::None
-        } else if sess.target.obj_is_bitcode
-            || (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
-        {
+        } else if sess.target.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
             // This case is selected if the target uses objects as bitcode, or
             // if linker plugin LTO is enabled. In the linker plugin LTO case
             // the assumption is that the final link-step will read the bitcode
             // and convert it to object code. This may be done by either the
             // native linker or rustc itself.
-            //
-            // Note, however, that the linker-plugin-lto requested here is
-            // explicitly ignored for `#![no_builtins]` crates. These crates are
-            // specifically ignored by rustc's LTO passes and wouldn't work if
-            // loaded into the linker. These crates define symbols that LLVM
-            // lowers intrinsics to, and these symbol dependencies aren't known
-            // until after codegen. As a result any crate marked
-            // `#![no_builtins]` is assumed to not participate in LTO and
-            // instead goes on to generate object code.
             EmitObj::Bitcode
         } else if need_bitcode_in_object(tcx) {
             EmitObj::ObjectCode(BitcodeSection::Full)
@@ -1037,9 +1026,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
 
     let mut each_linked_rlib_for_lto = Vec::new();
     drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
-        if link::ignored_for_lto(sess, crate_info, cnum) {
-            return;
-        }
         each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
     }));
 
@@ -1870,7 +1856,7 @@ impl SharedEmitterMain {
                     let mut err = match level {
                         Level::Error { lint: false } => sess.struct_err(msg).forget_guarantee(),
                         Level::Warning(_) => sess.struct_warn(msg),
-                        Level::Note => sess.struct_note_without_error(msg),
+                        Level::Note => sess.struct_note(msg),
                         _ => bug!("Invalid inline asm diagnostic level"),
                     };
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 1d5205ac67a..b87f4b6bf89 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -858,7 +858,6 @@ impl CrateInfo {
             local_crate_name,
             compiler_builtins,
             profiler_runtime: None,
-            is_no_builtins: Default::default(),
             native_libraries: Default::default(),
             used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(),
             crate_name: Default::default(),
@@ -885,9 +884,6 @@ impl CrateInfo {
             if tcx.is_profiler_runtime(cnum) {
                 info.profiler_runtime = Some(cnum);
             }
-            if tcx.is_no_builtins(cnum) {
-                info.is_no_builtins.insert(cnum);
-            }
         }
 
         // Handle circular dependencies in the standard library.
@@ -895,9 +891,7 @@ impl CrateInfo {
         // If global LTO is enabled then almost everything (*) is glued into a single object file,
         // so this logic is not necessary and can cause issues on some targets (due to weak lang
         // item symbols being "privatized" to that object file), so we disable it.
-        // (*) Native libs, and `#[compiler_builtins]` and `#[no_builtins]` crates are not glued,
-        // and we assume that they cannot define weak lang items. This is not currently enforced
-        // by the compiler, but that's ok because all this stuff is unstable anyway.
+        // (*) Native libs are not glued, and we assume that they cannot define weak lang items.
         let target = &tcx.sess.target;
         if !are_upstream_rust_objects_already_included(tcx.sess) {
             let missing_weak_lang_items: FxHashSet<Symbol> = info
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index e2b36fbd65b..40a985cf255 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -91,7 +91,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                 Some(tcx.fn_sig(did))
             } else {
                 tcx.sess
-                    .delay_span_bug(attr.span, "this attribute can only be applied to functions");
+                    .span_delayed_bug(attr.span, "this attribute can only be applied to functions");
                 None
             }
         };
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index bfd0a458884..cd5eb77e06e 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -25,7 +25,7 @@ extern crate tracing;
 extern crate rustc_middle;
 
 use rustc_ast as ast;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::dep_graph::WorkProduct;
@@ -157,7 +157,6 @@ pub struct CrateInfo {
     pub local_crate_name: Symbol,
     pub compiler_builtins: Option<CrateNum>,
     pub profiler_runtime: Option<CrateNum>,
-    pub is_no_builtins: FxHashSet<CrateNum>,
     pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>,
     pub crate_name: FxHashMap<CrateNum, Symbol>,
     pub used_libraries: Vec<NativeLib>,
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 35744d9a167..8e9907ed8bb 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -9,6 +9,7 @@ use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::{DynSend, DynSync};
 use rustc_errors::ErrorGuaranteed;
+use rustc_metadata::creader::MetadataLoaderDyn;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
@@ -16,7 +17,6 @@ use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_middle::util::Providers;
 use rustc_session::{
     config::{self, OutputFilenames, PrintRequest},
-    cstore::MetadataLoaderDyn,
     Session,
 };
 use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index bf1e0a37073..4934fcc75ec 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -148,7 +148,7 @@ where
             let mut err = tcx.sess.create_err(err);
 
             let msg = error.diagnostic_message();
-            error.add_args(&tcx.sess.parse_sess.span_diagnostic, &mut err);
+            error.add_args(tcx.sess.diagnostic(), &mut err);
 
             // Use *our* span to label the interp error
             err.span_label(our_span, msg);
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 4b13a3404a0..2d8ca67c3a5 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -391,7 +391,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
                 if ecx.tcx.is_ctfe_mir_available(def) {
                     Ok(ecx.tcx.mir_for_ctfe(def))
                 } else if ecx.tcx.def_kind(def) == DefKind::AssocConst {
-                    let guar = ecx.tcx.sess.delay_span_bug(
+                    let guar = ecx.tcx.sess.span_delayed_bug(
                         rustc_span::DUMMY_SP,
                         "This is likely a const item that is missing from its impl",
                     );
@@ -622,7 +622,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
                     let guard = ecx
                         .tcx
                         .sess
-                        .delay_span_bug(span, "The deny lint should have already errored");
+                        .span_delayed_bug(span, "The deny lint should have already errored");
                     throw_inval!(AlreadyReported(guard.into()));
                 }
             } else if new_steps > start && new_steps.is_power_of_two() {
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index cc8f3387238..8343dc2dd35 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -437,7 +437,7 @@ pub trait ReportErrorExt {
     {
         ty::tls::with(move |tcx| {
             let mut builder = tcx.sess.struct_allow(DiagnosticMessage::Str(String::new().into()));
-            let handler = &tcx.sess.parse_sess.span_diagnostic;
+            let handler = tcx.sess.diagnostic();
             let message = self.diagnostic_message();
             self.add_args(handler, &mut builder);
             let s = handler.eagerly_translate_to_string(message, builder.args());
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 3bdfc1db913..c0a20e51482 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -173,6 +173,9 @@ impl<Prov: Provenance> std::fmt::Debug for LocalState<'_, Prov> {
 }
 
 /// Current value of a local variable
+///
+/// This does not store the type of the local; the type is given by `body.local_decls` and can never
+/// change, so by not storing here we avoid having to maintain that as an invariant.
 #[derive(Copy, Clone, Debug)] // Miri debug-prints these
 pub(super) enum LocalValue<Prov: Provenance = AllocId> {
     /// This local is not currently alive, and cannot be used at all.
@@ -284,9 +287,9 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
             {
                 write!(f, "inside closure")
             } else {
-                // Note: this triggers a `good_path_bug` state, which means that if we ever get here
-                // we must emit a diagnostic. We should never display a `FrameInfo` unless we
-                // actually want to emit a warning or error to the user.
+                // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever
+                // get here we must emit a diagnostic. We should never display a `FrameInfo` unless
+                // we actually want to emit a warning or error to the user.
                 write!(f, "inside `{}`", self.instance)
             }
         })
@@ -300,8 +303,8 @@ impl<'tcx> FrameInfo<'tcx> {
             errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 }
         } else {
             let instance = format!("{}", self.instance);
-            // Note: this triggers a `good_path_bug` state, which means that if we ever get here
-            // we must emit a diagnostic. We should never display a `FrameInfo` unless we
+            // Note: this triggers a `good_path_delayed_bug` state, which means that if we ever get
+            // here we must emit a diagnostic. We should never display a `FrameInfo` unless we
             // actually want to emit a warning or error to the user.
             errors::FrameNote { where_: "instance", span, instance, times: 0 }
         }
@@ -470,7 +473,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         backtrace.print_backtrace();
         // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the
         // label and arguments from the InterpError.
-        let handler = &self.tcx.sess.parse_sess.span_diagnostic;
+        let handler = self.tcx.sess.diagnostic();
         #[allow(rustc::untranslatable_diagnostic)]
         let mut diag = self.tcx.sess.struct_allow("");
         let msg = e.diagnostic_message();
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 413963b2fdc..881df9b04ab 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -94,9 +94,9 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
         // If the pointer is dangling (neither in local nor global memory), we leave it
         // to validation to error -- it has the much better error messages, pointing out where
         // in the value the dangling reference lies.
-        // The `delay_span_bug` ensures that we don't forget such a check in validation.
+        // The `span_delayed_bug` ensures that we don't forget such a check in validation.
         if tcx.try_get_global_alloc(alloc_id).is_none() {
-            tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer");
+            tcx.sess.span_delayed_bug(ecx.tcx.span, "tried to intern dangling pointer");
         }
         // treat dangling pointers like other statics
         // just to stop trying to recurse into them
@@ -186,7 +186,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
                     // Validation will error (with a better message) on an invalid vtable pointer.
                     // Let validation show the error message, but make sure it *does* error.
                     tcx.sess
-                        .delay_span_bug(tcx.span, "vtables pointers cannot be integer pointers");
+                        .span_delayed_bug(tcx.span, "vtables pointers cannot be integer pointers");
                 }
             }
             // Check if we have encountered this pointer+layout combination before.
@@ -375,7 +375,7 @@ pub fn intern_const_alloc_recursive<
         match res {
             Ok(()) => {}
             Err(error) => {
-                ecx.tcx.sess.delay_span_bug(
+                ecx.tcx.sess.span_delayed_bug(
                     ecx.tcx.span,
                     format!(
                         "error during interning should later cause validation failure: {}",
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 13742ad273b..bcc42a376ea 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -248,7 +248,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
         // no need to emit duplicate errors here.
         if self.ccx.is_async() || body.coroutine.is_some() {
-            tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
+            tcx.sess.span_delayed_bug(body.span, "`async` functions cannot be `const fn`");
             return;
         }
 
@@ -357,7 +357,9 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
 
     fn check_static(&mut self, def_id: DefId, span: Span) {
         if self.tcx.is_thread_local_static(def_id) {
-            self.tcx.sess.delay_span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`");
+            self.tcx
+                .sess
+                .span_delayed_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`");
         }
         self.check_op_spanned(ops::StaticAccess, span)
     }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index 4c2492d1867..4f7e165c575 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -112,7 +112,7 @@ pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         None if is_parent_const_stable_trait(tcx, def_id) => {
             // Remove this when `#![feature(const_trait_impl)]` is stabilized,
             // returning `true` unconditionally.
-            tcx.sess.delay_span_bug(
+            tcx.sess.span_delayed_bug(
                 tcx.def_span(def_id),
                 "trait implementations cannot be const stable yet",
             );
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 3e8a0a2b7df..eaf4abf39b7 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -128,9 +128,9 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
     #[track_caller]
     fn fail(&self, location: Location, msg: impl AsRef<str>) {
         let span = self.body.source_info(location).span;
-        // We use `delay_span_bug` as we might see broken MIR when other errors have already
+        // We use `span_delayed_bug` as we might see broken MIR when other errors have already
         // occurred.
-        self.tcx.sess.diagnostic().delay_span_bug(
+        self.tcx.sess.diagnostic().span_delayed_bug(
             span,
             format!(
                 "broken MIR in {:?} ({}) at {:?}:\n{}",
@@ -571,7 +571,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
 
     fn visit_source_scope(&mut self, scope: SourceScope) {
         if self.body.source_scopes.get(scope).is_none() {
-            self.tcx.sess.diagnostic().delay_span_bug(
+            self.tcx.sess.diagnostic().span_delayed_bug(
                 self.body.span,
                 format!(
                     "broken MIR in {:?} ({}):\ninvalid source scope {:?}",
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 6af11ce8479..450e1ead0b2 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -33,10 +33,10 @@ use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
 use rustc_lint::unerased_lint_store;
+use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
 use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
 use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
-use rustc_session::cstore::MetadataLoader;
 use rustc_session::getopts::{self, Matches};
 use rustc_session::lint::{Lint, LintId};
 use rustc_session::{config, EarlyErrorHandler, Session};
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 85acf8ab5aa..3823a1707ec 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -351,18 +351,10 @@ impl<'a> DiagnosticBuilder<'a, !> {
     /// `struct_*` methods on [`Handler`].
     #[track_caller]
     pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into<DiagnosticMessage>) -> Self {
-        let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message);
-        Self::new_diagnostic_fatal(handler, diagnostic)
-    }
-
-    /// Creates a new `DiagnosticBuilder` with an already constructed
-    /// diagnostic.
-    pub(crate) fn new_diagnostic_fatal(handler: &'a Handler, diagnostic: Diagnostic) -> Self {
-        debug!("Created new diagnostic");
         Self {
             inner: DiagnosticBuilderInner {
                 state: DiagnosticBuilderState::Emittable(handler),
-                diagnostic: Box::new(diagnostic),
+                diagnostic: Box::new(Diagnostic::new_with_code(Level::Fatal, None, message)),
             },
             _marker: PhantomData,
         }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 6bd87f54140..5966fd80f97 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -431,10 +431,10 @@ struct HandlerInner {
     warn_count: usize,
     deduplicated_err_count: usize,
     emitter: Box<DynEmitter>,
-    delayed_span_bugs: Vec<DelayedDiagnostic>,
-    delayed_good_path_bugs: Vec<DelayedDiagnostic>,
+    span_delayed_bugs: Vec<DelayedDiagnostic>,
+    good_path_delayed_bugs: Vec<DelayedDiagnostic>,
     /// This flag indicates that an expected diagnostic was emitted and suppressed.
-    /// This is used for the `delayed_good_path_bugs` check.
+    /// This is used for the `good_path_delayed_bugs` check.
     suppressed_expected_diag: bool,
 
     /// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
@@ -528,7 +528,7 @@ pub struct HandlerFlags {
     /// If true, immediately emit diagnostics that would otherwise be buffered.
     /// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`)
     pub dont_buffer_diagnostics: bool,
-    /// If true, immediately print bugs registered with `delay_span_bug`.
+    /// If true, immediately print bugs registered with `span_delayed_bug`.
     /// (rustc: see `-Z report-delayed-bugs`)
     pub report_delayed_bugs: bool,
     /// Show macro backtraces.
@@ -545,20 +545,20 @@ impl Drop for HandlerInner {
         self.emit_stashed_diagnostics();
 
         if !self.has_errors() {
-            let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new());
-            self.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
+            let bugs = std::mem::replace(&mut self.span_delayed_bugs, Vec::new());
+            self.flush_delayed(bugs, "no errors encountered even though `span_delayed_bug` issued");
         }
 
-        // FIXME(eddyb) this explains what `delayed_good_path_bugs` are!
-        // They're `delayed_span_bugs` but for "require some diagnostic happened"
+        // FIXME(eddyb) this explains what `good_path_delayed_bugs` are!
+        // They're `span_delayed_bugs` but for "require some diagnostic happened"
         // instead of "require some error happened". Sadly that isn't ideal, as
         // lints can be `#[allow]`'d, potentially leading to this triggering.
         // Also, "good path" should be replaced with a better naming.
         if !self.has_any_message() && !self.suppressed_expected_diag && !std::thread::panicking() {
-            let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new());
+            let bugs = std::mem::replace(&mut self.good_path_delayed_bugs, Vec::new());
             self.flush_delayed(
                 bugs,
-                "no warnings or errors encountered even though `delayed_good_path_bugs` issued",
+                "no warnings or errors encountered even though `good_path_delayed_bugs` issued",
             );
         }
 
@@ -609,8 +609,8 @@ impl Handler {
                 deduplicated_err_count: 0,
                 deduplicated_warn_count: 0,
                 emitter,
-                delayed_span_bugs: Vec::new(),
-                delayed_good_path_bugs: Vec::new(),
+                span_delayed_bugs: Vec::new(),
+                good_path_delayed_bugs: Vec::new(),
                 suppressed_expected_diag: false,
                 taught_diagnostics: Default::default(),
                 emitted_diagnostic_codes: Default::default(),
@@ -648,7 +648,7 @@ impl Handler {
     // This is here to not allow mutation of flags;
     // as of this writing it's only used in tests in librustc_middle.
     pub fn can_emit_warnings(&self) -> bool {
-        self.inner.lock().flags.can_emit_warnings
+        self.inner.borrow_mut().flags.can_emit_warnings
     }
 
     /// Resets the diagnostic error count as well as the cached emitted diagnostics.
@@ -664,8 +664,8 @@ impl Handler {
         inner.deduplicated_warn_count = 0;
 
         // actually free the underlying memory (which `clear` would not do)
-        inner.delayed_span_bugs = Default::default();
-        inner.delayed_good_path_bugs = Default::default();
+        inner.span_delayed_bugs = Default::default();
+        inner.good_path_delayed_bugs = Default::default();
         inner.taught_diagnostics = Default::default();
         inner.emitted_diagnostic_codes = Default::default();
         inner.emitted_diagnostics = Default::default();
@@ -675,14 +675,13 @@ impl Handler {
     /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key.
     /// Retrieve a stashed diagnostic with `steal_diagnostic`.
     pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) {
-        let mut inner = self.inner.borrow_mut();
-        inner.stash((span.with_parent(None), key), diag);
+        self.inner.borrow_mut().stash((span.with_parent(None), key), diag);
     }
 
     /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key.
     pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> {
-        let mut inner = self.inner.borrow_mut();
-        inner
+        self.inner
+            .borrow_mut()
             .steal((span.with_parent(None), key))
             .map(|diag| DiagnosticBuilder::new_diagnostic(self, diag))
     }
@@ -927,10 +926,7 @@ impl Handler {
     /// Construct a builder at the `Note` level with the `msg`.
     #[rustc_lint_diagnostics]
     #[track_caller]
-    pub fn struct_note_without_error(
-        &self,
-        msg: impl Into<DiagnosticMessage>,
-    ) -> DiagnosticBuilder<'_, ()> {
+    pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
         DiagnosticBuilder::new(self, Level::Note, msg)
     }
 
@@ -970,11 +966,12 @@ impl Handler {
         span: impl Into<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
         code: DiagnosticId,
-    ) {
+    ) -> ErrorGuaranteed {
         self.emit_diag_at_span(
             Diagnostic::new_with_code(Error { lint: false }, Some(code), msg),
             span,
-        );
+        )
+        .unwrap()
     }
 
     #[rustc_lint_diagnostics]
@@ -998,20 +995,20 @@ impl Handler {
         self.inner.borrow_mut().span_bug(span, msg)
     }
 
-    /// For documentation on this, see `Session::delay_span_bug`.
+    /// For documentation on this, see `Session::span_delayed_bug`.
     #[track_caller]
-    pub fn delay_span_bug(
+    pub fn span_delayed_bug(
         &self,
         span: impl Into<MultiSpan>,
         msg: impl Into<String>,
     ) -> ErrorGuaranteed {
-        self.inner.borrow_mut().delay_span_bug(span, msg)
+        self.inner.borrow_mut().span_delayed_bug(span, msg)
     }
 
     // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
     // where the explanation of what "good path" is (also, it should be renamed).
-    pub fn delay_good_path_bug(&self, msg: impl Into<DiagnosticMessage>) {
-        self.inner.borrow_mut().delay_good_path_bug(msg)
+    pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
+        self.inner.borrow_mut().good_path_delayed_bug(msg)
     }
 
     #[track_caller]
@@ -1021,17 +1018,13 @@ impl Handler {
 
     #[track_caller]
     #[rustc_lint_diagnostics]
-    pub fn span_note_without_error(
-        &self,
-        span: impl Into<MultiSpan>,
-        msg: impl Into<DiagnosticMessage>,
-    ) {
+    pub fn span_note(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
         self.emit_diag_at_span(Diagnostic::new(Note, msg), span);
     }
 
     #[track_caller]
     #[rustc_lint_diagnostics]
-    pub fn span_note_diag(
+    pub fn struct_span_note(
         &self,
         span: Span,
         msg: impl Into<DiagnosticMessage>,
@@ -1054,12 +1047,11 @@ impl Handler {
 
     #[rustc_lint_diagnostics]
     pub fn warn(&self, msg: impl Into<DiagnosticMessage>) {
-        let mut db = DiagnosticBuilder::new(self, Warning(None), msg);
-        db.emit();
+        DiagnosticBuilder::new(self, Warning(None), msg).emit();
     }
 
     #[rustc_lint_diagnostics]
-    pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) {
+    pub fn note(&self, msg: impl Into<DiagnosticMessage>) {
         DiagnosticBuilder::new(self, Note, msg).emit();
     }
 
@@ -1085,8 +1077,8 @@ impl Handler {
             ErrorGuaranteed::unchecked_claim_error_was_emitted()
         })
     }
-    pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> {
-        self.inner.borrow().has_errors_or_delayed_span_bugs().then(|| {
+    pub fn has_errors_or_span_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
+        self.inner.borrow().has_errors_or_span_delayed_bugs().then(|| {
             #[allow(deprecated)]
             ErrorGuaranteed::unchecked_claim_error_was_emitted()
         })
@@ -1204,8 +1196,7 @@ impl Handler {
         mut diag: Diagnostic,
         sp: impl Into<MultiSpan>,
     ) -> Option<ErrorGuaranteed> {
-        let mut inner = self.inner.borrow_mut();
-        inner.emit_diagnostic(diag.set_span(sp))
+        self.inner.borrow_mut().emit_diagnostic(diag.set_span(sp))
     }
 
     pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
@@ -1273,9 +1264,9 @@ impl Handler {
     }
 
     pub fn flush_delayed(&self) {
-        let mut inner = self.inner.lock();
-        let bugs = std::mem::replace(&mut inner.delayed_span_bugs, Vec::new());
-        inner.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
+        let mut inner = self.inner.borrow_mut();
+        let bugs = std::mem::replace(&mut inner.span_delayed_bugs, Vec::new());
+        inner.flush_delayed(bugs, "no errors encountered even though `span_delayed_bug` issued");
     }
 }
 
@@ -1332,11 +1323,11 @@ impl HandlerInner {
 
         if diagnostic.level == Level::DelayedBug {
             // FIXME(eddyb) this should check for `has_errors` and stop pushing
-            // once *any* errors were emitted (and truncate `delayed_span_bugs`
+            // once *any* errors were emitted (and truncate `span_delayed_bugs`
             // when an error is first emitted, also), but maybe there's a case
             // in which that's not sound? otherwise this is really inefficient.
             let backtrace = std::backtrace::Backtrace::capture();
-            self.delayed_span_bugs
+            self.span_delayed_bugs
                 .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
 
             if !self.flags.report_delayed_bugs {
@@ -1451,7 +1442,7 @@ impl HandlerInner {
     }
 
     fn delayed_bug_count(&self) -> usize {
-        self.delayed_span_bugs.len() + self.delayed_good_path_bugs.len()
+        self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len()
     }
 
     fn print_error_count(&mut self, registry: &Registry) {
@@ -1502,18 +1493,18 @@ impl HandlerInner {
                 error_codes.sort();
                 if error_codes.len() > 1 {
                     let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
-                    self.failure(format!(
+                    self.failure_note(format!(
                         "Some errors have detailed explanations: {}{}",
                         error_codes[..limit].join(", "),
                         if error_codes.len() > 9 { "..." } else { "." }
                     ));
-                    self.failure(format!(
+                    self.failure_note(format!(
                         "For more information about an error, try \
                          `rustc --explain {}`.",
                         &error_codes[0]
                     ));
                 } else {
-                    self.failure(format!(
+                    self.failure_note(format!(
                         "For more information about this error, try \
                          `rustc --explain {}`.",
                         &error_codes[0]
@@ -1572,15 +1563,15 @@ impl HandlerInner {
     fn has_errors_or_lint_errors(&self) -> bool {
         self.has_errors() || self.lint_err_count > 0
     }
-    fn has_errors_or_delayed_span_bugs(&self) -> bool {
-        self.has_errors() || !self.delayed_span_bugs.is_empty()
+    fn has_errors_or_span_delayed_bugs(&self) -> bool {
+        self.has_errors() || !self.span_delayed_bugs.is_empty()
     }
     fn has_any_message(&self) -> bool {
         self.err_count() > 0 || self.lint_err_count > 0 || self.warn_count > 0
     }
 
     fn is_compilation_going_to_fail(&self) -> bool {
-        self.has_errors() || self.lint_err_count > 0 || !self.delayed_span_bugs.is_empty()
+        self.has_errors() || self.lint_err_count > 0 || !self.span_delayed_bugs.is_empty()
     }
 
     fn abort_if_errors(&mut self) {
@@ -1601,14 +1592,17 @@ impl HandlerInner {
         self.emit_diagnostic(diag.set_span(sp));
     }
 
-    /// For documentation on this, see `Session::delay_span_bug`.
+    /// For documentation on this, see `Session::span_delayed_bug`.
+    ///
+    /// Note: this function used to be called `delay_span_bug`. It was renamed
+    /// to match similar functions like `span_bug`, `span_err`, etc.
     #[track_caller]
-    fn delay_span_bug(
+    fn span_delayed_bug(
         &mut self,
         sp: impl Into<MultiSpan>,
         msg: impl Into<String>,
     ) -> ErrorGuaranteed {
-        // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before
+        // This is technically `self.treat_err_as_bug()` but `span_delayed_bug` is called before
         // incrementing `err_count` by one, so we need to +1 the comparing.
         // FIXME: Would be nice to increment err_count in a more coherent way.
         if self.flags.treat_err_as_bug.is_some_and(|c| {
@@ -1624,16 +1618,16 @@ impl HandlerInner {
 
     // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
     // where the explanation of what "good path" is (also, it should be renamed).
-    fn delay_good_path_bug(&mut self, msg: impl Into<DiagnosticMessage>) {
+    fn good_path_delayed_bug(&mut self, msg: impl Into<DiagnosticMessage>) {
         let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
         if self.flags.report_delayed_bugs {
             self.emit_diagnostic(&mut diagnostic);
         }
         let backtrace = std::backtrace::Backtrace::capture();
-        self.delayed_good_path_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
+        self.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
     }
 
-    fn failure(&mut self, msg: impl Into<DiagnosticMessage>) {
+    fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) {
         self.emit_diagnostic(&mut Diagnostic::new(FailureNote, msg));
     }
 
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 88e90a3b3d1..91f3ca1d115 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1119,7 +1119,7 @@ impl<'a> ExtCtxt<'a> {
         sp: S,
         msg: impl Into<DiagnosticMessage>,
     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
-        self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg)
+        self.sess.diagnostic().struct_span_err(sp, msg)
     }
 
     #[track_caller]
@@ -1143,15 +1143,15 @@ impl<'a> ExtCtxt<'a> {
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
-        self.sess.parse_sess.span_diagnostic.span_err(sp, msg);
+        self.sess.diagnostic().span_err(sp, msg);
     }
     #[rustc_lint_diagnostics]
     #[track_caller]
     pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
-        self.sess.parse_sess.span_diagnostic.span_warn(sp, msg);
+        self.sess.diagnostic().span_warn(sp, msg);
     }
     pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<String>) -> ! {
-        self.sess.parse_sess.span_diagnostic.span_bug(sp, msg);
+        self.sess.diagnostic().span_bug(sp, msg);
     }
     pub fn trace_macros_diag(&mut self) {
         for (span, notes) in self.expansions.iter() {
@@ -1165,7 +1165,7 @@ impl<'a> ExtCtxt<'a> {
         self.expansions.clear();
     }
     pub fn bug(&self, msg: &'static str) -> ! {
-        self.sess.parse_sess.span_diagnostic.bug(msg);
+        self.sess.diagnostic().bug(msg);
     }
     pub fn trace_macros(&self) -> bool {
         self.ecfg.trace_mac
@@ -1286,9 +1286,8 @@ pub fn expr_to_string(
 
 /// Non-fatally assert that `tts` is empty. Note that this function
 /// returns even when `tts` is non-empty, macros that *need* to stop
-/// compilation should call
-/// `cx.parse_sess.span_diagnostic.abort_if_errors()` (this should be
-/// done as rarely as possible).
+/// compilation should call `cx.diagnostic().abort_if_errors()`
+/// (this should be done as rarely as possible).
 pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) {
     if !tts.is_empty() {
         cx.emit_err(errors::TakesNoArguments { span, name });
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 1b51d80fb38..ad21a73f063 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -435,7 +435,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 invocations = mem::take(&mut undetermined_invocations);
                 force = !mem::replace(&mut progress, false);
                 if force && self.monotonic {
-                    self.cx.sess.delay_span_bug(
+                    self.cx.sess.span_delayed_bug(
                         invocations.last().unwrap().0.span(),
                         "expansion entered force mode without producing any errors",
                     );
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index 64cf9ced9c1..8f80e6e2927 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -34,7 +34,7 @@ pub(super) fn failed_to_match_macro<'cx>(
     if try_success_result.is_ok() {
         // Nonterminal parser recovery might turn failed matches into successful ones,
         // but for that it must have emitted an error already
-        tracker.cx.sess.delay_span_bug(sp, "Macro matching returned a success on the second try");
+        tracker.cx.sess.span_delayed_bug(sp, "Macro matching returned a success on the second try");
     }
 
     if let Some(result) = tracker.result {
@@ -151,7 +151,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
             Success(_) => {
                 // Nonterminal parser recovery might turn failed matches into successful ones,
                 // but for that it must have emitted an error already
-                self.cx.sess.delay_span_bug(
+                self.cx.sess.span_delayed_bug(
                     self.root_span,
                     "should not collect detailed info for successful macro match",
                 );
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index bc3f0ce5a70..19734394382 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -475,17 +475,14 @@ pub fn compile_declarative_macro(
 
                 let s = parse_failure_msg(&token);
                 let sp = token.span.substitute_dummy(def.span);
-                let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, s);
+                let mut err = sess.diagnostic().struct_span_err(sp, s);
                 err.span_label(sp, msg);
                 annotate_doc_comment(&mut err, sess.source_map(), sp);
                 err.emit();
                 return dummy_syn_ext();
             }
             Error(sp, msg) => {
-                sess.parse_sess
-                    .span_diagnostic
-                    .struct_span_err(sp.substitute_dummy(def.span), msg)
-                    .emit();
+                sess.diagnostic().struct_span_err(sp.substitute_dummy(def.span), msg).emit();
                 return dummy_syn_ext();
             }
             ErrorReported(_) => {
@@ -514,10 +511,10 @@ pub fn compile_declarative_macro(
                     valid &= check_lhs_nt_follows(&sess.parse_sess, def, &tt);
                     return tt;
                 }
-                sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
+                sess.diagnostic().span_bug(def.span, "wrong-structured lhs")
             })
             .collect::<Vec<mbe::TokenTree>>(),
-        _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
+        _ => sess.diagnostic().span_bug(def.span, "wrong-structured lhs"),
     };
 
     let rhses = match &argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] {
@@ -536,10 +533,10 @@ pub fn compile_declarative_macro(
                     .pop()
                     .unwrap();
                 }
-                sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs")
+                sess.diagnostic().span_bug(def.span, "wrong-structured rhs")
             })
             .collect::<Vec<mbe::TokenTree>>(),
-        _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"),
+        _ => sess.diagnostic().span_bug(def.span, "wrong-structured rhs"),
     };
 
     for rhs in &rhses {
@@ -595,7 +592,7 @@ pub fn compile_declarative_macro(
                     mbe::TokenTree::Delimited(_, delimited) => {
                         mbe::macro_parser::compute_locs(&delimited.tts)
                     }
-                    _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "malformed macro lhs"),
+                    _ => sess.diagnostic().span_bug(def.span, "malformed macro lhs"),
                 }
             })
             .collect()
@@ -648,10 +645,8 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool
                         iter.next();
                     }
                     let span = t.span.to(now.span);
-                    sess.span_diagnostic.span_note_without_error(
-                        span,
-                        "doc comments are ignored in matcher position",
-                    );
+                    sess.span_diagnostic
+                        .span_note(span, "doc comments are ignored in matcher position");
                 }
                 mbe::TokenTree::Sequence(_, sub_seq)
                     if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 6c6dfe53305..6a99412fc5b 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -357,7 +357,7 @@ fn parse_sep_and_kleene_op<'a>(
 fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) {
     sess.span_diagnostic
         .span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
-    sess.span_diagnostic.span_note_without_error(
+    sess.span_diagnostic.span_note(
         token.span,
         "`$$` and meta-variable expressions are not allowed inside macro parameter definitions",
     );
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 39a16259fa6..d08026b9c14 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -156,7 +156,7 @@ impl MultiItemModifier for DeriveProcMacro {
             }
         };
 
-        let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count();
+        let error_count_before = ecx.sess.diagnostic().err_count();
         let mut parser =
             rustc_parse::stream_to_parser(&ecx.sess.parse_sess, stream, Some("proc-macro derive"));
         let mut items = vec![];
@@ -179,7 +179,7 @@ impl MultiItemModifier for DeriveProcMacro {
         }
 
         // fail if there have been errors emitted
-        if ecx.sess.parse_sess.span_diagnostic.err_count() > error_count_before {
+        if ecx.sess.diagnostic().err_count() > error_count_before {
             ecx.sess.emit_err(errors::ProcMacroDeriveTokens { span });
         }
 
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 37ef4d86989..94e79144593 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -77,6 +77,8 @@ declare_features! (
     (accepted, bindings_after_at, "1.56.0", Some(65490), None),
     /// Allows empty structs and enum variants with braces.
     (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
+    /// Allows `c"foo"` literals.
+    (accepted, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
     /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
     (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
     /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 214de3ca402..9754f7acaae 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -813,7 +813,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),
     rustc_attr!(
         TEST, rustc_error, Normal,
-        template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly
+        template!(Word, List: "span_delayed_bug_from_inside_query"), WarnFollowingWordOnly
     ),
     rustc_attr!(TEST, rustc_dump_user_args, Normal, template!(Word), WarnFollowing),
     rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 8182c8779ff..dee68bff21d 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -354,8 +354,6 @@ declare_features! (
     (unstable, async_fn_track_caller, "1.73.0", Some(110011), None),
     /// Allows builtin # foo() syntax
     (unstable, builtin_syntax, "1.71.0", Some(110680), None),
-    /// Allows `c"foo"` literals.
-    (unstable, c_str_literals, "1.71.0", Some(105723), None),
     /// Treat `extern "C"` function as nounwind.
     (unstable, c_unwind, "1.52.0", Some(74990), None),
     /// Allows using C-variadics.
@@ -500,6 +498,9 @@ declare_features! (
     (incomplete, lazy_type_alias, "1.72.0", Some(112792), None),
     /// Allows `if/while p && let q = r && ...` chains.
     (unstable, let_chains, "1.37.0", Some(53667), None),
+    /// Allows using `#[link(kind = "link-arg", name = "...")]`
+    /// to pass custom arguments to the linker.
+    (unstable, link_arg_attribute, "CURRENT_RUSTC_VERSION", Some(99427), None),
     /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (unstable, lint_reasons, "1.31.0", Some(54503), None),
     /// Give access to additional metadata about declarative macro meta-variables.
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index b9a4806e6c2..fd3e6bd44e7 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -720,9 +720,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             // since we should have emitten an error for them earlier, and they will
             // not be well-formed!
             if polarity == ty::ImplPolarity::Negative {
-                self.tcx()
-                    .sess
-                    .delay_span_bug(binding.span, "negative trait bounds should not have bindings");
+                self.tcx().sess.span_delayed_bug(
+                    binding.span,
+                    "negative trait bounds should not have bindings",
+                );
                 continue;
             }
 
@@ -1419,7 +1420,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // trait reference.
                 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
                     // A cycle error occurred, most likely.
-                    let guar = tcx.sess.delay_span_bug(span, "expected cycle error");
+                    let guar = tcx.sess.span_delayed_bug(span, "expected cycle error");
                     return Err(guar);
                 };
 
@@ -2376,7 +2377,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let e = self
                     .tcx()
                     .sess
-                    .delay_span_bug(path.span, "path with `Res::Err` but no error emitted");
+                    .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
                 Ty::new_error(self.tcx(), e)
             }
diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
index 78c5809f8b4..6cb38c741b7 100644
--- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
@@ -325,7 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         false
                     });
                     if references_self {
-                        let guar = tcx.sess.delay_span_bug(
+                        let guar = tcx.sess.span_delayed_bug(
                             span,
                             "trait object projection bounds reference `Self`",
                         );
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index fbed6f33e59..56e272b14bd 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -130,7 +130,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
         for field in &def.non_enum_variant().fields {
             let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args))
             else {
-                tcx.sess.delay_span_bug(span, "could not normalize field type");
+                tcx.sess.span_delayed_bug(span, "could not normalize field type");
                 continue;
             };
 
@@ -151,7 +151,8 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                 return false;
             } else if field_ty.needs_drop(tcx, param_env) {
                 // This should never happen. But we can get here e.g. in case of name resolution errors.
-                tcx.sess.delay_span_bug(span, "we should never accept maybe-dropping union fields");
+                tcx.sess
+                    .span_delayed_bug(span, "we should never accept maybe-dropping union fields");
             }
         }
     } else {
@@ -181,7 +182,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         }
         // Generic statics are rejected, but we still reach this case.
         Err(e) => {
-            tcx.sess.delay_span_bug(span, format!("{e:?}"));
+            tcx.sess.span_delayed_bug(span, format!("{e:?}"));
             return;
         }
     };
@@ -204,7 +205,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
     let item = tcx.hir().item(id);
     let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
-        tcx.sess.delay_span_bug(item.span, "expected opaque item");
+        tcx.sess.span_delayed_bug(item.span, "expected opaque item");
         return;
     };
 
@@ -313,7 +314,7 @@ fn check_opaque_meets_bounds<'tcx>(
         Ok(()) => {}
         Err(ty_err) => {
             let ty_err = ty_err.to_string(tcx);
-            return Err(tcx.sess.delay_span_bug(
+            return Err(tcx.sess.span_delayed_bug(
                 span,
                 format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
             ));
@@ -655,7 +656,7 @@ pub(super) fn check_specialization_validity<'tcx>(
         if !tcx.is_impl_trait_in_trait(impl_item) {
             report_forbidden_specialization(tcx, impl_item, parent_impl);
         } else {
-            tcx.sess.delay_span_bug(
+            tcx.sess.span_delayed_bug(
                 DUMMY_SP,
                 format!("parent item: {parent_impl:?} not marked as default"),
             );
@@ -703,7 +704,7 @@ fn check_impl_items_against_trait<'tcx>(
             tcx.associated_item(trait_item_id)
         } else {
             // Checked in `associated_item`.
-            tcx.sess.delay_span_bug(tcx.def_span(impl_item), "missing associated item in trait");
+            tcx.sess.span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait");
             continue;
         };
         match ty_impl_item.kind {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 16fd1a951b5..1412fd1a987 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -439,7 +439,7 @@ fn compare_method_predicate_entailment<'tcx>(
                 }
                 return Err(tcx
                     .sess
-                    .delay_span_bug(rustc_span::DUMMY_SP, "error should have been emitted"));
+                    .span_delayed_bug(rustc_span::DUMMY_SP, "error should have been emitted"));
             }
         }
     }
@@ -937,7 +937,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                 remapped_types.insert(def_id, ty::EarlyBinder::bind(ty));
             }
             Err(err) => {
-                let reported = tcx.sess.delay_span_bug(
+                let reported = tcx.sess.span_delayed_bug(
                     return_span,
                     format!("could not fully resolve: {ty} => {err:?}"),
                 );
@@ -1114,7 +1114,9 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
                         .note(format!("hidden type inferred to be `{}`", self.ty))
                         .emit()
                 }
-                _ => self.tcx.sess.delay_span_bug(DUMMY_SP, "should've been able to remap region"),
+                _ => {
+                    self.tcx.sess.span_delayed_bug(DUMMY_SP, "should've been able to remap region")
+                }
             };
             return Err(guar);
         };
@@ -1473,7 +1475,7 @@ fn compare_number_of_generics<'tcx>(
     // inheriting the generics from will also have mismatched arguments, and
     // we'll report an error for that instead. Delay a bug for safety, though.
     if trait_.is_impl_trait_in_trait() {
-        return Err(tcx.sess.delay_span_bug(
+        return Err(tcx.sess.span_delayed_bug(
             rustc_span::DUMMY_SP,
             "errors comparing numbers of generics of trait/impl functions were not emitted",
         ));
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index bcd317f78ef..86c38480d57 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -153,7 +153,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         trait_m_sig.inputs_and_output,
     ));
     if !ocx.select_all_or_error().is_empty() {
-        tcx.sess.delay_span_bug(
+        tcx.sess.span_delayed_bug(
             DUMMY_SP,
             "encountered errors when checking RPITIT refinement (selection)",
         );
@@ -165,7 +165,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
     );
     let errors = infcx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
-        tcx.sess.delay_span_bug(
+        tcx.sess.span_delayed_bug(
             DUMMY_SP,
             "encountered errors when checking RPITIT refinement (regions)",
         );
@@ -173,7 +173,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
     }
     // Resolve any lifetime variables that may have been introduced during normalization.
     let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else {
-        tcx.sess.delay_span_bug(
+        tcx.sess.span_delayed_bug(
             DUMMY_SP,
             "encountered errors when checking RPITIT refinement (resolution)",
         );
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index 0a05c1039b6..58c77bb45cb 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -66,7 +66,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
             // already checked by coherence, but compilation may
             // not have been terminated.
             let span = tcx.def_span(drop_impl_did);
-            let reported = tcx.sess.delay_span_bug(
+            let reported = tcx.sess.span_delayed_bug(
                 span,
                 format!("should have been rejected by coherence check: {dtor_self_type}"),
             );
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index ba627c740df..2428fe6ae79 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -281,7 +281,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
     pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) {
         let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id());
         let Some(asm_arch) = self.tcx.sess.asm_arch else {
-            self.tcx.sess.delay_span_bug(DUMMY_SP, "target architecture does not support asm");
+            self.tcx.sess.span_delayed_bug(DUMMY_SP, "target architecture does not support asm");
             return;
         };
         for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 177e4611cc9..92619ae417b 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -118,10 +118,10 @@ where
         if tcx.sess.err_count() > 0 {
             return Err(err);
         } else {
-            // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs causes an
-            // error (delay_span_bug) during normalization, without reporting an error, so we need to act as if
-            // no error happened, in order to let our callers continue and report an error later in
-            // check_impl_items_against_trait.
+            // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs
+            // causes an error (span_delayed_bug) during normalization, without reporting an error,
+            // so we need to act as if no error happened, in order to let our callers continue and
+            // report an error later in check_impl_items_against_trait.
             return Ok(());
         }
     }
@@ -1040,7 +1040,7 @@ fn check_type_defn<'tcx>(
                     let ty = tcx.erase_regions(ty);
                     if ty.has_infer() {
                         tcx.sess
-                            .delay_span_bug(item.span, format!("inference variables in {ty:?}"));
+                            .span_delayed_bug(item.span, format!("inference variables in {ty:?}"));
                         // Just treat unresolved type expression as if it needs drop.
                         true
                     } else {
@@ -1812,8 +1812,10 @@ fn check_variances_for_type_defn<'tcx>(
             //
             // if they aren't in the same order, then the user has written invalid code, and already
             // got an error about it (or I'm wrong about this)
-            tcx.sess
-                .delay_span_bug(hir_param.span, "hir generics and ty generics in different order");
+            tcx.sess.span_delayed_bug(
+                hir_param.span,
+                "hir generics and ty generics in different order",
+            );
             continue;
         }
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 46f77780a52..45100457629 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -453,7 +453,7 @@ fn lint_auto_trait_impl<'tcx>(
     impl_def_id: LocalDefId,
 ) {
     if trait_ref.args.len() != 1 {
-        tcx.sess.diagnostic().delay_span_bug(
+        tcx.sess.diagnostic().span_delayed_bug(
             tcx.def_span(impl_def_id),
             "auto traits cannot have generic parameters",
         );
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index 6b18b0ebe9d..42e2818b63f 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -82,7 +82,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
             (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => {
                 // Reported in AST validation
-                tcx.sess.delay_span_bug(item.span, "unsafe negative impl");
+                tcx.sess.span_delayed_bug(item.span, "unsafe negative impl");
             }
             (_, _, Unsafety::Normal, hir::ImplPolarity::Negative(_))
             | (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive)
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index e49bd0917a8..c6ea853b9ba 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -335,7 +335,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // though this may happen when we call `poly_trait_ref_binder_info` with
                     // an (erroneous, #113423) associated return type bound in an impl header.
                     if !supertrait_bound_vars.is_empty() {
-                        self.tcx.sess.delay_span_bug(
+                        self.tcx.sess.span_delayed_bug(
                             DUMMY_SP,
                             format!(
                                 "found supertrait lifetimes without a binder to append \
@@ -1363,7 +1363,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             }
         }
 
-        self.tcx.sess.delay_span_bug(
+        self.tcx.sess.span_delayed_bug(
             lifetime_ref.ident.span,
             format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
         );
@@ -1493,7 +1493,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             }
         }
 
-        self.tcx.sess.delay_span_bug(
+        self.tcx.sess.span_delayed_bug(
             self.tcx.hir().span(hir_id),
             format!("could not resolve {param_def_id:?}"),
         );
@@ -1724,7 +1724,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 } else {
                     self.tcx
                         .sess
-                        .delay_span_bug(binding.ident.span, "bad return type notation here");
+                        .span_delayed_bug(binding.ident.span, "bad return type notation here");
                     vec![]
                 };
                 self.with(scope, |this| {
@@ -2057,7 +2057,7 @@ fn is_late_bound_map(
                                         Some(true) => Some(arg),
                                         Some(false) => None,
                                         None => {
-                                            tcx.sess.delay_span_bug(
+                                            tcx.sess.span_delayed_bug(
                                                 *span,
                                                 format!(
                                                     "Incorrect generic arg count for alias {alias_def:?}"
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index f22b836b42b..4ed1377e7fc 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -29,7 +29,7 @@ fn diagnostic_hir_wf_check<'tcx>(
 
     // HIR wfcheck should only ever happen as part of improving an existing error
     tcx.sess
-        .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
+        .span_delayed_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
 
     let icx = ItemCtxt::new(tcx, def_id);
 
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 788121f7a30..fff4a919e91 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -74,7 +74,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
     if impl_self_ty.references_error() {
         // Don't complain about unconstrained type params when self ty isn't known due to errors.
         // (#36836)
-        tcx.sess.delay_span_bug(
+        tcx.sess.span_delayed_bug(
             tcx.def_span(impl_def_id),
             format!(
                 "potentially unconstrained type parameters weren't evaluated: {impl_self_ty:?}",
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 1c3ac297457..91cdffbbe4f 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -209,8 +209,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
         tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
     });
 
-    // HACK: `check_mod_type_wf` may spuriously emit errors due to `delay_span_bug`, even if those errors
-    // only actually get emitted in `check_mod_item_types`.
+    // HACK: `check_mod_type_wf` may spuriously emit errors due to `span_delayed_bug`, even if
+    // those errors only actually get emitted in `check_mod_item_types`.
     errs?;
 
     if tcx.features().rustc_attrs {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index d3abe0d7e1a..a907acba0e0 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -244,7 +244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ) {
                 // Check for `self` receiver on the method, otherwise we can't use this as a `Fn*` trait.
                 if !self.tcx.associated_item(ok.value.def_id).fn_has_self_parameter {
-                    self.tcx.sess.delay_span_bug(
+                    self.tcx.sess.span_delayed_bug(
                         call_expr.span,
                         "input to overloaded call fn is not a self receiver",
                     );
@@ -259,9 +259,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else {
                         // The `fn`/`fn_mut` lang item is ill-formed, which should have
                         // caused an error elsewhere.
-                        self.tcx
-                            .sess
-                            .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref");
+                        self.tcx.sess.span_delayed_bug(
+                            call_expr.span,
+                            "input to call/call_mut is not a ref",
+                        );
                         return None;
                     };
 
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 00af6d46213..d89af297560 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -142,7 +142,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let reported = self
                     .tcx
                     .sess
-                    .delay_span_bug(span, format!("`{t:?}` should be sized but is not?"));
+                    .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
                 return Err(reported);
             }
         })
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 587038d57bd..f39d795f0ed 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1549,7 +1549,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 // any superfluous errors we might encounter while trying to
                 // emit or provide suggestions on how to fix the initial error.
                 fcx.set_tainted_by_errors(
-                    fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"),
+                    fcx.tcx
+                        .sess
+                        .span_delayed_bug(cause.span, "coercion error but no error emitted"),
                 );
                 let (expected, found) = if label_expression_as_expected {
                     // In the case where this is a "forced unit", like
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 33d14476b2c..8f633834885 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -256,7 +256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.adjust_expr_for_assert_eq_macro(&mut expr, &mut expected_ty_expr);
 
-        self.set_tainted_by_errors(self.tcx.sess.delay_span_bug(
+        self.set_tainted_by_errors(self.tcx.sess.span_delayed_bug(
             expr.span,
             "`TypeError` when attempting coercion but no error emitted",
         ));
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index ed5ac2cea38..7c157c0eae0 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -75,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // coercions from ! to `expected`.
         if ty.is_never() {
             if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
-                let reported = self.tcx().sess.delay_span_bug(
+                let reported = self.tcx().sess.span_delayed_bug(
                     expr.span,
                     "expression with never type wound up being adjusted",
                 );
@@ -514,7 +514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Res::Err => {
                 self.suggest_assoc_method_call(segs);
                 let e =
-                    self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+                    self.tcx.sess.span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
                 Ty::new_error(tcx, e)
             }
@@ -623,7 +623,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Set expectation to error in that case and set tainted
                 // by error (#114529)
                 let coerce_to = opt_coerce_to.unwrap_or_else(|| {
-                    let guar = tcx.sess.delay_span_bug(
+                    let guar = tcx.sess.span_delayed_bug(
                         expr.span,
                         "illegal break with value found but no error reported",
                     );
@@ -1292,7 +1292,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // permit break with a value [1].
         if ctxt.coerce.is_none() && !ctxt.may_break {
             // [1]
-            self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
+            self.tcx.sess.span_delayed_bug(body.span, "no coercion, but loop may not break");
         }
         ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| Ty::new_unit(self.tcx))
     }
@@ -2090,7 +2090,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 [] => unreachable!(),
             };
             err.note(format!(
-                "... and other private field{s} {names}that {were} not provided",
+                "{}private field{s} {names}that {were} not provided",
+                if used_fields.is_empty() { "" } else { "...and other " },
                 s = pluralize!(remaining_private_fields_len),
                 were = pluralize!("was", remaining_private_fields_len),
             ));
@@ -2186,7 +2187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let guar = self
                 .tcx
                 .sess
-                .delay_span_bug(expr.span, "parser recovered but no error was emitted");
+                .span_delayed_bug(expr.span, "parser recovered but no error was emitted");
             self.set_tainted_by_errors(guar);
             return guar;
         }
@@ -2402,7 +2403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let guar = if field.name == kw::Empty {
-            self.tcx.sess.delay_span_bug(field.span, "field name with no name")
+            self.tcx.sess.span_delayed_bug(field.span, "field name with no name")
         } else if self.method_exists(field, base_ty, expr.hir_id, expected.only_has_type(self)) {
             self.ban_take_value_of_method(expr, base_ty, field)
         } else if !base_ty.is_primitive_ty() {
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 9991050d7b2..c22b15231a1 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -538,7 +538,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
             // The struct path probably didn't resolve
             if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() {
-                self.tcx().sess.delay_span_bug(field.span, "couldn't resolve index for field");
+                self.tcx().sess.span_delayed_bug(field.span, "couldn't resolve index for field");
             }
         }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 23b9ac4139d..e1a2a260df7 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -277,7 +277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // FIXME: currently we never try to compose autoderefs
                     // and ReifyFnPointer/UnsafeFnPointer, but we could.
                     _ => {
-                        self.tcx.sess.delay_span_bug(
+                        self.tcx.sess.span_delayed_bug(
                             expr.span,
                             format!(
                                 "while adjusting {:?}, can't compose {:?} and {:?}",
@@ -866,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let guar = self
                     .tcx
                     .sess
-                    .delay_span_bug(span, "method resolution should've emitted an error");
+                    .span_delayed_bug(span, "method resolution should've emitted an error");
                 let result = match error {
                     method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
                     _ => Err(guar),
@@ -1440,7 +1440,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ) {
                 Ok(ok) => self.register_infer_ok_obligations(ok),
                 Err(_) => {
-                    self.tcx.sess.delay_span_bug(
+                    self.tcx.sess.span_delayed_bug(
                         span,
                         format!(
                         "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index f1720dc98e6..509596c1e90 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -517,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let tcx = self.tcx;
         // FIXME: taint after emitting errors and pass through an `ErrorGuaranteed`
         self.set_tainted_by_errors(
-            tcx.sess.delay_span_bug(call_span, "no errors reported for args"),
+            tcx.sess.span_delayed_bug(call_span, "no errors reported for args"),
         );
 
         // Get the argument span in the context of the call span so that
@@ -1361,7 +1361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let variant = match def {
             Res::Err => {
                 let guar =
-                    self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted");
+                    self.tcx.sess.span_delayed_bug(path_span, "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(guar);
                 return Err(guar);
             }
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 5d516eaf507..a3c77af62a7 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -48,7 +48,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let to = normalize(to);
         trace!(?from, ?to);
         if from.has_non_region_infer() || to.has_non_region_infer() {
-            tcx.sess.delay_span_bug(span, "argument to transmute has inference variables");
+            tcx.sess.span_delayed_bug(span, "argument to transmute has inference variables");
             return;
         }
         // Transmutes that are only changing lifetimes are always ok.
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index a22c95ac8ff..29e4fd9239a 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -420,20 +420,16 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) {
         MultiSpan::new(),
         "It looks like you're trying to break rust; would you like some ICE?",
     );
-    handler.note_without_error("the compiler expectedly panicked. this is a feature.");
-    handler.note_without_error(
+    handler.note("the compiler expectedly panicked. this is a feature.");
+    handler.note(
         "we would appreciate a joke overview: \
          https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
     );
-    handler.note_without_error(format!(
-        "rustc {} running on {}",
-        tcx.sess.cfg_version,
-        config::host_triple(),
-    ));
+    handler.note(format!("rustc {} running on {}", tcx.sess.cfg_version, config::host_triple(),));
     if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() {
-        handler.note_without_error(format!("compiler flags: {}", flags.join(" ")));
+        handler.note(format!("compiler flags: {}", flags.join(" ")));
         if excluded_cargo_defaults {
-            handler.note_without_error("some of the compiler flags provided by cargo are hidden");
+            handler.note("some of the compiler flags provided by cargo are hidden");
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 0bcb7c7b5d7..ebb15e072aa 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -540,7 +540,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         let ty::Adt(adt_def, _) = ty.kind() else {
             self.tcx()
                 .sess
-                .delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
+                .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT");
             return Err(());
         };
 
@@ -575,7 +575,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
             _ => {
                 self.tcx()
                     .sess
-                    .delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
+                    .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT");
                 Err(())
             }
         }
@@ -588,7 +588,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         match ty.kind() {
             ty::Tuple(args) => Ok(args.len()),
             _ => {
-                self.tcx().sess.delay_span_bug(span, "tuple pattern not applied to a tuple");
+                self.tcx().sess.span_delayed_bug(span, "tuple pattern not applied to a tuple");
                 Err(())
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index d69d2529b18..f820835acef 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -385,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // type parameters or early-bound regions.
         let tcx = self.tcx;
         let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
-            tcx.sess.delay_span_bug(
+            tcx.sess.span_delayed_bug(
                 obligation.cause.span,
                 "operator trait does not have corresponding operator method",
             );
@@ -393,7 +393,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         if method_item.kind != ty::AssocKind::Fn {
-            self.tcx.sess.delay_span_bug(tcx.def_span(method_item.def_id), "not a method");
+            self.tcx.sess.span_delayed_bug(tcx.def_span(method_item.def_id), "not a method");
             return None;
         }
 
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 7d83f4a12b1..b980a7d1d28 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -802,7 +802,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         let trait_ref = principal.with_self_ty(self.tcx, self_ty);
         self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
             if new_trait_ref.has_non_region_bound_vars() {
-                this.tcx.sess.delay_span_bug(
+                this.tcx.sess.span_delayed_bug(
                     this.span,
                     "tried to select method from HRTB with non-lifetime bound vars",
                 );
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index a7764f4ff96..858385246dd 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -813,7 +813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         span: item_span,
                         ..
                     })) => {
-                        tcx.sess.delay_span_bug(
+                        tcx.sess.span_delayed_bug(
                             *item_span,
                             "auto trait is invoked with no method error, but no error reported?",
                         );
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index fcb3f8f47bd..1e9387ef041 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -900,7 +900,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ) {
             self.tcx
                 .sess
-                .delay_span_bug(span, "operator didn't have the right number of generic args");
+                .span_delayed_bug(span, "operator didn't have the right number of generic args");
             return Err(vec![]);
         }
 
@@ -933,7 +933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // This path may do some inference, so make sure we've really
                 // doomed compilation so as to not accidentally stabilize new
                 // inference or something here...
-                self.tcx.sess.delay_span_bug(span, "this path really should be doomed...");
+                self.tcx.sess.span_delayed_bug(span, "this path really should be doomed...");
                 // Guide inference for the RHS expression if it's provided --
                 // this will allow us to better error reporting, at the expense
                 // of making some error messages a bit more specific.
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 1ecf553d71d..b63bb1e00cb 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -899,7 +899,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let (res, opt_ty, segments) = path_resolution;
         match res {
             Res::Err => {
-                let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+                let e = tcx.sess.span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
                 return Ty::new_error(tcx, e);
             }
@@ -1068,7 +1068,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let (res, opt_ty, segments) =
             self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None);
         if res == Res::Err {
-            let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
+            let e = tcx.sess.span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
             self.set_tainted_by_errors(e);
             on_error(e);
             return Ty::new_error(tcx, e);
@@ -1084,7 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let variant = match res {
             Res::Err => {
-                let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
+                let e = tcx.sess.span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
                 on_error(e);
                 return Ty::new_error(tcx, e);
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 3a0f46c3a8c..c0a5818b9e5 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -725,7 +725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 }
 
-                self.tcx.sess.delay_span_bug(
+                self.tcx.sess.span_delayed_bug(
                     closure_span,
                     format!(
                         "two identical projections: ({:?}, {:?})",
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index fc635a8da2e..cc617fd2d0b 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -218,7 +218,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 // When encountering `return [0][0]` outside of a `fn` body we can encounter a base
                 // that isn't in the type table. We assume more relevant errors have already been
                 // emitted, so we delay an ICE if none have. (#64638)
-                self.tcx().sess.delay_span_bug(e.span, format!("bad base: `{base:?}`"));
+                self.tcx().sess.span_delayed_bug(e.span, format!("bad base: `{base:?}`"));
             }
             if let Some(base_ty) = base_ty
                 && let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
@@ -311,7 +311,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
                 // Nothing to write back here
             }
             hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
-                self.tcx().sess.delay_span_bug(p.span, format!("unexpected generic param: {p:?}"));
+                self.tcx()
+                    .sess
+                    .span_delayed_bug(p.span, format!("unexpected generic param: {p:?}"));
             }
         }
     }
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index 2d809030e58..92297a27a63 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -262,7 +262,7 @@ pub(crate) fn prepare_session_directory(
                     directory."
             );
 
-            sess.init_incr_comp_session(session_dir, directory_lock, false);
+            sess.init_incr_comp_session(session_dir, directory_lock);
             return Ok(());
         };
 
@@ -276,7 +276,7 @@ pub(crate) fn prepare_session_directory(
                 sess.emit_warning(errors::HardLinkFailed { path: &session_dir });
             }
 
-            sess.init_incr_comp_session(session_dir, directory_lock, true);
+            sess.init_incr_comp_session(session_dir, directory_lock);
             return Ok(());
         } else {
             debug!("copying failed - trying next directory");
@@ -312,7 +312,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) {
 
     let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone();
 
-    if let Some(_) = sess.has_errors_or_delayed_span_bugs() {
+    if let Some(_) = sess.has_errors_or_span_delayed_bugs() {
         // If there have been any errors during compilation, we don't want to
         // publish this session directory. Rather, we'll just delete it.
 
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index d6320d680e7..ff0953e9f7b 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -32,7 +32,7 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) {
             return;
         }
         // This is going to be deleted in finalize_session_directory, so let's not create it
-        if let Some(_) = sess.has_errors_or_delayed_span_bugs() {
+        if let Some(_) = sess.has_errors_or_span_delayed_bugs() {
             return;
         }
 
@@ -87,7 +87,7 @@ pub fn save_work_product_index(
         return;
     }
     // This is going to be deleted in finalize_session_directory, so let's not create it
-    if let Some(_) = sess.has_errors_or_delayed_span_bugs() {
+    if let Some(_) = sess.has_errors_or_span_delayed_bugs() {
         return;
     }
 
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 6fbab0ef299..473a3965885 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -194,8 +194,8 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
                 //
                 // rust-lang/rust#57464: `impl Trait` can leak local
                 // scopes (in manner violating typeck). Therefore, use
-                // `delay_span_bug` to allow type error over an ICE.
-                canonicalizer.tcx.sess.delay_span_bug(
+                // `span_delayed_bug` to allow type error over an ICE.
+                canonicalizer.tcx.sess.span_delayed_bug(
                     rustc_span::DUMMY_SP,
                     format!("unexpected region in query response: `{r:?}`"),
                 );
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 2a9e20b9f8f..c3d07415bb8 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -175,7 +175,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 &mut OriginalQueryValues::default(),
             );
             self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
-                self.tcx.sess.delay_span_bug(
+                self.tcx.sess.span_delayed_bug(
                     DUMMY_SP,
                     format!("cannot relate consts of different types (a={a:?}, b={b:?})",),
                 )
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 3be23796550..9cdf78484d4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -131,13 +131,13 @@ pub struct TypeErrCtxt<'a, 'tcx> {
 
 impl Drop for TypeErrCtxt<'_, '_> {
     fn drop(&mut self) {
-        if let Some(_) = self.infcx.tcx.sess.has_errors_or_delayed_span_bugs() {
+        if let Some(_) = self.infcx.tcx.sess.has_errors_or_span_delayed_bugs() {
             // ok, emitted an error.
         } else {
             self.infcx
                 .tcx
                 .sess
-                .delay_good_path_bug("used a `TypeErrCtxt` without raising an error or lint");
+                .good_path_delayed_bug("used a `TypeErrCtxt` without raising an error or lint");
         }
     }
 }
@@ -517,7 +517,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
         self.tcx
             .sess
-            .delay_span_bug(self.tcx.def_span(generic_param_scope), "expected region errors")
+            .span_delayed_bug(self.tcx.def_span(generic_param_scope), "expected region errors")
     }
 
     // This method goes through all the errors and try to group certain types
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 7dd19c8e15f..8fe6c1b0d86 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -374,7 +374,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 multi_suggestions,
                 bad_label,
             }
-            .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+            .into_diagnostic(self.tcx.sess.diagnostic()),
             TypeAnnotationNeeded::E0283 => AmbiguousImpl {
                 span,
                 source_kind,
@@ -384,7 +384,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 multi_suggestions,
                 bad_label,
             }
-            .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+            .into_diagnostic(self.tcx.sess.diagnostic()),
             TypeAnnotationNeeded::E0284 => AmbiguousReturn {
                 span,
                 source_kind,
@@ -394,7 +394,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 multi_suggestions,
                 bad_label,
             }
-            .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+            .into_diagnostic(self.tcx.sess.diagnostic()),
         }
     }
 }
@@ -581,7 +581,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 multi_suggestions,
                 bad_label: None,
             }
-            .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+            .into_diagnostic(self.tcx.sess.diagnostic()),
             TypeAnnotationNeeded::E0283 => AmbiguousImpl {
                 span,
                 source_kind,
@@ -591,7 +591,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 multi_suggestions,
                 bad_label: None,
             }
-            .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+            .into_diagnostic(self.tcx.sess.diagnostic()),
             TypeAnnotationNeeded::E0284 => AmbiguousReturn {
                 span,
                 source_kind,
@@ -601,7 +601,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 multi_suggestions,
                 bad_label: None,
             }
-            .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
+            .into_diagnostic(self.tcx.sess.diagnostic()),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 781cc192ae5..fed76cd65cf 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -140,7 +140,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     span,
                     notes: reference_valid.into_iter().chain(content_valid).collect(),
                 }
-                .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+                .into_diagnostic(self.tcx.sess.diagnostic())
             }
             infer::RelateObjectBound(span) => {
                 let object_valid = note_and_explain::RegionExplanation::new(
@@ -161,7 +161,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     span,
                     notes: object_valid.into_iter().chain(pointer_valid).collect(),
                 }
-                .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+                .into_diagnostic(self.tcx.sess.diagnostic())
             }
             infer::RelateParamBound(span, ty, opt_span) => {
                 let prefix = match *sub {
@@ -177,7 +177,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     self.tcx, sub, opt_span, prefix, suffix,
                 );
                 FulfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note }
-                    .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+                    .into_diagnostic(self.tcx.sess.diagnostic())
             }
             infer::RelateRegionParamBound(span) => {
                 let param_instantiated = note_and_explain::RegionExplanation::new(
@@ -198,7 +198,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     span,
                     notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
                 }
-                .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+                .into_diagnostic(self.tcx.sess.diagnostic())
             }
             infer::ReferenceOutlivesReferent(ty, span) => {
                 let pointer_valid = note_and_explain::RegionExplanation::new(
@@ -220,7 +220,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     ty: self.resolve_vars_if_possible(ty),
                     notes: pointer_valid.into_iter().chain(data_valid).collect(),
                 }
-                .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+                .into_diagnostic(self.tcx.sess.diagnostic())
             }
             infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
                 let mut err = self.report_extra_impl_obligation(
@@ -281,7 +281,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     span,
                     notes: instantiated.into_iter().chain(must_outlive).collect(),
                 }
-                .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+                .into_diagnostic(self.tcx.sess.diagnostic())
             }
         };
         if sub.is_error() || sup.is_error() {
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index b0e82a92674..b6e86e2b676 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -798,7 +798,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
 
         // Errors in earlier passes can yield error variables without
         // resolution errors here; delay ICE in favor of those errors.
-        self.tcx().sess.delay_span_bug(
+        self.tcx().sess.span_delayed_bug(
             self.var_infos[node_idx].origin.span(),
             format!(
                 "collect_error_for_expanding_node() could not find \
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index bb16d97eb85..32c09e491c7 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1433,7 +1433,7 @@ impl<'tcx> InferCtxt<'tcx> {
                     let guar = self
                         .tcx
                         .sess
-                        .delay_span_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved"));
+                        .span_delayed_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved"));
                     Ok(self.tcx.fold_regions(value, |re, _| {
                         if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re }
                     }))
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index ee6a3fd0c82..77c1d6a7313 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -494,7 +494,7 @@ where
                     // shouldn't ever fail. Instead, it unconditionally emits an
                     // alias-relate goal.
                     assert!(!self.infcx.next_trait_solver());
-                    self.tcx().sess.delay_span_bug(
+                    self.tcx().sess.span_delayed_bug(
                         self.delegate.span(),
                         "failure to relate an opaque to itself should result in an error later on",
                     );
@@ -552,7 +552,7 @@ where
         match b.kind() {
             ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
                 // Forbid inference variables in the RHS.
-                self.infcx.tcx.sess.delay_span_bug(
+                self.infcx.tcx.sess.span_delayed_bug(
                     self.delegate.span(),
                     format!("unexpected inference var {b:?}",),
                 );
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index a737761ba22..715006a50d3 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -41,7 +41,7 @@ impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
     fn drop(&mut self) {
         if !self.opaque_types.is_empty() {
             ty::tls::with(|tcx| {
-                tcx.sess.delay_span_bug(DUMMY_SP, format!("{:?}", self.opaque_types))
+                tcx.sess.span_delayed_bug(DUMMY_SP, format!("{:?}", self.opaque_types))
             });
         }
     }
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index c6cbde4dba9..395830d937b 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -254,7 +254,7 @@ where
                     // ignore this, we presume it will yield an error
                     // later, since if a type variable is not resolved by
                     // this point it never will be
-                    self.tcx.sess.delay_span_bug(
+                    self.tcx.sess.span_delayed_bug(
                         origin.span(),
                         format!("unresolved inference variable in outlives: {v:?}"),
                     );
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 35a8fe6dc47..ce619ae8a0d 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -180,7 +180,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
                 // ignore this, we presume it will yield an error
                 // later, since if a type variable is not resolved by
                 // this point it never will be
-                self.tcx.sess.delay_span_bug(
+                self.tcx.sess.span_delayed_bug(
                     rustc_span::DUMMY_SP,
                     format!("unresolved inference variable in outlives: {v:?}"),
                 );
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 88212d164bc..fab8a18f2dc 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -519,9 +519,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
     match result {
         Ok(_) => {
             if sess.opts.json_artifact_notifications {
-                sess.parse_sess
-                    .span_diagnostic
-                    .emit_artifact_notification(deps_filename, "dep-info");
+                sess.diagnostic().emit_artifact_notification(deps_filename, "dep-info");
             }
         }
         Err(error) => {
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index e81c3f42a16..e9611c74a68 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -194,16 +194,16 @@ impl<'tcx> Queries<'tcx> {
         let Some((def_id, _)) = tcx.entry_fn(()) else { return };
         for attr in tcx.get_attrs(def_id, sym::rustc_error) {
             match attr.meta_item_list() {
-                // Check if there is a `#[rustc_error(delay_span_bug_from_inside_query)]`.
+                // Check if there is a `#[rustc_error(span_delayed_bug_from_inside_query)]`.
                 Some(list)
                     if list.iter().any(|list_item| {
                         matches!(
                             list_item.ident().map(|i| i.name),
-                            Some(sym::delay_span_bug_from_inside_query)
+                            Some(sym::span_delayed_bug_from_inside_query)
                         )
                     }) =>
                 {
-                    tcx.ensure().trigger_delay_span_bug(def_id);
+                    tcx.ensure().trigger_span_delayed_bug(def_id);
                 }
 
                 // Bare `#[rustc_error]`.
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 9bc9f88d3f7..024e542d4af 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -926,6 +926,10 @@ pub trait LintContext {
                         if elided { "'static " } else { "'static" },
                         Applicability::MachineApplicable
                     );
+                },
+                BuiltinLintDiagnostics::RedundantImportVisibility { max_vis, span } => {
+                    db.span_note(span, format!("the most public imported item is `{max_vis}`"));
+                    db.help("reduce the glob import's visibility or increase visibility of imported items");
                 }
             }
             // Rewrap `db`, and pass control to the user.
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 36aa959ddc9..4cccaeeca84 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -430,7 +430,7 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
     // that was not lint-checked (perhaps it doesn't exist?). This is a bug.
     for (id, lints) in cx.context.buffered.map {
         for early_lint in lints {
-            sess.delay_span_bug(
+            sess.span_delayed_bug(
                 early_lint.span,
                 format!(
                     "failed to process buffered lint here (dummy = {})",
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 878c1a65dbf..de0abe04611 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -583,6 +583,10 @@ pub enum BuiltinLintDiagnostics {
         elided: bool,
         span: Span,
     },
+    RedundantImportVisibility {
+        span: Span,
+        max_vis: String,
+    },
 }
 
 /// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 7f033265136..0edcac93b62 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -525,12 +525,9 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
 
 // Unfortunately, the LLVM C API doesn't provide a way to create the
 // TargetLibraryInfo pass, so we use this method to do so.
-extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
-                                       bool DisableSimplifyLibCalls) {
+extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M) {
   Triple TargetTriple(unwrap(M)->getTargetTriple());
   TargetLibraryInfoImpl TLII(TargetTriple);
-  if (DisableSimplifyLibCalls)
-    TLII.disableAllFunctions();
   unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
 }
 
@@ -697,7 +694,7 @@ LLVMRustOptimize(
     bool IsLinkerPluginLTO,
     bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
     bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
-    bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
+    bool EmitLifetimeMarkers,
     LLVMRustSanitizerOptions *SanitizerOptions,
     const char *PGOGenPath, const char *PGOUsePath,
     bool InstrumentCoverage, const char *InstrProfileOutput,
@@ -795,8 +792,6 @@ LLVMRustOptimize(
 
   Triple TargetTriple(TheModule->getTargetTriple());
   std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
-  if (DisableSimplifyLibCalls)
-    TLII->disableAllFunctions();
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
   PB.registerModuleAnalyses(MAM);
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index 44b235a6d3d..8da6f0007f0 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -269,7 +269,7 @@ metadata_unknown_import_name_type =
     unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated
 
 metadata_unknown_link_kind =
-    unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib
+    unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib, link-arg
     .label = unknown link kind
 
 metadata_unknown_link_modifier =
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 169b56d40fa..301e3f2620d 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -7,8 +7,9 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob
 use rustc_ast::expand::allocator::{alloc_error_handler_name, global_fn_name, AllocatorKind};
 use rustc_ast::{self as ast, *};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::owned_slice::OwnedSlice;
 use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{FreezeReadGuard, FreezeWriteGuard};
+use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard};
 use rustc_expand::base::SyntaxExtension;
 use rustc_fs_util::try_canonicalize;
 use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE};
@@ -16,16 +17,14 @@ use rustc_hir::definitions::Definitions;
 use rustc_index::IndexVec;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, CrateType, ExternLocation};
-use rustc_session::cstore::{
-    CrateDepKind, CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn,
-};
+use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource};
 use rustc_session::lint;
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
-use rustc_target::spec::{PanicStrategy, TargetTriple};
+use rustc_target::spec::{PanicStrategy, Target, TargetTriple};
 
 use proc_macro::bridge::client::ProcMacro;
 use std::error::Error;
@@ -34,6 +33,17 @@ use std::path::Path;
 use std::time::Duration;
 use std::{cmp, iter};
 
+/// The backend's way to give the crate store access to the metadata in a library.
+/// Note that it returns the raw metadata bytes stored in the library file, whether
+/// it is compressed, uncompressed, some weird mix, etc.
+/// rmeta files are backend independent and not handled here.
+pub trait MetadataLoader {
+    fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
+    fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
+}
+
+pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync;
+
 pub struct CStore {
     metadata_loader: Box<MetadataLoaderDyn>,
 
@@ -257,7 +267,7 @@ impl CStore {
             let unused_externs =
                 self.unused_externs.iter().map(|ident| ident.to_ident_string()).collect::<Vec<_>>();
             let unused_externs = unused_externs.iter().map(String::as_str).collect::<Vec<&str>>();
-            tcx.sess.parse_sess.span_diagnostic.emit_unused_externs(
+            tcx.sess.diagnostic().emit_unused_externs(
                 level,
                 json_unused_externs.is_loud(),
                 &unused_externs,
diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs
index 4b451253f2b..c95ef01faa7 100644
--- a/compiler/rustc_metadata/src/fs.rs
+++ b/compiler/rustc_metadata/src/fs.rs
@@ -91,10 +91,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) {
             }
         };
         if tcx.sess.opts.json_artifact_notifications {
-            tcx.sess
-                .parse_sess
-                .span_diagnostic
-                .emit_artifact_notification(out_filename.as_path(), "metadata");
+            tcx.sess.diagnostic().emit_artifact_notification(out_filename.as_path(), "metadata");
         }
         (filename, None)
     } else {
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 2b5773320b4..bcc124524eb 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -212,7 +212,7 @@
 //! no means all of the necessary details. Take a look at the rest of
 //! metadata::locator or metadata::creader for all the juicy details!
 
-use crate::creader::Library;
+use crate::creader::{Library, MetadataLoader};
 use crate::errors;
 use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
 
@@ -223,7 +223,7 @@ use rustc_data_structures::svh::Svh;
 use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
 use rustc_fs_util::try_canonicalize;
 use rustc_session::config;
-use rustc_session::cstore::{CrateSource, MetadataLoader};
+use rustc_session::cstore::CrateSource;
 use rustc_session::filesearch::FileSearch;
 use rustc_session::search_paths::PathKind;
 use rustc_session::utils::CanonicalizedPath;
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index f352fa6d46a..b3760b1099b 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -160,6 +160,18 @@ impl<'tcx> Collector<'tcx> {
                                 }
                                 NativeLibKind::RawDylib
                             }
+                            "link-arg" => {
+                                if !features.link_arg_attribute {
+                                    feature_err(
+                                        &sess.parse_sess,
+                                        sym::link_arg_attribute,
+                                        span,
+                                        "link kind `link-arg` is unstable",
+                                    )
+                                    .emit();
+                                }
+                                NativeLibKind::LinkArg
+                            }
                             kind => {
                                 sess.emit_err(errors::UnknownLinkKind { span, kind });
                                 continue;
diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs
index c1884bb8068..8c1e58fefc5 100644
--- a/compiler/rustc_middle/src/macros.rs
+++ b/compiler/rustc_middle/src/macros.rs
@@ -4,9 +4,10 @@
 ///
 /// If you have a span available, you should use [`span_bug`] instead.
 ///
-/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful.
+/// If the bug should only be emitted when compilation didn't fail, [`Session::span_delayed_bug`]
+/// may be useful.
 ///
-/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug
+/// [`Session::span_delayed_bug`]: rustc_session::Session::span_delayed_bug
 /// [`span_bug`]: crate::span_bug
 #[macro_export]
 macro_rules! bug {
@@ -23,9 +24,10 @@ macro_rules! bug {
 /// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger
 /// ICEs.
 ///
-/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful.
+/// If the bug should only be emitted when compilation didn't fail, [`Session::span_delayed_bug`]
+/// may be useful.
 ///
-/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug
+/// [`Session::span_delayed_bug`]: rustc_session::Session::span_delayed_bug
 #[macro_export]
 macro_rules! span_bug {
     ($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) });
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index f7a55fa95b6..27d82f5fefc 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -566,7 +566,7 @@ impl<'tcx> TyCtxt<'tcx> {
             |span, def_id| {
                 // The API could be uncallable for other reasons, for example when a private module
                 // was referenced.
-                self.sess.delay_span_bug(span, format!("encountered unmarked API: {def_id:?}"));
+                self.sess.span_delayed_bug(span, format!("encountered unmarked API: {def_id:?}"));
             },
         )
     }
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index aded3e495d9..09e56b2e4a8 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -315,7 +315,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
     pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
         Self::uninit_inner(size, align, || {
             ty::tls::with(|tcx| {
-                tcx.sess.delay_span_bug(DUMMY_SP, "exhausted memory during interpretation")
+                tcx.sess.span_delayed_bug(DUMMY_SP, "exhausted memory during interpretation")
             });
             InterpError::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted).into()
         })
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index e360fb3eaaf..e5f891fcc91 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -199,7 +199,7 @@ pub struct LitToConstInput<'tcx> {
 #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
 pub enum LitToConstError {
     /// The literal's inferred type did not match the expected `ty` in the input.
-    /// This is used for graceful error handling (`delay_span_bug`) in
+    /// This is used for graceful error handling (`span_delayed_bug`) in
     /// type checking (`Const::from_anon_const`).
     TypeError,
     Reported(ErrorGuaranteed),
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 29decd0f050..03f3ceb8d17 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -108,9 +108,9 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
 // Queries marked with `fatal_cycle` do not need the latter implementation,
 // as they will raise an fatal error on query cycles instead.
 rustc_queries! {
-    /// This exists purely for testing the interactions between delay_span_bug and incremental.
-    query trigger_delay_span_bug(key: DefId) -> () {
-        desc { "triggering a delay span bug for testing incremental" }
+    /// This exists purely for testing the interactions between span_delayed_bug and incremental.
+    query trigger_span_delayed_bug(key: DefId) -> () {
+        desc { "triggering a span delayed bug for testing incremental" }
     }
 
     /// Collects the list of all tools registered using `#![register_tool]`.
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 9a6eba89655..0d1f3c1f8b5 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -551,7 +551,7 @@ macro_rules! define_feedable {
                                 // We have an inconsistency. This can happen if one of the two
                                 // results is tainted by errors. In this case, delay a bug to
                                 // ensure compilation is doomed, and keep the `old` value.
-                                tcx.sess.delay_span_bug(DUMMY_SP, format!(
+                                tcx.sess.span_delayed_bug(DUMMY_SP, format!(
                                     "Trying to feed an already recorded value for query {} key={key:?}:\n\
                                     old value: {old:?}\nnew value: {value:?}",
                                     stringify!($name),
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 7650389415c..1d9a25628b0 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -481,7 +481,7 @@ impl<'tcx> AdtDef<'tcx> {
                     ErrorHandled::Reported(..) => "enum discriminant evaluation failed",
                     ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics",
                 };
-                tcx.sess.delay_span_bug(tcx.def_span(expr_did), msg);
+                tcx.sess.span_delayed_bug(tcx.def_span(expr_did), msg);
                 None
             }
         }
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index d0a1c943292..b478d95be1b 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -144,7 +144,7 @@ impl<'tcx> Const<'tcx> {
         span: S,
         msg: &'static str,
     ) -> Const<'tcx> {
-        let reported = tcx.sess.delay_span_bug(span, msg);
+        let reported = tcx.sess.span_delayed_bug(span, msg);
         Const::new_error(tcx, reported, ty)
     }
 
@@ -208,7 +208,7 @@ impl<'tcx> Const<'tcx> {
             match tcx.at(expr.span).lit_to_const(lit_input) {
                 Ok(c) => return Some(c),
                 Err(e) => {
-                    tcx.sess.delay_span_bug(
+                    tcx.sess.span_delayed_bug(
                         expr.span,
                         format!("Const::from_anon_const: couldn't lit_to_const {e:?}"),
                     );
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index bb02c6e0c78..ff690db7bee 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -714,8 +714,10 @@ impl<'tcx> TyCtxt<'tcx> {
             {
                 Bound::Included(a)
             } else {
-                self.sess
-                    .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute");
+                self.sess.span_delayed_bug(
+                    attr.span,
+                    "invalid rustc_layout_scalar_valid_range attribute",
+                );
                 Bound::Unbounded
             }
         };
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 4d8ac19dbe2..e1d1f361091 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -282,8 +282,8 @@ pub struct LayoutCx<'tcx, C> {
 impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
     type TargetDataLayoutRef = &'tcx TargetDataLayout;
 
-    fn delay_bug(&self, txt: String) {
-        self.tcx.sess.delay_span_bug(DUMMY_SP, txt);
+    fn delayed_bug(&self, txt: String) {
+        self.tcx.sess.span_delayed_bug(DUMMY_SP, txt);
     }
 
     fn current_data_layout(&self) -> Self::TargetDataLayoutRef {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 24cba913bb8..9feda4d205e 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -296,6 +296,23 @@ pub enum Visibility<Id = LocalDefId> {
     Restricted(Id),
 }
 
+impl Visibility {
+    pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
+        match self {
+            ty::Visibility::Restricted(restricted_id) => {
+                if restricted_id.is_top_level_module() {
+                    "pub(crate)".to_string()
+                } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
+                    "pub(self)".to_string()
+                } else {
+                    format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
+                }
+            }
+            ty::Visibility::Public => "pub".to_string(),
+        }
+    }
+}
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
 pub enum BoundConstness {
     /// `T: Trait`
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index d50743bc207..68dd8dee87c 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -3025,7 +3025,7 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
         //
         // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths`
         // wrapper can be used to suppress this query, in exchange for full paths being formatted.
-        tcx.sess.delay_good_path_bug(
+        tcx.sess.good_path_delayed_bug(
             "trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging",
         );
     }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index f12a512da31..e10b5706b48 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1545,7 +1545,7 @@ impl<'tcx> Region<'tcx> {
         tcx.intern_region(ty::ReError(reported))
     }
 
-    /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it
+    /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` to ensure it
     /// gets used.
     #[track_caller]
     pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
@@ -1556,7 +1556,7 @@ impl<'tcx> Region<'tcx> {
         )
     }
 
-    /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given
+    /// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` with the given
     /// `msg` to ensure it gets used.
     #[track_caller]
     pub fn new_error_with_message<S: Into<MultiSpan>>(
@@ -1564,7 +1564,7 @@ impl<'tcx> Region<'tcx> {
         span: S,
         msg: &'static str,
     ) -> Region<'tcx> {
-        let reported = tcx.sess.delay_span_bug(span, msg);
+        let reported = tcx.sess.span_delayed_bug(span, msg);
         Region::new_error(tcx, reported)
     }
 
@@ -1997,13 +1997,13 @@ impl<'tcx> Ty<'tcx> {
         Ty::new(tcx, Error(reported))
     }
 
-    /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
+    /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` to ensure it gets used.
     #[track_caller]
     pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         Ty::new_error_with_message(tcx, DUMMY_SP, "TyKind::Error constructed but no error reported")
     }
 
-    /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
+    /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to
     /// ensure it gets used.
     #[track_caller]
     pub fn new_error_with_message<S: Into<MultiSpan>>(
@@ -2011,7 +2011,7 @@ impl<'tcx> Ty<'tcx> {
         span: S,
         msg: impl Into<String>,
     ) -> Ty<'tcx> {
-        let reported = tcx.sess.delay_span_bug(span, msg);
+        let reported = tcx.sess.span_delayed_bug(span, msg);
         Ty::new(tcx, Error(reported))
     }
 
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 4a5c89411da..d372c1cd604 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -391,7 +391,7 @@ impl<'tcx> TypeckResults<'tcx> {
 
     pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option<BindingMode> {
         self.pat_binding_modes().get(id).copied().or_else(|| {
-            s.delay_span_bug(sp, "missing binding mode");
+            s.span_delayed_bug(sp, "missing binding mode");
             None
         })
     }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 40d592ddef0..70252a4dc67 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -361,7 +361,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
             let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
                 self.sess
-                    .delay_span_bug(self.def_span(impl_did), "Drop impl without drop function");
+                    .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function");
                 return;
             };
 
diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs
index 634ed5ec54b..21c1a93fde8 100644
--- a/compiler/rustc_middle/src/util/bug.rs
+++ b/compiler/rustc_middle/src/util/bug.rs
@@ -38,16 +38,16 @@ fn opt_span_bug_fmt<S: Into<MultiSpan>>(
     })
 }
 
-/// A query to trigger a `delay_span_bug`. Clearly, if one has a `tcx` one can already trigger a
-/// `delay_span_bug`, so what is the point of this? It exists to help us test `delay_span_bug`'s
+/// A query to trigger a `span_delayed_bug`. Clearly, if one has a `tcx` one can already trigger a
+/// `span_delayed_bug`, so what is the point of this? It exists to help us test `span_delayed_bug`'s
 /// interactions with the query system and incremental.
-pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) {
-    tcx.sess.delay_span_bug(
+pub fn trigger_span_delayed_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) {
+    tcx.sess.span_delayed_bug(
         tcx.def_span(key),
-        "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]",
+        "delayed span bug triggered by #[rustc_error(span_delayed_bug_from_inside_query)]",
     );
 }
 
 pub fn provide(providers: &mut crate::query::Providers) {
-    *providers = crate::query::Providers { trigger_delay_span_bug, ..*providers };
+    *providers = crate::query::Providers { trigger_span_delayed_bug, ..*providers };
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 4ed49e78738..3bfffa7354d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -114,7 +114,7 @@ fn lit_to_mir_constant<'tcx>(
         let width = tcx
             .layout_of(param_ty)
             .map_err(|_| {
-                LitToConstError::Reported(tcx.sess.delay_span_bug(
+                LitToConstError::Reported(tcx.sess.span_delayed_bug(
                     DUMMY_SP,
                     format!("couldn't compute width of literal: {:?}", lit_input.lit),
                 ))
@@ -158,7 +158,7 @@ fn lit_to_mir_constant<'tcx>(
         }
         (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg)
             .ok_or_else(|| {
-                LitToConstError::Reported(tcx.sess.delay_span_bug(
+                LitToConstError::Reported(tcx.sess.span_delayed_bug(
                     DUMMY_SP,
                     format!("couldn't parse float literal: {:?}", lit_input.lit),
                 ))
@@ -167,7 +167,7 @@ fn lit_to_mir_constant<'tcx>(
         (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
         (ast::LitKind::Err, _) => {
             return Err(LitToConstError::Reported(
-                tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"),
+                tcx.sess.span_delayed_bug(DUMMY_SP, "encountered LitKind::Err during mir build"),
             ));
         }
         _ => return Err(LitToConstError::TypeError),
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index c17fdf71b55..1f7c6d7875b 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -470,7 +470,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     if let Some((assigned_ty, assignment_span)) = self.assignment_info {
                         if assigned_ty.needs_drop(self.tcx, self.param_env) {
                             // This would be unsafe, but should be outright impossible since we reject such unions.
-                            self.tcx.sess.delay_span_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}"));
+                            self.tcx.sess.span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}"));
                         }
                     } else {
                         self.requires_unsafe(expr.span, AccessToUnionField);
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index fbb74650faa..240aa10ac91 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -16,7 +16,7 @@ pub(crate) fn lit_to_const<'tcx>(
         let width = tcx
             .layout_of(param_ty)
             .map_err(|_| {
-                LitToConstError::Reported(tcx.sess.delay_span_bug(
+                LitToConstError::Reported(tcx.sess.span_delayed_bug(
                     DUMMY_SP,
                     format!("couldn't compute width of literal: {:?}", lit_input.lit),
                 ))
@@ -62,7 +62,7 @@ pub(crate) fn lit_to_const<'tcx>(
         (ast::LitKind::Float(n, _), ty::Float(fty)) => {
             let bits = parse_float_into_scalar(*n, *fty, neg)
                 .ok_or_else(|| {
-                    LitToConstError::Reported(tcx.sess.delay_span_bug(
+                    LitToConstError::Reported(tcx.sess.span_delayed_bug(
                         DUMMY_SP,
                         format!("couldn't parse float literal: {:?}", lit_input.lit),
                     ))
@@ -73,7 +73,7 @@ pub(crate) fn lit_to_const<'tcx>(
         (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
         (ast::LitKind::Err, _) => {
             return Err(LitToConstError::Reported(
-                tcx.sess.delay_span_bug(DUMMY_SP, "encountered LitKind::Err during mir build"),
+                tcx.sess.span_delayed_bug(DUMMY_SP, "encountered LitKind::Err during mir build"),
             ));
         }
         _ => return Err(LitToConstError::TypeError),
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 5edb2054fd4..eb548ad29eb 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -108,7 +108,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     let msg = format!(
                         "found bad range pattern endpoint `{expr:?}` outside of error recovery"
                     );
-                    return Err(self.tcx.sess.delay_span_bug(expr.span, msg));
+                    return Err(self.tcx.sess.span_delayed_bug(expr.span, msg));
                 };
                 Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const))
             }
@@ -178,7 +178,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     ) -> Result<PatKind<'tcx>, ErrorGuaranteed> {
         if lo_expr.is_none() && hi_expr.is_none() {
             let msg = format!("found twice-open range pattern (`..`) outside of error recovery");
-            return Err(self.tcx.sess.delay_span_bug(span, msg));
+            return Err(self.tcx.sess.span_delayed_bug(span, msg));
         }
 
         let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?;
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index 84e7362c3d0..f246de55ca8 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -242,7 +242,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
                     let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
                     if assigned_ty.needs_drop(self.tcx, self.param_env) {
                         // This would be unsafe, but should be outright impossible since we reject such unions.
-                        self.tcx.sess.delay_span_bug(
+                        self.tcx.sess.span_delayed_bug(
                             self.source_info.span,
                             format!("union fields that need dropping should be impossible: {assigned_ty}")
                         );
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index d626fed3275..1373596fd2b 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -1510,8 +1510,10 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
                 (args.discr_ty(tcx), movability == hir::Movability::Movable)
             }
             _ => {
-                tcx.sess
-                    .delay_span_bug(body.span, format!("unexpected coroutine type {coroutine_ty}"));
+                tcx.sess.span_delayed_bug(
+                    body.span,
+                    format!("unexpected coroutine type {coroutine_ty}"),
+                );
                 return;
             }
         };
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 83517aef7e2..f7188ea83fc 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -316,7 +316,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                     self.init_data.seek_before(self.body.terminator_loc(bb));
                     let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent);
                     if maybe_dead {
-                        self.tcx.sess.delay_span_bug(
+                        self.tcx.sess.span_delayed_bug(
                             terminator.source_info.span,
                             format!(
                                 "drop of untracked, uninitialized value {bb:?}, place {place:?} ({path:?})"
@@ -381,7 +381,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                 LookupResult::Parent(None) => {}
                 LookupResult::Parent(Some(_)) => {
                     if !replace {
-                        self.tcx.sess.delay_span_bug(
+                        self.tcx.sess.span_delayed_bug(
                             terminator.source_info.span,
                             format!("drop of untracked value {bb:?}"),
                         );
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index fff760ba399..89e897191e8 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -266,7 +266,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
     let body = &tcx.mir_const(def).borrow();
 
     if body.return_ty().references_error() {
-        tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
+        tcx.sess.span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
         return Default::default();
     }
 
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 6e0765f74fe..92df2da8710 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -223,9 +223,6 @@ impl<'a> StringReader<'a> {
                 rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
                     let suffix_start = start + BytePos(suffix_start);
                     let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
-                    if let token::LitKind::CStr | token::LitKind::CStrRaw(_) = kind {
-                        self.sess.gated_spans.gate(sym::c_str_literals, self.mk_sp(start, self.pos));
-                    }
                     let suffix = if suffix_start < self.pos {
                         let string = self.str_from(suffix_start);
                         if string == "_" {
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index bad7c19cc27..422bb79308d 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -56,7 +56,7 @@ impl<'a> Parser<'a> {
             } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
                 if attr_style != ast::AttrStyle::Outer {
                     let span = self.token.span;
-                    let mut err = self.sess.span_diagnostic.struct_span_err_with_code(
+                    let mut err = self.diagnostic().struct_span_err_with_code(
                         span,
                         fluent::parse_inner_doc_comment_not_permitted,
                         error_code!(E0753),
@@ -418,7 +418,7 @@ impl<'a> Parser<'a> {
         }
 
         Err(InvalidMetaItem { span: self.token.span, token: self.token.clone() }
-            .into_diagnostic(&self.sess.span_diagnostic))
+            .into_diagnostic(self.diagnostic()))
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index c4e8d9006e6..c66a7176aab 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -41,7 +41,7 @@ impl AttrWrapper {
     }
 
     pub(crate) fn take_for_recovery(self, sess: &ParseSess) -> AttrVec {
-        sess.span_diagnostic.delay_span_bug(
+        sess.span_diagnostic.span_delayed_bug(
             self.attrs.get(0).map(|attr| attr.span).unwrap_or(DUMMY_SP),
             "AttrVec is taken for recovery but no error is produced",
         );
@@ -266,9 +266,8 @@ impl<'a> Parser<'a> {
             if let Some(attr_range) = self.capture_state.inner_attr_ranges.remove(&inner_attr.id) {
                 inner_attr_replace_ranges.push(attr_range);
             } else {
-                self.sess
-                    .span_diagnostic
-                    .delay_span_bug(inner_attr.span, "Missing token range for attribute");
+                self.diagnostic()
+                    .span_delayed_bug(inner_attr.span, "Missing token range for attribute");
             }
         }
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 8921c1c6a03..a4eb36dd92c 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -247,11 +247,11 @@ impl<'a> Parser<'a> {
         sp: S,
         m: impl Into<DiagnosticMessage>,
     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
-        self.sess.span_diagnostic.struct_span_err(sp, m)
+        self.diagnostic().struct_span_err(sp, m)
     }
 
     pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: impl Into<String>) -> ! {
-        self.sess.span_diagnostic.span_bug(sp, m)
+        self.diagnostic().span_bug(sp, m)
     }
 
     pub(super) fn diagnostic(&self) -> &'a Handler {
@@ -285,7 +285,7 @@ impl<'a> Parser<'a> {
                 span: self.prev_token.span,
                 missing_comma: None,
             }
-            .into_diagnostic(&self.sess.span_diagnostic));
+            .into_diagnostic(self.diagnostic()));
         }
 
         let valid_follow = &[
@@ -348,7 +348,7 @@ impl<'a> Parser<'a> {
             suggest_remove_comma,
             help_cannot_start_number,
         };
-        let mut err = err.into_diagnostic(&self.sess.span_diagnostic);
+        let mut err = err.into_diagnostic(self.diagnostic());
 
         // if the token we have is a `<`
         // it *might* be a misplaced generic
@@ -1426,7 +1426,7 @@ impl<'a> Parser<'a> {
                                 // Not entirely sure now, but we bubble the error up with the
                                 // suggestion.
                                 self.restore_snapshot(snapshot);
-                                Err(err.into_diagnostic(&self.sess.span_diagnostic))
+                                Err(err.into_diagnostic(self.diagnostic()))
                             }
                         }
                     } else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind {
@@ -1441,7 +1441,7 @@ impl<'a> Parser<'a> {
                         }
                         // Consume the fn call arguments.
                         match self.consume_fn_args() {
-                            Err(()) => Err(err.into_diagnostic(&self.sess.span_diagnostic)),
+                            Err(()) => Err(err.into_diagnostic(self.diagnostic())),
                             Ok(()) => {
                                 self.sess.emit_err(err);
                                 // FIXME: actually check that the two expressions in the binop are
@@ -1467,7 +1467,7 @@ impl<'a> Parser<'a> {
                             mk_err_expr(self, inner_op.span.to(self.prev_token.span))
                         } else {
                             // These cases cause too many knock-down errors, bail out (#61329).
-                            Err(err.into_diagnostic(&self.sess.span_diagnostic))
+                            Err(err.into_diagnostic(self.diagnostic()))
                         }
                     };
                 }
@@ -2522,8 +2522,7 @@ impl<'a> Parser<'a> {
             Ok(Some(GenericArg::Const(self.parse_const_arg()?)))
         } else {
             let after_kw_const = self.token.span;
-            self.recover_const_arg(after_kw_const, err.into_diagnostic(&self.sess.span_diagnostic))
-                .map(Some)
+            self.recover_const_arg(after_kw_const, err.into_diagnostic(self.diagnostic())).map(Some)
         }
     }
 
@@ -2886,7 +2885,7 @@ impl<'a> Parser<'a> {
                         span: path.span.shrink_to_hi(),
                         between: between_span,
                     }
-                    .into_diagnostic(&self.sess.span_diagnostic));
+                    .into_diagnostic(self.diagnostic()));
                 }
             }
         }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index b1b77305e4f..f8444881d1a 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1269,7 +1269,7 @@ impl<'a> Parser<'a> {
                                         .collect(),
                                 },
                             }
-                            .into_diagnostic(&self.sess.span_diagnostic);
+                            .into_diagnostic(self.diagnostic());
                             replacement_err.emit();
 
                             let old_err = mem::replace(err, replacement_err);
@@ -1691,7 +1691,7 @@ impl<'a> Parser<'a> {
         err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>,
     ) -> L {
         if let Some(mut diag) =
-            self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
+            self.diagnostic().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
         {
             diag.span_suggestion_verbose(
                 lifetime.span.shrink_to_hi(),
@@ -1882,7 +1882,7 @@ impl<'a> Parser<'a> {
 
         let Some((ident, false)) = self.token.ident() else {
             let err = errors::ExpectedBuiltinIdent { span: self.token.span }
-                .into_diagnostic(&self.sess.span_diagnostic);
+                .into_diagnostic(self.diagnostic());
             return Err(err);
         };
         self.sess.gated_spans.gate(sym::builtin_syntax, ident.span);
@@ -1893,7 +1893,7 @@ impl<'a> Parser<'a> {
             Ok(res)
         } else {
             let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name }
-                .into_diagnostic(&self.sess.span_diagnostic);
+                .into_diagnostic(self.diagnostic());
             return Err(err);
         };
         self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?;
@@ -1957,7 +1957,7 @@ impl<'a> Parser<'a> {
             && matches!(e.kind, ExprKind::Err)
         {
             let mut err = errors::InvalidInterpolatedExpression { span: self.token.span }
-                .into_diagnostic(&self.sess.span_diagnostic);
+                .into_diagnostic(self.diagnostic());
             err.downgrade_to_delayed_bug();
             return Err(err);
         }
@@ -2169,7 +2169,7 @@ impl<'a> Parser<'a> {
                     return Err(errors::MissingSemicolonBeforeArray {
                         open_delim: open_delim_span,
                         semicolon: prev_span.shrink_to_hi(),
-                    }.into_diagnostic(&self.sess.span_diagnostic));
+                    }.into_diagnostic(self.diagnostic()));
                 }
                 Ok(_) => (),
                 Err(err) => err.cancel(),
@@ -2309,7 +2309,7 @@ impl<'a> Parser<'a> {
             if self.check_keyword(kw::Async) {
                 let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
                 Err(errors::AsyncMoveOrderIncorrect { span: move_async_span }
-                    .into_diagnostic(&self.sess.span_diagnostic))
+                    .into_diagnostic(self.diagnostic()))
             } else {
                 Ok(CaptureBy::Value { move_kw: move_kw_span })
             }
@@ -2499,7 +2499,7 @@ impl<'a> Parser<'a> {
             };
             if self.prev_token.kind == token::BinOp(token::Or) {
                 // This was part of a closure, the that part of the parser recover.
-                return Err(err.into_diagnostic(&self.sess.span_diagnostic));
+                return Err(err.into_diagnostic(self.diagnostic()));
             } else {
                 Some(self.sess.emit_err(err))
             }
@@ -3148,7 +3148,7 @@ impl<'a> Parser<'a> {
         let (attrs, body) = self.parse_inner_attrs_and_block()?;
         if self.eat_keyword(kw::Catch) {
             Err(errors::CatchAfterTry { span: self.prev_token.span }
-                .into_diagnostic(&self.sess.span_diagnostic))
+                .into_diagnostic(self.diagnostic()))
         } else {
             let span = span_lo.to(body.span);
             self.sess.gated_spans.gate(sym::try_blocks, span);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index ab18e40482e..a737f37a104 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -444,11 +444,7 @@ impl<'a> Parser<'a> {
             None
         };
 
-        if let Some(err) = err {
-            Err(err.into_diagnostic(&self.sess.span_diagnostic))
-        } else {
-            Ok(())
-        }
+        if let Some(err) = err { Err(err.into_diagnostic(self.diagnostic())) } else { Ok(()) }
     }
 
     fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
@@ -1382,8 +1378,7 @@ impl<'a> Parser<'a> {
 
         let span = self.prev_token.span.shrink_to_hi();
         let err: DiagnosticBuilder<'_, ErrorGuaranteed> =
-            errors::MissingConstType { span, colon, kind }
-                .into_diagnostic(&self.sess.span_diagnostic);
+            errors::MissingConstType { span, colon, kind }.into_diagnostic(self.diagnostic());
         err.stash(span, StashKey::ItemNoType);
 
         // The user intended that the type be inferred,
@@ -1400,7 +1395,7 @@ impl<'a> Parser<'a> {
                 self.bump();
                 self.sess.emit_err(err);
             } else {
-                return Err(err.into_diagnostic(&self.sess.span_diagnostic));
+                return Err(err.into_diagnostic(self.diagnostic()));
             }
         }
 
@@ -1600,7 +1595,7 @@ impl<'a> Parser<'a> {
         } else {
             let err =
                 errors::UnexpectedTokenAfterStructName::new(self.token.span, self.token.clone());
-            return Err(err.into_diagnostic(&self.sess.span_diagnostic));
+            return Err(err.into_diagnostic(self.diagnostic()));
         };
 
         Ok((class_name, ItemKind::Struct(vdata, generics)))
@@ -1796,7 +1791,7 @@ impl<'a> Parser<'a> {
                         let sp = previous_span.shrink_to_hi();
                         err.missing_comma = Some(sp);
                     }
-                    return Err(err.into_diagnostic(&self.sess.span_diagnostic));
+                    return Err(err.into_diagnostic(self.diagnostic()));
                 }
             }
             _ => {
@@ -1846,7 +1841,7 @@ impl<'a> Parser<'a> {
                     // Make sure an error was emitted (either by recovering an angle bracket,
                     // or by finding an identifier as the next token), since we're
                     // going to continue parsing
-                    assert!(self.sess.span_diagnostic.has_errors().is_some());
+                    assert!(self.diagnostic().has_errors().is_some());
                 } else {
                     return Err(err);
                 }
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 06cc39fbb5a..4360a69e501 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -115,7 +115,7 @@ impl<'a> Parser<'a> {
                 Some(item) => NtItem(item),
                 None => {
                     return Err(UnexpectedNonterminal::Item(self.token.span)
-                        .into_diagnostic(&self.sess.span_diagnostic));
+                        .into_diagnostic(self.diagnostic()));
                 }
             },
             NonterminalKind::Block => {
@@ -127,7 +127,7 @@ impl<'a> Parser<'a> {
                 Some(s) => NtStmt(P(s)),
                 None => {
                     return Err(UnexpectedNonterminal::Statement(self.token.span)
-                        .into_diagnostic(&self.sess.span_diagnostic));
+                        .into_diagnostic(self.diagnostic()));
                 }
             },
             NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => {
@@ -163,7 +163,7 @@ impl<'a> Parser<'a> {
                     span: self.token.span,
                     token: self.token.clone(),
                 }
-                .into_diagnostic(&self.sess.span_diagnostic));
+                .into_diagnostic(self.diagnostic()));
             }
             NonterminalKind::Path => {
                 NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?))
@@ -181,7 +181,7 @@ impl<'a> Parser<'a> {
                         span: self.token.span,
                         token: self.token.clone(),
                     }
-                    .into_diagnostic(&self.sess.span_diagnostic));
+                    .into_diagnostic(self.diagnostic()));
                 }
             }
         };
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 3d1d1ec8108..bd1bf2c7859 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -877,7 +877,7 @@ impl<'a> Parser<'a> {
         // will direct us over to `parse_enum_variant()`.
         if self.token == token::OpenDelim(Delimiter::Parenthesis) {
             return Err(EnumPatternInsteadOfIdentifier { span: self.prev_token.span }
-                .into_diagnostic(&self.sess.span_diagnostic));
+                .into_diagnostic(self.diagnostic()));
         }
 
         Ok(PatKind::Ident(binding_annotation, ident, sub))
@@ -991,7 +991,7 @@ impl<'a> Parser<'a> {
             // check that a comma comes after every field
             if !ate_comma {
                 let mut err = ExpectedCommaAfterPatternField { span: self.token.span }
-                    .into_diagnostic(&self.sess.span_diagnostic);
+                    .into_diagnostic(self.diagnostic());
                 if let Some(mut delayed) = delayed_err {
                     delayed.emit();
                 }
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index f825363ae39..18a80aa34f8 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -31,7 +31,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
 
         if !errors.is_empty() {
             let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
-            tcx.sess.delay_span_bug(rustc_span::DUMMY_SP, message);
+            tcx.sess.span_delayed_bug(rustc_span::DUMMY_SP, message);
         }
     }
 }
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index a0ba4e481f6..c9e5eb50b3a 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -592,7 +592,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         match self.successors[ln] {
             Some(successor) => self.assigned_on_entry(successor, var),
             None => {
-                self.ir.tcx.sess.delay_span_bug(DUMMY_SP, "no successor");
+                self.ir.tcx.sess.span_delayed_bug(DUMMY_SP, "no successor");
                 true
             }
         }
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index b8109d5bb06..e7ec4749efe 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -888,21 +888,6 @@ pub struct TestReachabilityVisitor<'tcx, 'a> {
     effective_visibilities: &'a EffectiveVisibilities,
 }
 
-fn vis_to_string<'tcx>(def_id: LocalDefId, vis: ty::Visibility, tcx: TyCtxt<'tcx>) -> String {
-    match vis {
-        ty::Visibility::Restricted(restricted_id) => {
-            if restricted_id.is_top_level_module() {
-                "pub(crate)".to_string()
-            } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
-                "pub(self)".to_string()
-            } else {
-                format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
-            }
-        }
-        ty::Visibility::Public => "pub".to_string(),
-    }
-}
-
 impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
     fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
         if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) {
@@ -910,7 +895,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
             let span = self.tcx.def_span(def_id.to_def_id());
             if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {
                 for level in Level::all_levels() {
-                    let vis_str = vis_to_string(def_id, *effective_vis.at_level(level), self.tcx);
+                    let vis_str = effective_vis.at_level(level).to_string(def_id, self.tcx);
                     if level != Level::Direct {
                         error_msg.push_str(", ");
                     }
@@ -1268,7 +1253,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
                 } else {
                     self.tcx
                         .sess
-                        .delay_span_bug(expr.span, "no type-dependent def for method call");
+                        .span_delayed_bug(expr.span, "no type-dependent def for method call");
                 }
             }
             _ => {}
@@ -1506,11 +1491,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
                         tcx: self.tcx,
                     })
                         .into(),
-                    item_vis_descr: &vis_to_string(self.item_def_id, reachable_at_vis, self.tcx),
+                    item_vis_descr: &reachable_at_vis.to_string(self.item_def_id, self.tcx),
                     ty_span: vis_span,
                     ty_kind: kind,
                     ty_descr: descr.into(),
-                    ty_vis_descr: &vis_to_string(local_def_id, vis, self.tcx),
+                    ty_vis_descr: &vis.to_string(local_def_id, self.tcx),
                 },
             );
         }
@@ -1589,8 +1574,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
                     span,
                     kind: self.tcx.def_descr(def_id.to_def_id()),
                     descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(),
-                    reachable_vis: &vis_to_string(def_id, *reachable_at_vis, self.tcx),
-                    reexported_vis: &vis_to_string(def_id, *reexported_at_vis, self.tcx),
+                    reachable_vis: &reachable_at_vis.to_string(def_id, self.tcx),
+                    reexported_vis: &reexported_at_vis.to_string(def_id, self.tcx),
                 },
             );
         }
@@ -1843,7 +1828,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
                             ..
                         }) => tr.path.res.opt_def_id().map_or_else(
                             || {
-                                tcx.sess.delay_span_bug(tr.path.span, "trait without a def-id");
+                                tcx.sess.span_delayed_bug(tr.path.span, "trait without a def-id");
                                 ty::Visibility::Public
                             },
                             |def_id| tcx.visibility(def_id).expect_local(),
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 5acd012ef04..bc09972185a 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -818,7 +818,7 @@ impl<D: Deps> DepGraphData<D> {
             None => {}
         }
 
-        if let None = qcx.dep_context().sess().has_errors_or_delayed_span_bugs() {
+        if let None = qcx.dep_context().sess().has_errors_or_span_delayed_bugs() {
             panic!("try_mark_previous_green() - Forcing the DepNode should have set its color")
         }
 
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 2a55ec72c5f..d933f897833 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -605,7 +605,7 @@ pub(crate) fn report_cycle<'a>(
         note_span: (),
     };
 
-    cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic)
+    cycle_diag.into_diagnostic(sess.diagnostic())
 }
 
 pub fn print_query_stack<Qcx: QueryContext>(
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 2f9f094dae2..41638b38c74 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -138,7 +138,7 @@ where
                 && let Some(span) = root.query.span
             {
                 error.stash(span, StashKey::Cycle);
-                qcx.dep_context().sess().delay_span_bug(span, "delayed cycle error")
+                qcx.dep_context().sess().span_delayed_bug(span, "delayed cycle error")
             } else {
                 error.emit()
             };
@@ -421,7 +421,7 @@ where
                 // We have an inconsistency. This can happen if one of the two
                 // results is tainted by errors. In this case, delay a bug to
                 // ensure compilation is doomed.
-                qcx.dep_context().sess().delay_span_bug(
+                qcx.dep_context().sess().span_delayed_bug(
                     DUMMY_SP,
                     format!(
                         "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 272483d4a98..a5faaaab639 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -127,8 +127,6 @@ resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here
 
 resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
 
-resolve_glob_import_doesnt_reexport =
-    glob import doesn't reexport anything because no candidate is public enough
 
 resolve_ident_bound_more_than_once_in_parameter_list =
     identifier `{$identifier}` is bound more than once in this parameter list
@@ -200,7 +198,7 @@ resolve_param_in_non_trivial_anon_const =
     .label = cannot perform const operation using `{$name}`
 
 resolve_param_in_non_trivial_anon_const_help =
-    use `#![feature(generic_const_exprs)]` to allow generic const expressions
+    add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 resolve_param_in_ty_of_const_param =
     the type of const parameters must not depend on other generic parameters
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index a069c6f8e04..a9f7002e564 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1201,7 +1201,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                             }
                                         };
                                         self.report_error(span, error);
-                                        self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
+                                        self.tcx.sess.span_delayed_bug(span, CG_BUG_STR);
                                     }
 
                                     return Res::Err;
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 3774ae66420..b28ad671f12 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -8,7 +8,7 @@ use crate::errors::{
     ItemsInTraitsAreNotImportable,
 };
 use crate::Determinacy::{self, *};
-use crate::{fluent_generated as fluent, Namespace::*};
+use crate::Namespace::*;
 use crate::{module_to_string, names_to_string, ImportSuggestion};
 use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
@@ -987,13 +987,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                     if !is_prelude
                         && let Some(max_vis) = max_vis.get()
-                        && !max_vis.is_at_least(import.expect_vis(), self.tcx)
+                        && let import_vis = import.expect_vis()
+                        && !max_vis.is_at_least(import_vis, self.tcx)
                     {
-                        self.lint_buffer.buffer_lint(
+                        let def_id = self.local_def_id(id);
+                        let msg = format!(
+                            "glob import doesn't reexport anything with visibility `{}` because no imported item is public enough",
+                            import_vis.to_string(def_id, self.tcx)
+                        );
+                        self.lint_buffer.buffer_lint_with_diagnostic(
                             UNUSED_IMPORTS,
                             id,
                             import.span,
-                            fluent::resolve_glob_import_doesnt_reexport,
+                            msg.to_string(),
+                            BuiltinLintDiagnostics::RedundantImportVisibility {
+                                max_vis: max_vis.to_string(def_id, self.tcx),
+                                span: import.span,
+                            },
                         );
                     }
                     return None;
@@ -1059,7 +1069,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         if res == Res::Err || has_ambiguity_error {
                             this.tcx
                                 .sess
-                                .delay_span_bug(import.span, "some error happened for an import");
+                                .span_delayed_bug(import.span, "some error happened for an import");
                             return;
                         }
                         if let Ok(initial_res) = initial_res {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 75a0541b89b..f20d5829030 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3544,7 +3544,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             Res::SelfCtor(_) => {
                 // We resolve `Self` in pattern position as an ident sometimes during recovery,
                 // so delay a bug instead of ICEing.
-                self.r.tcx.sess.delay_span_bug(
+                self.r.tcx.sess.span_delayed_bug(
                     ident.span,
                     "unexpected `SelfCtor` in pattern, expected identifier"
                 );
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 5f21741223b..ca225416e36 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -710,7 +710,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // Make sure compilation does not succeed if preferred macro resolution
                     // has changed after the macro had been expanded. In theory all such
                     // situations should be reported as errors, so this is a bug.
-                    this.tcx.sess.delay_span_bug(span, "inconsistent resolution for a macro");
+                    this.tcx.sess.span_delayed_bug(span, "inconsistent resolution for a macro");
                 }
             } else {
                 // It's possible that the macro was unresolved (indeterminate) and silently
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 77874bd9c07..e694e150b31 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -8,23 +8,19 @@ use crate::search_paths::SearchPath;
 use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
 use crate::{lint, HashStableContext};
 use crate::{EarlyErrorHandler, Session};
-
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
-use rustc_target::abi::Align;
-use rustc_target::spec::LinkSelfContainedComponents;
-use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
-use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
-
+use rustc_errors::emitter::HumanReadableErrorType;
+use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg};
 use rustc_feature::UnstableFeatures;
 use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
 use rustc_span::source_map::FilePathMapping;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
-
-use rustc_errors::emitter::HumanReadableErrorType;
-use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg};
-
+use rustc_target::abi::Align;
+use rustc_target::spec::LinkSelfContainedComponents;
+use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
+use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
 use std::collections::btree_map::{
     Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
 };
@@ -555,12 +551,15 @@ impl Default for ErrorOutputType {
 /// Parameter to control path trimming.
 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
 pub enum TrimmedDefPaths {
-    /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive query
+    /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive
+    /// query.
     #[default]
     Never,
-    /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call `delay_good_path_bug`
+    /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call
+    /// `good_path_delayed_bug`.
     Always,
-    /// `try_print_trimmed_def_path` calls the expensive query, the query calls `delay_good_path_bug`
+    /// `try_print_trimmed_def_path` calls the expensive query, the query calls
+    /// `good_path_delayed_bug`.
     GoodPath,
 }
 
@@ -1250,7 +1249,7 @@ fn default_configuration(sess: &Session) -> Cfg {
     // NOTE: This should be kept in sync with `CheckCfg::fill_well_known` below.
     let end = &sess.target.endian;
     let arch = &sess.target.arch;
-    let wordsz = sess.target.pointer_width.to_string();
+    let wordsz = sess.target.pointer_width as u64;
     let os = &sess.target.os;
     let env = &sess.target.env;
     let abi = &sess.target.abi;
@@ -1277,7 +1276,7 @@ fn default_configuration(sess: &Session) -> Cfg {
     }
     ret.insert((sym::target_arch, Some(Symbol::intern(arch))));
     ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
-    ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
+    ret.insert((sym::target_pointer_width, Some(sym::integer(wordsz))));
     ret.insert((sym::target_env, Some(Symbol::intern(env))));
     ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
     if sess.is_nightly_build() {
@@ -1297,19 +1296,18 @@ fn default_configuration(sess: &Session) -> Cfg {
     ] {
         if i >= min_atomic_width && i <= max_atomic_width {
             has_atomic = true;
-            let mut insert_atomic = |s, align: Align| {
-                ret.insert((sym::target_has_atomic_load_store, Some(Symbol::intern(s))));
+            let mut insert_atomic = |sym, align: Align| {
+                ret.insert((sym::target_has_atomic_load_store, Some(sym)));
                 if atomic_cas {
-                    ret.insert((sym::target_has_atomic, Some(Symbol::intern(s))));
+                    ret.insert((sym::target_has_atomic, Some(sym)));
                 }
                 if align.bits() == i {
-                    ret.insert((sym::target_has_atomic_equal_alignment, Some(Symbol::intern(s))));
+                    ret.insert((sym::target_has_atomic_equal_alignment, Some(sym)));
                 }
             };
-            let s = i.to_string();
-            insert_atomic(&s, align);
-            if s == wordsz {
-                insert_atomic("ptr", layout.pointer_align.abi);
+            insert_atomic(sym::integer(i), align);
+            if wordsz == i {
+                insert_atomic(sym::ptr, layout.pointer_align.abi);
             }
         }
     }
@@ -2150,25 +2148,27 @@ fn collect_print_requests(
     }
 
     const PRINT_KINDS: &[(&str, PrintKind)] = &[
+        // tidy-alphabetical-start
+        ("all-target-specs-json", PrintKind::AllTargetSpecs),
+        ("calling-conventions", PrintKind::CallingConventions),
+        ("cfg", PrintKind::Cfg),
+        ("code-models", PrintKind::CodeModels),
         ("crate-name", PrintKind::CrateName),
+        ("deployment-target", PrintKind::DeploymentTarget),
         ("file-names", PrintKind::FileNames),
+        ("link-args", PrintKind::LinkArgs),
+        ("native-static-libs", PrintKind::NativeStaticLibs),
+        ("relocation-models", PrintKind::RelocationModels),
+        ("split-debuginfo", PrintKind::SplitDebuginfo),
+        ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
         ("sysroot", PrintKind::Sysroot),
-        ("target-libdir", PrintKind::TargetLibdir),
-        ("cfg", PrintKind::Cfg),
-        ("calling-conventions", PrintKind::CallingConventions),
-        ("target-list", PrintKind::TargetList),
         ("target-cpus", PrintKind::TargetCPUs),
         ("target-features", PrintKind::TargetFeatures),
-        ("relocation-models", PrintKind::RelocationModels),
-        ("code-models", PrintKind::CodeModels),
-        ("tls-models", PrintKind::TlsModels),
-        ("native-static-libs", PrintKind::NativeStaticLibs),
-        ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
+        ("target-libdir", PrintKind::TargetLibdir),
+        ("target-list", PrintKind::TargetList),
         ("target-spec-json", PrintKind::TargetSpec),
-        ("all-target-specs-json", PrintKind::AllTargetSpecs),
-        ("link-args", PrintKind::LinkArgs),
-        ("split-debuginfo", PrintKind::SplitDebuginfo),
-        ("deployment-target", PrintKind::DeploymentTarget),
+        ("tls-models", PrintKind::TlsModels),
+        // tidy-alphabetical-end
     ];
 
     // We disallow reusing the same path in multiple prints, such as `--print
@@ -2297,14 +2297,7 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf
     if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
 }
 
-fn select_debuginfo_compression(
-    _handler: &EarlyErrorHandler,
-    unstable_opts: &UnstableOptions,
-) -> DebugInfoCompression {
-    unstable_opts.debuginfo_compression
-}
-
-pub(crate) fn parse_assert_incr_state(
+fn parse_assert_incr_state(
     handler: &EarlyErrorHandler,
     opt_assertion: &Option<String>,
 ) -> Option<IncrementalStateAssertion> {
@@ -2460,6 +2453,17 @@ pub fn parse_externs(
     matches: &getopts::Matches,
     unstable_opts: &UnstableOptions,
 ) -> Externs {
+    fn is_ascii_ident(string: &str) -> bool {
+        let mut chars = string.chars();
+        if let Some(start) = chars.next()
+            && (start.is_ascii_alphabetic() || start == '_')
+        {
+            chars.all(|char| char.is_ascii_alphanumeric() || char == '_')
+        } else {
+            false
+        }
+    }
+
     let is_unstable_enabled = unstable_opts.unstable_options;
     let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
     for arg in matches.opt_strs("extern") {
@@ -2472,12 +2476,12 @@ pub fn parse_externs(
             Some((opts, name)) => (Some(opts), name.to_string()),
         };
 
-        if !crate::utils::is_ascii_ident(&name) {
+        if !is_ascii_ident(&name) {
             let mut error = handler.early_struct_error(format!(
                 "crate name `{name}` passed to `--extern` is not a valid ASCII identifier"
             ));
             let adjusted_name = name.replace('-', "_");
-            if crate::utils::is_ascii_ident(&adjusted_name) {
+            if is_ascii_ident(&adjusted_name) {
                 error.help(format!(
                     "consider replacing the dashes with underscores: `{adjusted_name}`"
                 ));
@@ -2791,8 +2795,7 @@ pub fn build_session_options(
     // for more details.
     let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
     let debuginfo = select_debuginfo(matches, &cg);
-    let debuginfo_compression: DebugInfoCompression =
-        select_debuginfo_compression(handler, &unstable_opts);
+    let debuginfo_compression = unstable_opts.debuginfo_compression;
 
     let mut search_paths = vec![];
     for s in &matches.opt_strs("L") {
@@ -3143,6 +3146,12 @@ impl PpMode {
     }
 }
 
+#[derive(Clone, Hash, PartialEq, Eq, Debug)]
+pub enum WasiExecModel {
+    Command,
+    Reactor,
+}
+
 /// Command-line arguments passed to the compiler have to be incorporated with
 /// the dependency tracking system for incremental compilation. This module
 /// provides some utilities to make this more convenient.
@@ -3168,9 +3177,9 @@ pub(crate) mod dep_tracking {
         LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType,
         OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
         SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
+        WasiExecModel,
     };
     use crate::lint;
-    use crate::options::WasiExecModel;
     use crate::utils::NativeLib;
     use rustc_data_structures::stable_hasher::Hash64;
     use rustc_errors::LanguageIdentifier;
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index d816842b02b..a0f5eb59b6a 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -6,7 +6,6 @@ use crate::search_paths::PathKind;
 use crate::utils::NativeLibKind;
 use crate::Session;
 use rustc_ast as ast;
-use rustc_data_structures::owned_slice::OwnedSlice;
 use rustc_data_structures::sync::{self, AppendOnlyIndexVec, FreezeLock};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
@@ -14,10 +13,9 @@ use rustc_span::hygiene::{ExpnHash, ExpnId};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
-use rustc_target::spec::Target;
 
 use std::any::Any;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 
 // lonely orphan structs and enums looking for a better home
 
@@ -197,21 +195,6 @@ pub enum ExternCrateSource {
     Path,
 }
 
-/// The backend's way to give the crate store access to the metadata in a library.
-/// Note that it returns the raw metadata bytes stored in the library file, whether
-/// it is compressed, uncompressed, some weird mix, etc.
-/// rmeta files are backend independent and not handled here.
-///
-/// At the time of this writing, there is only one backend and one way to store
-/// metadata in library -- this trait just serves to decouple rustc_metadata from
-/// the archive reader, which depends on LLVM.
-pub trait MetadataLoader: std::fmt::Debug {
-    fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
-    fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
-}
-
-pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync;
-
 /// A store of Rust crates, through which their metadata can be accessed.
 ///
 /// Note that this trait should probably not be expanding today. All new
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 3988416d0c7..6e459ac45d3 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -9,12 +9,6 @@ use std::path::{Path, PathBuf};
 use crate::search_paths::{PathKind, SearchPath};
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
 
-#[derive(Copy, Clone)]
-pub enum FileMatch {
-    FileMatches,
-    FileDoesntMatch,
-}
-
 #[derive(Clone)]
 pub struct FileSearch<'a> {
     sysroot: &'a Path,
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index ffc2a250681..0b55af2f73b 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,6 +1,4 @@
-#![feature(if_let_guard)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(lazy_cell)]
 #![feature(option_get_or_insert_default)]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 68a39de73b7..7a6108bfbe2 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1813,7 +1813,7 @@ options! {
         "directory into which to write optimization remarks (if not specified, they will be \
 written to standard error output)"),
     report_delayed_bugs: bool = (false, parse_bool, [TRACKED],
-        "immediately print bugs registered with `delay_span_bug` (default: no)"),
+        "immediately print bugs registered with `span_delayed_bug` (default: no)"),
     sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
         "use a sanitizer"),
     sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED],
@@ -1985,9 +1985,3 @@ written to standard error output)"),
     // - compiler/rustc_interface/src/tests.rs
     // - src/doc/unstable-book/src/compiler-flags
 }
-
-#[derive(Clone, Hash, PartialEq, Eq, Debug)]
-pub enum WasiExecModel {
-    Command,
-    Reactor,
-}
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index 9cd96895a61..2ff32b5bb9a 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -1,4 +1,4 @@
-//! Related to out filenames of compilation (e.g. save analysis, binaries).
+//! Related to out filenames of compilation (e.g. binaries).
 use crate::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
 use crate::errors::{
     CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable,
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 4d20d6d4187..f7b33cb598b 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -214,7 +214,7 @@ pub struct ParseSess {
     pub assume_incomplete_release: bool,
     /// Spans passed to `proc_macro::quote_span`. Each span has a numerical
     /// identifier represented by its position in the vector.
-    pub proc_macro_quoted_spans: AppendOnlyVec<Span>,
+    proc_macro_quoted_spans: AppendOnlyVec<Span>,
     /// Used to generate new `AttrId`s. Every `AttrId` is unique.
     pub attr_id_generator: AttrIdGenerator,
 }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index e79d7648bef..c6f435a8f92 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -10,8 +10,6 @@ use crate::parse::{add_feature_diagnostics, ParseSess};
 use crate::search_paths::{PathKind, SearchPath};
 use crate::{filesearch, lint};
 
-pub use rustc_ast::attr::MarkedAttrs;
-pub use rustc_ast::Attribute;
 use rustc_data_structures::flock;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::jobserver::{self, Client};
@@ -48,7 +46,7 @@ use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::sync::{atomic::AtomicBool, Arc};
 
-pub struct OptimizationFuel {
+struct OptimizationFuel {
     /// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`.
     remaining: u64,
     /// We're rejecting all further optimizations.
@@ -304,7 +302,7 @@ impl Session {
         if diags.is_empty() {
             return;
         }
-        self.parse_sess.span_diagnostic.emit_future_breakage_report(diags);
+        self.diagnostic().emit_future_breakage_report(diags);
     }
 
     /// Returns true if the crate is a testing one.
@@ -480,7 +478,7 @@ impl Session {
         sp: S,
         msg: impl Into<DiagnosticMessage>,
         code: DiagnosticId,
-    ) {
+    ) -> ErrorGuaranteed {
         self.diagnostic().span_err_with_code(sp, msg, code)
     }
     #[rustc_lint_diagnostics]
@@ -553,8 +551,8 @@ impl Session {
     pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
         self.diagnostic().has_errors()
     }
-    pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> {
-        self.diagnostic().has_errors_or_delayed_span_bugs()
+    pub fn has_errors_or_span_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
+        self.diagnostic().has_errors_or_span_delayed_bugs()
     }
     pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> {
         self.diagnostic().is_compilation_going_to_fail()
@@ -580,7 +578,7 @@ impl Session {
         if self.err_count() == old_count {
             Ok(result)
         } else {
-            Err(self.delay_span_bug(
+            Err(self.span_delayed_bug(
                 rustc_span::DUMMY_SP,
                 "`self.err_count()` changed but an error was not emitted",
             ))
@@ -621,24 +619,28 @@ impl Session {
     ///
     /// This can be used in code paths that should never run on successful compilations.
     /// For example, it can be used to create an [`ErrorGuaranteed`]
-    /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission directly).
+    /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission
+    /// directly).
     ///
     /// If no span is available, use [`DUMMY_SP`].
     ///
     /// [`DUMMY_SP`]: rustc_span::DUMMY_SP
+    ///
+    /// Note: this function used to be called `delay_span_bug`. It was renamed
+    /// to match similar functions like `span_err`, `span_warn`, etc.
     #[track_caller]
-    pub fn delay_span_bug<S: Into<MultiSpan>>(
+    pub fn span_delayed_bug<S: Into<MultiSpan>>(
         &self,
         sp: S,
         msg: impl Into<String>,
     ) -> ErrorGuaranteed {
-        self.diagnostic().delay_span_bug(sp, msg)
+        self.diagnostic().span_delayed_bug(sp, msg)
     }
 
     /// Used for code paths of expensive computations that should only take place when
     /// warnings or errors are emitted. If no messages are emitted ("good path"), then
     /// it's likely a bug.
-    pub fn delay_good_path_bug(&self, msg: impl Into<DiagnosticMessage>) {
+    pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
         if self.opts.unstable_opts.print_type_sizes
             || self.opts.unstable_opts.query_dep_graph
             || self.opts.unstable_opts.dump_mir.is_some()
@@ -649,40 +651,33 @@ impl Session {
             return;
         }
 
-        self.diagnostic().delay_good_path_bug(msg)
+        self.diagnostic().good_path_delayed_bug(msg)
     }
 
     #[rustc_lint_diagnostics]
     #[allow(rustc::untranslatable_diagnostic)]
     #[allow(rustc::diagnostic_outside_of_impl)]
-    pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) {
-        self.diagnostic().note_without_error(msg)
+    pub fn note(&self, msg: impl Into<DiagnosticMessage>) {
+        self.diagnostic().note(msg)
     }
 
     #[track_caller]
     #[rustc_lint_diagnostics]
     #[allow(rustc::untranslatable_diagnostic)]
     #[allow(rustc::diagnostic_outside_of_impl)]
-    pub fn span_note_without_error<S: Into<MultiSpan>>(
-        &self,
-        sp: S,
-        msg: impl Into<DiagnosticMessage>,
-    ) {
-        self.diagnostic().span_note_without_error(sp, msg)
+    pub fn span_note<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
+        self.diagnostic().span_note(sp, msg)
     }
 
     #[rustc_lint_diagnostics]
     #[allow(rustc::untranslatable_diagnostic)]
     #[allow(rustc::diagnostic_outside_of_impl)]
-    pub fn struct_note_without_error(
-        &self,
-        msg: impl Into<DiagnosticMessage>,
-    ) -> DiagnosticBuilder<'_, ()> {
-        self.diagnostic().struct_note_without_error(msg)
+    pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
+        self.diagnostic().struct_note(msg)
     }
 
     #[inline]
-    pub fn diagnostic(&self) -> &rustc_errors::Handler {
+    pub fn diagnostic(&self) -> &Handler {
         &self.parse_sess.span_diagnostic
     }
 
@@ -816,12 +811,7 @@ impl Session {
         if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
     }
 
-    pub fn init_incr_comp_session(
-        &self,
-        session_dir: PathBuf,
-        lock_file: flock::Lock,
-        load_dep_graph: bool,
-    ) {
+    pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) {
         let mut incr_comp_session = self.incr_comp_session.borrow_mut();
 
         if let IncrCompSession::NotInitialized = *incr_comp_session {
@@ -830,7 +820,7 @@ impl Session {
         }
 
         *incr_comp_session =
-            IncrCompSession::Active { session_directory: session_dir, lock_file, load_dep_graph };
+            IncrCompSession::Active { session_directory: session_dir, _lock_file: lock_file };
     }
 
     pub fn finalize_incr_comp_session(&self, new_directory_path: PathBuf) {
@@ -893,7 +883,7 @@ impl Session {
                 if fuel.remaining == 0 && !fuel.out_of_fuel {
                     if self.diagnostic().can_emit_warnings() {
                         // We only call `msg` in case we can actually emit warnings.
-                        // Otherwise, this could cause a `delay_good_path_bug` to
+                        // Otherwise, this could cause a `good_path_delayed_bug` to
                         // trigger (issue #79546).
                         self.emit_warning(errors::OptimisationFuelExhausted { msg: msg() });
                     }
@@ -1417,7 +1407,7 @@ pub fn build_session(
     );
     let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
 
-    let mut span_diagnostic = rustc_errors::Handler::with_emitter(emitter)
+    let mut span_diagnostic = Handler::with_emitter(emitter)
         .with_flags(sopts.unstable_opts.diagnostic_handler_flags(can_emit_warnings));
     if let Some(ice_file) = ice_file {
         span_diagnostic = span_diagnostic.with_ice_file(ice_file);
@@ -1704,13 +1694,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
 
 /// Holds data on the current incremental compilation session, if there is one.
 #[derive(Debug)]
-pub enum IncrCompSession {
+enum IncrCompSession {
     /// This is the state the session will be in until the incr. comp. dir is
     /// needed.
     NotInitialized,
     /// This is the state during which the session directory is private and can
-    /// be modified.
-    Active { session_directory: PathBuf, lock_file: flock::Lock, load_dep_graph: bool },
+    /// be modified. `_lock_file` is never directly used, but its presence
+    /// alone has an effect, because the file will unlock when the session is
+    /// dropped.
+    Active { session_directory: PathBuf, _lock_file: flock::Lock },
     /// This is the state after the session directory has been finalized. In this
     /// state, the contents of the directory must not be modified any more.
     Finalized { session_directory: PathBuf },
@@ -1728,7 +1720,7 @@ pub struct EarlyErrorHandler {
 impl EarlyErrorHandler {
     pub fn new(output: ErrorOutputType) -> Self {
         let emitter = mk_emitter(output);
-        Self { handler: rustc_errors::Handler::with_emitter(emitter) }
+        Self { handler: Handler::with_emitter(emitter) }
     }
 
     pub fn abort_if_errors(&self) {
@@ -1748,7 +1740,7 @@ impl EarlyErrorHandler {
     #[allow(rustc::untranslatable_diagnostic)]
     #[allow(rustc::diagnostic_outside_of_impl)]
     pub fn early_note(&self, msg: impl Into<DiagnosticMessage>) {
-        self.handler.struct_note_without_error(msg).emit()
+        self.handler.struct_note(msg).emit()
     }
 
     #[allow(rustc::untranslatable_diagnostic)]
@@ -1772,7 +1764,7 @@ impl EarlyErrorHandler {
 
     #[allow(rustc::untranslatable_diagnostic)]
     #[allow(rustc::diagnostic_outside_of_impl)]
-    pub(crate) fn early_struct_error(
+    pub fn early_struct_error(
         &self,
         msg: impl Into<DiagnosticMessage>,
     ) -> DiagnosticBuilder<'_, !> {
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 3ed044ad769..f76c69af526 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -158,14 +158,3 @@ pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
 
     if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None }
 }
-
-pub(crate) fn is_ascii_ident(string: &str) -> bool {
-    let mut chars = string.chars();
-    if let Some(start) = chars.next()
-        && (start.is_ascii_alphabetic() || start == '_')
-    {
-        chars.all(|char| char.is_ascii_alphanumeric() || char == '_')
-    } else {
-        false
-    }
-}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index e9b835f90db..165b8c50e70 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -579,13 +579,12 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
             mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt {
                 discr: discr.stable(tables),
                 targets: {
-                    let (value_vec, mut target_vec): (Vec<_>, Vec<_>) =
-                        targets.iter().map(|(value, target)| (value, target.as_usize())).unzip();
-                    // We need to push otherwise as last element to ensure it's same as in MIR.
-                    target_vec.push(targets.otherwise().as_usize());
-                    stable_mir::mir::SwitchTargets { value: value_vec, targets: target_vec }
+                    let branches = targets.iter().map(|(val, target)| (val, target.as_usize()));
+                    stable_mir::mir::SwitchTargets::new(
+                        branches.collect(),
+                        targets.otherwise().as_usize(),
+                    )
                 },
-                otherwise: targets.otherwise().as_usize(),
             },
             mir::TerminatorKind::UnwindResume => TerminatorKind::Resume,
             mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort,
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 76be546e945..cc3f0962d6c 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -2247,7 +2247,7 @@ pub struct ErrorGuaranteed(());
 impl ErrorGuaranteed {
     /// To be used only if you really know what you are doing... ideally, we would find a way to
     /// eliminate all calls to this method.
-    #[deprecated = "`Session::delay_span_bug` should be preferred over this function"]
+    #[deprecated = "`Session::span_delayed_bug` should be preferred over this function"]
     pub fn unchecked_claim_error_was_emitted() -> Self {
         ErrorGuaranteed(())
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9a2fe01229d..d7e822382ef 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -128,13 +128,11 @@ symbols! {
         AcqRel,
         Acquire,
         AddToDiagnostic,
-        Alignment,
         Any,
         Arc,
         ArcWeak,
         Argument,
         ArgumentMethods,
-        Arguments,
         ArrayIntoIter,
         AsMut,
         AsRef,
@@ -164,7 +162,6 @@ symbols! {
         Break,
         C,
         CStr,
-        CString,
         Capture,
         Center,
         Cleanup,
@@ -174,7 +171,6 @@ symbols! {
         Context,
         Continue,
         Copy,
-        Count,
         Cow,
         Debug,
         DebugStruct,
@@ -199,7 +195,6 @@ symbols! {
         Fn,
         FnMut,
         FnOnce,
-        FormatSpec,
         Formatter,
         From,
         FromIterator,
@@ -208,8 +203,6 @@ symbols! {
         FsPermissions,
         Future,
         FutureOutput,
-        FxHashMap,
-        FxHashSet,
         GlobalAlloc,
         Hash,
         HashMap,
@@ -253,7 +246,6 @@ symbols! {
         NonZeroI32,
         NonZeroI64,
         NonZeroI8,
-        NonZeroIsize,
         NonZeroU128,
         NonZeroU16,
         NonZeroU32,
@@ -275,7 +267,6 @@ symbols! {
         Path,
         PathBuf,
         Pending,
-        Pin,
         Pointer,
         Poll,
         ProcMacro,
@@ -333,7 +324,6 @@ symbols! {
         TyCtxt,
         TyKind,
         Unknown,
-        UnsafeArg,
         Vec,
         VecDeque,
         Wrapper,
@@ -389,7 +379,6 @@ symbols! {
         allow_fail,
         allow_internal_unsafe,
         allow_internal_unstable,
-        allowed,
         alu32,
         always,
         and,
@@ -405,8 +394,6 @@ symbols! {
         arm,
         arm_target_feature,
         array,
-        arrays,
-        as_mut_ptr,
         as_ptr,
         as_ref,
         as_str,
@@ -589,7 +576,6 @@ symbols! {
         const_try,
         constant,
         constructor,
-        context,
         convert_identity,
         copy,
         copy_closures,
@@ -655,7 +641,6 @@ symbols! {
         default_method_body_is_const,
         default_type_parameter_fallback,
         default_type_params,
-        delay_span_bug_from_inside_query,
         deny,
         deprecated,
         deprecated_safe,
@@ -776,8 +761,6 @@ symbols! {
         field,
         field_init_shorthand,
         file,
-        fill,
-        flags,
         float,
         float_to_int_unchecked,
         floorf32,
@@ -950,6 +933,7 @@ symbols! {
         likely,
         line,
         link,
+        link_arg_attribute,
         link_args,
         link_cfg,
         link_llvm_intrinsics,
@@ -1059,7 +1043,6 @@ symbols! {
         mir_unwind_unreachable,
         mir_variant,
         miri,
-        misc,
         mmx_reg,
         modifiers,
         module,
@@ -1157,9 +1140,7 @@ symbols! {
         omit_gdb_pretty_printer_section,
         on,
         on_unimplemented,
-        oom,
         opaque,
-        ops,
         opt_out_copy,
         optimize,
         optimize_attribute,
@@ -1217,7 +1198,6 @@ symbols! {
         pointer,
         pointer_like,
         poll,
-        position,
         post_dash_lto: "post-lto",
         powerpc_target_feature,
         powf32,
@@ -1226,7 +1206,6 @@ symbols! {
         powif64,
         pre_dash_lto: "pre-lto",
         precise_pointer_size_matching,
-        precision,
         pref_align_of,
         prefetch_read_data,
         prefetch_read_instruction,
@@ -1236,7 +1215,6 @@ symbols! {
         prelude,
         prelude_import,
         preserves_flags,
-        primitive,
         print_macro,
         println_macro,
         proc_dash_macro: "proc-macro",
@@ -1260,7 +1238,6 @@ symbols! {
         ptr_const_is_null,
         ptr_copy,
         ptr_copy_nonoverlapping,
-        ptr_drop_in_place,
         ptr_eq,
         ptr_from_ref,
         ptr_guaranteed_cmp,
@@ -1579,6 +1556,7 @@ symbols! {
         slice_patterns,
         slicing_syntax,
         soft,
+        span_delayed_bug_from_inside_query,
         specialization,
         speed,
         spotlight,
@@ -1622,7 +1600,6 @@ symbols! {
         structural_match,
         structural_peq,
         structural_teq,
-        sty,
         sub,
         sub_assign,
         sub_with_overflow,
@@ -1744,7 +1721,6 @@ symbols! {
         unrestricted_attribute_tokens,
         unsafe_block_in_unsafe_fn,
         unsafe_cell,
-        unsafe_cell_from_mut,
         unsafe_cell_raw_get,
         unsafe_no_drop_flag,
         unsafe_pin_internals,
@@ -1769,7 +1745,6 @@ symbols! {
         used_with_arg,
         using,
         usize,
-        v1,
         va_arg,
         va_copy,
         va_end,
@@ -1801,7 +1776,6 @@ symbols! {
         wasm_import_module,
         wasm_target_feature,
         while_let,
-        width,
         windows,
         windows_subsystem,
         with_negative_coherence,
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs b/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs
index 37bbf32c768..03823569669 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals/mod.rs
@@ -196,7 +196,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
             };
 
             let error_response = |ecx: &mut EvalCtxt<'_, 'tcx>, reason| {
-                let guar = tcx.sess.delay_span_bug(tcx.def_span(assoc_def.item.def_id), reason);
+                let guar = tcx.sess.span_delayed_bug(tcx.def_span(assoc_def.item.def_id), reason);
                 let error_term = match assoc_def.item.kind {
                     ty::AssocKind::Const => ty::Const::new_error(
                         tcx,
@@ -286,7 +286,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx> {
-        ecx.tcx().sess.delay_span_bug(
+        ecx.tcx().sess.span_delayed_bug(
             ecx.tcx().def_span(goal.predicate.def_id()),
             "associated types not allowed on auto traits",
         );
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 62ab1e1049b..aee51320792 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -65,7 +65,7 @@ pub fn is_const_evaluatable<'tcx>(
                 // FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but
                 // currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it
                 // is evaluatable or not. For now we just ICE until this is implemented.
-                Err(NotConstEvaluatable::Error(tcx.sess.delay_span_bug(
+                Err(NotConstEvaluatable::Error(tcx.sess.span_delayed_bug(
                     span,
                     "evaluating `ConstKind::Expr` is not currently supported",
                 )))
@@ -74,7 +74,7 @@ pub fn is_const_evaluatable<'tcx>(
                 let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
                 match concrete {
                     Err(ErrorHandled::TooGeneric(_)) => {
-                        Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
+                        Err(NotConstEvaluatable::Error(infcx.tcx.sess.span_delayed_bug(
                             span,
                             "Missing value for constant, but no error reported?",
                         )))
@@ -138,10 +138,10 @@ pub fn is_const_evaluatable<'tcx>(
                 } else if uv.has_non_region_param() {
                     NotConstEvaluatable::MentionsParam
                 } else {
-                    let guar = infcx
-                        .tcx
-                        .sess
-                        .delay_span_bug(span, "Missing value for constant, but no error reported?");
+                    let guar = infcx.tcx.sess.span_delayed_bug(
+                        span,
+                        "Missing value for constant, but no error reported?",
+                    );
                     NotConstEvaluatable::Error(guar)
                 };
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index feeeaa51f81..ba019c4ff6f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -677,8 +677,9 @@ impl<'tcx> OnUnimplementedDirective {
 
             Ok(None)
         } else {
-            let reported =
-                tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str");
+            let reported = tcx
+                .sess
+                .span_delayed_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str");
             return Err(reported);
         };
         debug!("of_item({:?}) = {:?}", item_def_id, result);
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index e4cb99727fc..d5e1efb9663 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -17,7 +17,7 @@ use rustc_errors::{
     ErrorGuaranteed, MultiSpan, Style, SuggestionStyle,
 };
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::is_range_literal;
@@ -36,7 +36,7 @@ use rustc_middle::ty::{
     TypeSuperFoldable, TypeVisitableExt, TypeckResults,
 };
 use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::{sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use std::borrow::Cow;
@@ -222,6 +222,15 @@ pub trait TypeErrCtxtExt<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
 
+    fn note_conflicting_fn_args(
+        &self,
+        err: &mut Diagnostic,
+        cause: &ObligationCauseCode<'tcx>,
+        expected: Ty<'tcx>,
+        found: Ty<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    );
+
     fn note_conflicting_closure_bounds(
         &self,
         cause: &ObligationCauseCode<'tcx>,
@@ -1034,7 +1043,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind else {
             return;
         };
-        let hir::def::Res::Local(hir_id) = path.res else {
+        let Res::Local(hir_id) = path.res else {
             return;
         };
         let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else {
@@ -1618,7 +1627,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
-                && let hir::def::Res::Local(hir_id) = path.res
+                && let Res::Local(hir_id) = path.res
                 && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id)
                 && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
                 && let None = local.ty
@@ -2005,6 +2014,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let signature_kind = format!("{argument_kind} signature");
         err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
 
+        self.note_conflicting_fn_args(&mut err, cause, expected, found, param_env);
         self.note_conflicting_closure_bounds(cause, &mut err);
 
         if let Some(found_node) = found_node {
@@ -2014,6 +2024,151 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         err
     }
 
+    fn note_conflicting_fn_args(
+        &self,
+        err: &mut Diagnostic,
+        cause: &ObligationCauseCode<'tcx>,
+        expected: Ty<'tcx>,
+        found: Ty<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) {
+        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = cause else {
+            return;
+        };
+        let ty::FnPtr(expected) = expected.kind() else {
+            return;
+        };
+        let ty::FnPtr(found) = found.kind() else {
+            return;
+        };
+        let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id) else {
+            return;
+        };
+        let hir::ExprKind::Path(path) = arg.kind else {
+            return;
+        };
+        let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(*expected).inputs();
+        let found_inputs = self.tcx.instantiate_bound_regions_with_erased(*found).inputs();
+        let both_tys = expected_inputs.iter().copied().zip(found_inputs.iter().copied());
+
+        let arg_expr = |infcx: &InferCtxt<'tcx>, name, expected: Ty<'tcx>, found: Ty<'tcx>| {
+            let (expected_ty, expected_refs) = get_deref_type_and_refs(expected);
+            let (found_ty, found_refs) = get_deref_type_and_refs(found);
+
+            if infcx.can_eq(param_env, found_ty, expected_ty) {
+                if found_refs.len() == expected_refs.len()
+                    && found_refs.iter().eq(expected_refs.iter())
+                {
+                    name
+                } else if found_refs.len() > expected_refs.len() {
+                    let refs = &found_refs[..found_refs.len() - expected_refs.len()];
+                    if found_refs[..expected_refs.len()].iter().eq(expected_refs.iter()) {
+                        format!(
+                            "{}{name}",
+                            refs.iter()
+                                .map(|mutbl| format!("&{}", mutbl.prefix_str()))
+                                .collect::<Vec<_>>()
+                                .join(""),
+                        )
+                    } else {
+                        // The refs have different mutability.
+                        format!(
+                            "{}*{name}",
+                            refs.iter()
+                                .map(|mutbl| format!("&{}", mutbl.prefix_str()))
+                                .collect::<Vec<_>>()
+                                .join(""),
+                        )
+                    }
+                } else if expected_refs.len() > found_refs.len() {
+                    format!(
+                        "{}{name}",
+                        (0..(expected_refs.len() - found_refs.len()))
+                            .map(|_| "*")
+                            .collect::<Vec<_>>()
+                            .join(""),
+                    )
+                } else {
+                    format!(
+                        "{}{name}",
+                        found_refs
+                            .iter()
+                            .map(|mutbl| format!("&{}", mutbl.prefix_str()))
+                            .chain(found_refs.iter().map(|_| "*".to_string()))
+                            .collect::<Vec<_>>()
+                            .join(""),
+                    )
+                }
+            } else {
+                format!("/* {found} */")
+            }
+        };
+        let args_have_same_underlying_type = both_tys.clone().all(|(expected, found)| {
+            let (expected_ty, _) = get_deref_type_and_refs(expected);
+            let (found_ty, _) = get_deref_type_and_refs(found);
+            self.can_eq(param_env, found_ty, expected_ty)
+        });
+        let (closure_names, call_names): (Vec<_>, Vec<_>) = if args_have_same_underlying_type
+            && !expected_inputs.is_empty()
+            && expected_inputs.len() == found_inputs.len()
+            && let Some(typeck) = &self.typeck_results
+            && let Res::Def(_, fn_def_id) = typeck.qpath_res(&path, *arg_hir_id)
+        {
+            let closure: Vec<_> = self
+                .tcx
+                .fn_arg_names(fn_def_id)
+                .iter()
+                .enumerate()
+                .map(|(i, ident)| {
+                    if ident.name.is_empty() || ident.name == kw::SelfLower {
+                        format!("arg{i}")
+                    } else {
+                        format!("{ident}")
+                    }
+                })
+                .collect();
+            let args = closure
+                .iter()
+                .zip(both_tys)
+                .map(|(name, (expected, found))| {
+                    arg_expr(self.infcx, name.to_owned(), expected, found)
+                })
+                .collect();
+            (closure, args)
+        } else {
+            let closure_args = expected_inputs
+                .iter()
+                .enumerate()
+                .map(|(i, _)| format!("arg{i}"))
+                .collect::<Vec<_>>();
+            let call_args = both_tys
+                .enumerate()
+                .map(|(i, (expected, found))| {
+                    arg_expr(self.infcx, format!("arg{i}"), expected, found)
+                })
+                .collect::<Vec<_>>();
+            (closure_args, call_args)
+        };
+        let closure_names: Vec<_> = closure_names
+            .into_iter()
+            .zip(expected_inputs.iter())
+            .map(|(name, ty)| {
+                format!(
+                    "{name}{}",
+                    if ty.has_infer_types() { String::new() } else { format!(": {ty}") }
+                )
+            })
+            .collect();
+        err.multipart_suggestion(
+            format!("consider wrapping the function in a closure"),
+            vec![
+                (arg.span.shrink_to_lo(), format!("|{}| ", closure_names.join(", "))),
+                (arg.span.shrink_to_hi(), format!("({})", call_names.join(", "))),
+            ],
+            Applicability::MaybeIncorrect,
+        );
+    }
+
     // Add a note if there are two `Fn`-family bounds that have conflicting argument
     // requirements, which will always cause a closure to have a type error.
     fn note_conflicting_closure_bounds(
@@ -3634,7 +3789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
-                && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
+                && let hir::Path { res: Res::Local(hir_id), .. } = path
                 && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
                 && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
                 && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
@@ -3894,7 +4049,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             );
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
-                && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
+                && let hir::Path { res: Res::Local(hir_id), .. } = path
                 && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
                 && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
@@ -4349,17 +4504,6 @@ fn hint_missing_borrow<'tcx>(
 
     let args = fn_decl.inputs.iter();
 
-    fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) {
-        let mut refs = vec![];
-
-        while let ty::Ref(_, new_ty, mutbl) = ty.kind() {
-            ty = *new_ty;
-            refs.push(*mutbl);
-        }
-
-        (ty, refs)
-    }
-
     let mut to_borrow = Vec::new();
     let mut remove_borrow = Vec::new();
 
@@ -4519,7 +4663,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
     fn visit_ty(&mut self, t: &'hir hir::Ty<'hir>) {
         if let hir::TyKind::Path(hir::QPath::Resolved(
             None,
-            hir::Path { res: hir::def::Res::Def(_, segment_did), .. },
+            hir::Path { res: Res::Def(_, segment_did), .. },
         )) = t.kind
         {
             if self.param_did == *segment_did {
@@ -4652,3 +4796,14 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
 
     Some(sugg)
 }
+
+fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) {
+    let mut refs = vec![];
+
+    while let ty::Ref(_, new_ty, mutbl) = ty.kind() {
+        ty = *new_ty;
+        refs.push(*mutbl);
+    }
+
+    (ty, refs)
+}
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 b28bff1ca2a..b3910a2770b 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
@@ -218,7 +218,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
 
-        self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fulfillment errors")
+        self.tcx.sess.span_delayed_bug(DUMMY_SP, "expected fulfillment errors")
     }
 
     /// Reports that an overflow has occurred and halts compilation. We
@@ -369,7 +369,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let mut span = obligation.cause.span;
         // FIXME: statically guarantee this by tainting after the diagnostic is emitted
         self.set_tainted_by_errors(
-            tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"),
+            tcx.sess.span_delayed_bug(span, "`report_selection_error` did not emit an error"),
         );
 
         let mut err = match *error {
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 08544b4a93a..fd39fce9dd1 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -1,4 +1,5 @@
 use crate::infer::{InferCtxt, TyOrConstInferVar};
+use crate::traits::error_reporting::TypeErrCtxtExt;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::obligation_forest::ProcessResult;
 use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
@@ -410,6 +411,29 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     }
                 }
 
+                ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
+                ty::PredicateKind::AliasRelate(..) => {
+                    bug!("AliasRelate is only used for new solver")
+                }
+
+                // General case overflow check. Allow `process_trait_obligation`
+                // and `process_projection_obligation` to handle checking for
+                // the recursion limit themselves. Also don't check some
+                // predicate kinds that don't give further obligations.
+                _ if !self
+                    .selcx
+                    .tcx()
+                    .recursion_limit()
+                    .value_within_limit(obligation.recursion_depth) =>
+                {
+                    self.selcx.infcx.err_ctxt().report_overflow_error(
+                        &obligation.predicate,
+                        obligation.cause.span,
+                        false,
+                        |_| {},
+                    );
+                }
+
                 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
                     match wf::obligations(
                         self.selcx.infcx,
@@ -440,7 +464,12 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
                             ProcessResult::Unchanged
                         }
-                        Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
+                        Ok(Ok(mut ok)) => {
+                            for subobligation in &mut ok.obligations {
+                                subobligation.set_depth_from_parent(obligation.recursion_depth);
+                            }
+                            ProcessResult::Changed(mk_pending(ok.obligations))
+                        }
                         Ok(Err(err)) => {
                             let expected_found =
                                 ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b);
@@ -611,10 +640,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         }
                     }
                 }
-                ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
-                ty::PredicateKind::AliasRelate(..) => {
-                    bug!("AliasRelate is only used for new solver")
-                }
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
                     match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
                         DefineOpaqueTypes::No,
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index ab07b10c65f..2f2411310a9 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -173,7 +173,7 @@ pub fn all_fields_implement_trait<'tcx>(
             // between expected and found const-generic types. Don't report an
             // additional copy error here, since it's not typically useful.
             if !normalization_errors.is_empty() || ty.references_error() {
-                tcx.sess.delay_span_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking {tr} implementation", tr = tcx.def_path_str(trait_def_id)));
+                tcx.sess.span_delayed_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking {tr} implementation", tr = tcx.def_path_str(trait_def_id)));
                 continue;
             }
 
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 2c004c65929..64d2b5fc159 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -215,7 +215,7 @@ fn do_normalize_predicates<'tcx>(
     // the normalized predicates.
     let errors = infcx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
-        tcx.sess.delay_span_bug(
+        tcx.sess.span_delayed_bug(
             span,
             format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"),
         );
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 8268273884d..fbde7455145 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -509,7 +509,7 @@ fn virtual_call_violations_for_method<'tcx>(
                     Ok(layout) => Some(layout.abi),
                     Err(err) => {
                         // #78372
-                        tcx.sess.delay_span_bug(
+                        tcx.sess.span_delayed_bug(
                             tcx.def_span(method.def_id),
                             format!("error: {err}\n while computing layout for type {ty:?}"),
                         );
@@ -525,7 +525,7 @@ fn virtual_call_violations_for_method<'tcx>(
             match abi_of_ty(unit_receiver_ty) {
                 Some(Abi::Scalar(..)) => (),
                 abi => {
-                    tcx.sess.delay_span_bug(
+                    tcx.sess.span_delayed_bug(
                         tcx.def_span(method.def_id),
                         format!(
                             "receiver when `Self = ()` should have a Scalar ABI; found {abi:?}"
@@ -543,7 +543,7 @@ fn virtual_call_violations_for_method<'tcx>(
             match abi_of_ty(trait_object_receiver) {
                 Some(Abi::ScalarPair(..)) => (),
                 abi => {
-                    tcx.sess.delay_span_bug(
+                    tcx.sess.span_delayed_bug(
                         tcx.def_span(method.def_id),
                         format!(
                             "receiver when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}"
@@ -597,7 +597,7 @@ fn virtual_call_violations_for_method<'tcx>(
             if pred_trait_ref.args.len() != 1 {
                 tcx.sess
                     .diagnostic()
-                    .delay_span_bug(span, "auto traits cannot have generic parameters");
+                    .span_delayed_bug(span, "auto traits cannot have generic parameters");
             }
             return false;
         }
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 1c2966bb3e5..7513f88cfc3 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -111,7 +111,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
 
             let errors = ocx.select_all_or_error();
             if !errors.is_empty() {
-                self.tcx.sess.delay_span_bug(
+                self.tcx.sess.span_delayed_bug(
                     span,
                     "implied_outlives_bounds failed to solve obligations from instantiation",
                 );
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 3be14951703..45bdff09dee 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1469,7 +1469,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
     match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) {
         Ok(mut ok) => obligations.append(&mut ok.obligations),
         Err(_) => {
-            tcx.sess.delay_span_bug(
+            tcx.sess.span_delayed_bug(
                 cause.span,
                 format!(
                     "{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not"
@@ -1974,7 +1974,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
             ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _)
             | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
                 // These traits have no associated types.
-                selcx.tcx().sess.delay_span_bug(
+                selcx.tcx().sess.span_delayed_bug(
                     obligation.cause.span,
                     format!("Cannot project an associated type from `{impl_source:?}`"),
                 );
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 06d41243e75..ec80df1d658 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -237,7 +237,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
                 // By the time this code runs, all type variables ought to
                 // be fully resolved.
 
-                tcx.sess.delay_span_bug(
+                tcx.sess.span_delayed_bug(
                     span,
                     format!("upvar_tys for closure not found. Expected capture information for closure {ty}",),
                 );
@@ -286,7 +286,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             if !args.is_valid() {
                 // By the time this code runs, all type variables ought to
                 // be fully resolved.
-                tcx.sess.delay_span_bug(
+                tcx.sess.span_delayed_bug(
                     span,
                     format!("upvar_tys for coroutine not found. Expected capture information for coroutine {ty}",),
                 );
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 8faaa6be9f5..4728fcf3301 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -292,7 +292,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
                     // Rustdoc normalizes possibly not well-formed types, so only
                     // treat this as a bug if we're not in rustdoc.
                     if !tcx.sess.opts.actually_rustdoc {
-                        tcx.sess.delay_span_bug(
+                        tcx.sess.span_delayed_bug(
                             DUMMY_SP,
                             format!("unexpected ambiguity: {c_data:?} {result:?}"),
                         );
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
index c81bc579003..18bb56ba4eb 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
@@ -82,13 +82,13 @@ where
     let value = infcx.commit_if_ok(|_| {
         let ocx = ObligationCtxt::new(infcx);
         let value = op(&ocx).map_err(|_| {
-            infcx.tcx.sess.delay_span_bug(span, format!("error performing operation: {name}"))
+            infcx.tcx.sess.span_delayed_bug(span, format!("error performing operation: {name}"))
         })?;
         let errors = ocx.select_all_or_error();
         if errors.is_empty() {
             Ok(value)
         } else {
-            Err(infcx.tcx.sess.delay_span_bug(
+            Err(infcx.tcx.sess.span_delayed_bug(
                 DUMMY_SP,
                 format!("errors selecting obligation during MIR typeck: {errors:?}"),
             ))
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
index a5ccf62608e..e87e585ef0b 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs
@@ -160,14 +160,14 @@ where
         let (output, error_info, mut obligations) =
             Q::fully_perform_into(self, infcx, &mut region_constraints)
                 .map_err(|_| {
-                    infcx.tcx.sess.delay_span_bug(span, format!("error performing {self:?}"))
+                    infcx.tcx.sess.span_delayed_bug(span, format!("error performing {self:?}"))
                 })
                 .and_then(|(output, error_info, obligations, certainty)| match certainty {
                     Certainty::Proven => Ok((output, error_info, obligations)),
                     Certainty::Ambiguous => Err(infcx
                         .tcx
                         .sess
-                        .delay_span_bug(span, format!("ambiguity performing {self:?}"))),
+                        .span_delayed_bug(span, format!("ambiguity performing {self:?}"))),
                 })?;
 
         // Typically, instantiating NLL query results does not
@@ -196,7 +196,7 @@ where
                 }
             }
             if !progress {
-                return Err(infcx.tcx.sess.delay_span_bug(
+                return Err(infcx.tcx.sess.span_delayed_bug(
                     span,
                     format!("ambiguity processing {obligations:?} from {self:?}"),
                 ));
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 4763a906172..a33160b7c43 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -553,7 +553,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             let defs: &ty::Generics = tcx.generics_of(assoc_type);
 
             if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended {
-                tcx.sess.delay_span_bug(
+                tcx.sess.span_delayed_bug(
                     obligation.cause.span,
                     "GATs in trait object shouldn't have been considered",
                 );
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 0c884b7c16a..b26c781100a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2419,7 +2419,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 // the placeholder trait ref may fail due the Generalizer relation
                 // raising a CyclicalTy error due to a sub_root_var relation
                 // for a variable being generalized...
-                let guar = self.infcx.tcx.sess.delay_span_bug(
+                let guar = self.infcx.tcx.sess.span_delayed_bug(
                     obligation.cause.span,
                     format!(
                         "Impl {impl_def_id:?} was matchable against {obligation:?} but now is not"
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 73ba03a3610..56f5057608f 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -202,7 +202,7 @@ fn fulfill_implication<'tcx>(
         {
             Ok(source_trait_ref) => source_trait_ref,
             Err(_errors) => {
-                infcx.tcx.sess.delay_span_bug(
+                infcx.tcx.sess.span_delayed_bug(
                     infcx.tcx.def_span(source_impl),
                     format!("failed to fully normalize {source_trait_ref}"),
                 );
@@ -431,7 +431,10 @@ fn report_conflicting_impls<'tcx>(
                 decorate(tcx, &overlap, impl_span, &mut err);
                 Some(err.emit())
             } else {
-                Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
+                Some(
+                    tcx.sess
+                        .span_delayed_bug(impl_span, "impl should have failed the orphan check"),
+                )
             };
             sg.has_errored = reported;
         }
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 5960415a88d..f8e47caccb7 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -135,7 +135,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
                 bug!("unexpected type during structural-match checking: {:?}", ty);
             }
             ty::Error(_) => {
-                self.tcx.sess.delay_span_bug(self.span, "ty::Error in structural-match check");
+                self.tcx.sess.span_delayed_bug(self.span, "ty::Error in structural-match check");
                 // We still want to check other types after encountering an error,
                 // as this may still emit relevant errors.
                 return ControlFlow::Continue(());
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 31f6a56eaeb..a0f01d9eca9 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -79,7 +79,7 @@ fn resolve_associated_item<'tcx>(
     let vtbl = match tcx.codegen_select_candidate((param_env, trait_ref)) {
         Ok(vtbl) => vtbl,
         Err(CodegenObligationError::Ambiguity) => {
-            let reported = tcx.sess.delay_span_bug(
+            let reported = tcx.sess.span_delayed_bug(
                 tcx.def_span(trait_item_id),
                 format!(
                     "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \
@@ -171,7 +171,7 @@ fn resolve_associated_item<'tcx>(
 
             // Any final impl is required to define all associated items.
             if !leaf_def.item.defaultness(tcx).has_value() {
-                let guard = tcx.sess.delay_span_bug(
+                let guard = tcx.sess.span_delayed_bug(
                     tcx.def_span(leaf_def.item.def_id),
                     "missing value for assoc item in impl",
                 );
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 826c69ee716..7599aa9fa41 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -93,7 +93,7 @@ fn univariant_uninterned<'tcx>(
     let dl = cx.data_layout();
     let pack = repr.pack;
     if pack.is_some() && repr.align.is_some() {
-        cx.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned");
+        cx.tcx.sess.span_delayed_bug(DUMMY_SP, "struct cannot be packed and aligned");
         return Err(cx.tcx.arena.alloc(LayoutError::Unknown(ty)));
     }
 
@@ -346,7 +346,7 @@ fn layout_of_uncached<'tcx>(
         ty::Adt(def, args) if def.repr().simd() => {
             if !def.is_struct() {
                 // Should have yielded E0517 by now.
-                tcx.sess.delay_span_bug(
+                tcx.sess.span_delayed_bug(
                     DUMMY_SP,
                     "#[repr(simd)] was applied to an ADT that is not a struct",
                 );
@@ -376,7 +376,7 @@ fn layout_of_uncached<'tcx>(
             // (should be caught by typeck)
             for fi in fields {
                 if fi.ty(tcx, args) != f0_ty {
-                    tcx.sess.delay_span_bug(
+                    tcx.sess.span_delayed_bug(
                         DUMMY_SP,
                         "#[repr(simd)] was applied to an ADT with heterogeneous field type",
                     );
@@ -473,7 +473,7 @@ fn layout_of_uncached<'tcx>(
 
             if def.is_union() {
                 if def.repr().pack.is_some() && def.repr().align.is_some() {
-                    cx.tcx.sess.delay_span_bug(
+                    cx.tcx.sess.span_delayed_bug(
                         tcx.def_span(def.did()),
                         "union cannot be packed and aligned",
                     );
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 16f5ed09d00..db43c31ccab 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -238,7 +238,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                                     .instantiate(self.tcx, impl_args)
                                     .visit_with(self);
                             } else {
-                                self.tcx.sess.delay_span_bug(
+                                self.tcx.sess.span_delayed_bug(
                                     self.tcx.def_span(assoc.def_id),
                                     "item had incorrect args",
                                 );
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 02a28687676..3a4f4283562 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -3,7 +3,7 @@ use crate::ty::{
     AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
 };
 use crate::{Error, Opaque, Span, Symbol};
-use std::{io, slice};
+use std::io;
 /// The SMIR representation of a single function.
 #[derive(Clone, Debug)]
 pub struct Body {
@@ -23,6 +23,8 @@ pub struct Body {
     pub(super) var_debug_info: Vec<VarDebugInfo>,
 }
 
+pub type BasicBlockIdx = usize;
+
 impl Body {
     /// Constructs a `Body`.
     ///
@@ -114,22 +116,21 @@ pub struct Terminator {
 }
 
 impl Terminator {
-    pub fn successors(&self) -> Successors<'_> {
+    pub fn successors(&self) -> Successors {
         self.kind.successors()
     }
 }
 
-pub type Successors<'a> = impl Iterator<Item = usize> + 'a;
+pub type Successors = Vec<BasicBlockIdx>;
 
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum TerminatorKind {
     Goto {
-        target: usize,
+        target: BasicBlockIdx,
     },
     SwitchInt {
         discr: Operand,
         targets: SwitchTargets,
-        otherwise: usize,
     },
     Resume,
     Abort,
@@ -137,43 +138,42 @@ pub enum TerminatorKind {
     Unreachable,
     Drop {
         place: Place,
-        target: usize,
+        target: BasicBlockIdx,
         unwind: UnwindAction,
     },
     Call {
         func: Operand,
         args: Vec<Operand>,
         destination: Place,
-        target: Option<usize>,
+        target: Option<BasicBlockIdx>,
         unwind: UnwindAction,
     },
     Assert {
         cond: Operand,
         expected: bool,
         msg: AssertMessage,
-        target: usize,
+        target: BasicBlockIdx,
         unwind: UnwindAction,
     },
-    CoroutineDrop,
     InlineAsm {
         template: String,
         operands: Vec<InlineAsmOperand>,
         options: String,
         line_spans: String,
-        destination: Option<usize>,
+        destination: Option<BasicBlockIdx>,
         unwind: UnwindAction,
     },
 }
 
 impl TerminatorKind {
-    pub fn successors(&self) -> Successors<'_> {
+    pub fn successors(&self) -> Successors {
         use self::TerminatorKind::*;
         match *self {
-            Call { target: Some(t), unwind: UnwindAction::Cleanup(ref u), .. }
-            | Drop { target: t, unwind: UnwindAction::Cleanup(ref u), .. }
-            | Assert { target: t, unwind: UnwindAction::Cleanup(ref u), .. }
-            | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } => {
-                Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied())
+            Call { target: Some(t), unwind: UnwindAction::Cleanup(u), .. }
+            | Drop { target: t, unwind: UnwindAction::Cleanup(u), .. }
+            | Assert { target: t, unwind: UnwindAction::Cleanup(u), .. }
+            | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(u), .. } => {
+                vec![t, u]
             }
             Goto { target: t }
             | Call { target: None, unwind: UnwindAction::Cleanup(t), .. }
@@ -182,21 +182,18 @@ impl TerminatorKind {
             | Assert { target: t, unwind: _, .. }
             | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(t), .. }
             | InlineAsm { destination: Some(t), unwind: _, .. } => {
-                Some(t).into_iter().chain((&[]).into_iter().copied())
+                vec![t]
             }
 
-            CoroutineDrop
-            | Return
+            Return
             | Resume
             | Abort
             | Unreachable
             | Call { target: None, unwind: _, .. }
             | InlineAsm { destination: None, unwind: _, .. } => {
-                None.into_iter().chain((&[]).into_iter().copied())
-            }
-            SwitchInt { ref targets, .. } => {
-                None.into_iter().chain(targets.targets.iter().copied())
+                vec![]
             }
+            SwitchInt { ref targets, .. } => targets.all_targets(),
         }
     }
 
@@ -205,7 +202,6 @@ impl TerminatorKind {
             TerminatorKind::Goto { .. }
             | TerminatorKind::Return
             | TerminatorKind::Unreachable
-            | TerminatorKind::CoroutineDrop
             | TerminatorKind::Resume
             | TerminatorKind::Abort
             | TerminatorKind::SwitchInt { .. } => None,
@@ -231,7 +227,7 @@ pub enum UnwindAction {
     Continue,
     Unreachable,
     Terminate,
-    Cleanup(usize),
+    Cleanup(BasicBlockIdx),
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -662,10 +658,42 @@ pub struct Constant {
     pub literal: Const,
 }
 
+/// The possible branch sites of a [TerminatorKind::SwitchInt].
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub struct SwitchTargets {
-    pub value: Vec<u128>,
-    pub targets: Vec<usize>,
+    /// The conditional branches where the first element represents the value that guards this
+    /// branch, and the second element is the branch target.
+    branches: Vec<(u128, BasicBlockIdx)>,
+    /// The `otherwise` branch which will be taken in case none of the conditional branches are
+    /// satisfied.
+    otherwise: BasicBlockIdx,
+}
+
+impl SwitchTargets {
+    /// All possible targets including the `otherwise` target.
+    pub fn all_targets(&self) -> Successors {
+        self.branches.iter().map(|(_, target)| *target).chain(Some(self.otherwise)).collect()
+    }
+
+    /// The `otherwise` branch target.
+    pub fn otherwise(&self) -> BasicBlockIdx {
+        self.otherwise
+    }
+
+    /// The conditional targets which are only taken if the pattern matches the given value.
+    pub fn branches(&self) -> impl Iterator<Item = (u128, BasicBlockIdx)> + '_ {
+        self.branches.iter().copied()
+    }
+
+    /// The number of targets including `otherwise`.
+    pub fn len(&self) -> usize {
+        self.branches.len() + 1
+    }
+
+    /// Create a new SwitchTargets from the given branches and `otherwise` target.
+    pub fn new(branches: Vec<(u128, BasicBlockIdx)>, otherwise: BasicBlockIdx) -> SwitchTargets {
+        SwitchTargets { branches, otherwise }
+    }
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index 759c3b148df..3a0eed521dc 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -76,7 +76,8 @@ pub fn pretty_statement(statement: &StatementKind) -> String {
 
 pub fn pretty_terminator<W: io::Write>(terminator: &TerminatorKind, w: &mut W) -> io::Result<()> {
     write!(w, "{}", pretty_terminator_head(terminator))?;
-    let successor_count = terminator.successors().count();
+    let successors = terminator.successors();
+    let successor_count = successors.len();
     let labels = pretty_successor_labels(terminator);
 
     let show_unwind = !matches!(terminator.unwind(), None | Some(UnwindAction::Cleanup(_)));
@@ -98,12 +99,12 @@ pub fn pretty_terminator<W: io::Write>(terminator: &TerminatorKind, w: &mut W) -
             Ok(())
         }
         (1, false) => {
-            write!(w, " -> {:?}", terminator.successors().next().unwrap())?;
+            write!(w, " -> {:?}", successors[0])?;
             Ok(())
         }
         _ => {
             write!(w, " -> [")?;
-            for (i, target) in terminator.successors().enumerate() {
+            for (i, target) in successors.iter().enumerate() {
                 if i > 0 {
                     write!(w, ", ")?;
                 }
@@ -157,7 +158,6 @@ pub fn pretty_terminator_head(terminator: &TerminatorKind) -> String {
             pretty.push_str(")");
             pretty
         }
-        CoroutineDrop => format!("        coroutine_drop"),
         InlineAsm { .. } => todo!(),
     }
 }
@@ -165,12 +165,11 @@ pub fn pretty_terminator_head(terminator: &TerminatorKind) -> String {
 pub fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec<String> {
     use self::TerminatorKind::*;
     match terminator {
-        Resume | Abort | Return | Unreachable | CoroutineDrop => vec![],
+        Resume | Abort | Return | Unreachable => vec![],
         Goto { .. } => vec!["".to_string()],
         SwitchInt { targets, .. } => targets
-            .value
-            .iter()
-            .map(|target| format!("{}", target))
+            .branches()
+            .map(|(val, _target)| format!("{val}"))
             .chain(iter::once("otherwise".into()))
             .collect(),
         Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()],
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index 69bf6ca72b0..0c44781c463 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -237,8 +237,7 @@ pub trait MirVisitor {
             TerminatorKind::Goto { .. }
             | TerminatorKind::Resume
             | TerminatorKind::Abort
-            | TerminatorKind::Unreachable
-            | TerminatorKind::CoroutineDrop => {}
+            | TerminatorKind::Unreachable => {}
             TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
                 self.visit_operand(cond, location);
                 self.visit_assert_msg(msg, location);
@@ -268,7 +267,7 @@ pub trait MirVisitor {
                 let local = RETURN_LOCAL;
                 self.visit_local(&local, PlaceContext::NON_MUTATING, location);
             }
-            TerminatorKind::SwitchInt { discr, targets: _, otherwise: _ } => {
+            TerminatorKind::SwitchInt { discr, targets: _ } => {
                 self.visit_operand(discr, location);
             }
         }
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 547a7b7052f..3b6fbf95faf 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -74,7 +74,7 @@ macro_rules! error_contains {
 // tests most of the time, but at least we do if the user has the right
 // permissions.
 pub fn got_symlink_permission(tmpdir: &TempDir) -> bool {
-    if cfg!(unix) {
+    if cfg!(not(windows)) || env::var_os("CI").is_some() {
         return true;
     }
     let link = tmpdir.join("some_hopefully_unique_link_name");
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index aaddf5ca09c..65af2aed6de 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -10,6 +10,7 @@ use std::io::{BufRead, BufReader};
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::sync::OnceLock;
 use std::time::{Duration, Instant};
 
 use crate::core::build_steps::llvm;
@@ -25,12 +26,10 @@ use crate::EXTRA_CHECK_CFGS;
 use crate::{Build, CLang, DocTests, GitRepo, Mode};
 
 pub use crate::Compiler;
-// FIXME:
-// - use std::lazy for `Lazy`
-// - use std::cell for `OnceCell`
-// Once they get stabilized and reach beta.
+
 use clap::ValueEnum;
-use once_cell::sync::{Lazy, OnceCell};
+// FIXME: replace with std::lazy after it gets stabilized and reaches beta
+use once_cell::sync::Lazy;
 
 #[cfg(test)]
 #[path = "../tests/builder.rs"]
@@ -496,7 +495,7 @@ impl<'a> ShouldRun<'a> {
     ///
     /// [`path`]: ShouldRun::path
     pub fn paths(mut self, paths: &[&str]) -> Self {
-        static SUBMODULES_PATHS: OnceCell<Vec<String>> = OnceCell::new();
+        static SUBMODULES_PATHS: OnceLock<Vec<String>> = OnceLock::new();
 
         let init_submodules_paths = |src: &PathBuf| {
             let file = File::open(src.join(".gitmodules")).unwrap();
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 9ef90798590..22e8ce8365b 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -17,6 +17,7 @@ use std::io::IsTerminal;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::str::FromStr;
+use std::sync::OnceLock;
 
 use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX;
 use crate::core::build_steps::llvm;
@@ -25,7 +26,6 @@ use crate::utils::cache::{Interned, INTERNER};
 use crate::utils::channel::{self, GitInfo};
 use crate::utils::helpers::{exe, output, t};
 use build_helper::exit;
-use once_cell::sync::OnceCell;
 use semver::Version;
 use serde::{Deserialize, Deserializer};
 use serde_derive::Deserialize;
@@ -1907,7 +1907,7 @@ impl Config {
     }
 
     pub(crate) fn download_rustc_commit(&self) -> Option<&str> {
-        static DOWNLOAD_RUSTC: OnceCell<Option<String>> = OnceCell::new();
+        static DOWNLOAD_RUSTC: OnceLock<Option<String>> = OnceLock::new();
         if self.dry_run() && DOWNLOAD_RUSTC.get().is_none() {
             // avoid trying to actually download the commit
             return self.download_rustc_commit.as_deref();
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 3327aed9600..0a5844a6859 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -5,10 +5,10 @@ use std::{
     io::{BufRead, BufReader, BufWriter, ErrorKind, Write},
     path::{Path, PathBuf},
     process::{Command, Stdio},
+    sync::OnceLock,
 };
 
 use build_helper::ci::CiEnv;
-use once_cell::sync::OnceCell;
 use xz2::bufread::XzDecoder;
 
 use crate::core::build_steps::llvm::detect_llvm_sha;
@@ -16,7 +16,7 @@ use crate::core::config::RustfmtMetadata;
 use crate::utils::helpers::{check_run, exe, program_out_of_date};
 use crate::{t, Config};
 
-static SHOULD_FIX_BINS_AND_DYLIBS: OnceCell<bool> = OnceCell::new();
+static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
 
 /// `Config::try_run` wrapper for this module to avoid warnings on `try_run`, since we don't have access to a `builder` yet.
 fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> {
@@ -131,7 +131,7 @@ impl Config {
         println!("attempting to patch {}", fname.display());
 
         // Only build `.nix-deps` once.
-        static NIX_DEPS_DIR: OnceCell<PathBuf> = OnceCell::new();
+        static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new();
         let mut nix_build_succeeded = true;
         let nix_deps_dir = NIX_DEPS_DIR.get_or_init(|| {
             // Run `nix-build` to "build" each dependency (which will likely reuse
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 480dd757915..60a89e9bf07 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -25,12 +25,12 @@ use std::io;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output, Stdio};
 use std::str;
+use std::sync::OnceLock;
 
 use build_helper::ci::{gha, CiEnv};
 use build_helper::exit;
 use build_helper::util::fail;
 use filetime::FileTime;
-use once_cell::sync::OnceCell;
 use sha2::digest::Digest;
 use termcolor::{ColorChoice, StandardStream, WriteColor};
 use utils::channel::GitInfo;
@@ -906,7 +906,7 @@ impl Build {
 
     /// Returns the sysroot of the snapshot compiler.
     fn rustc_snapshot_sysroot(&self) -> &Path {
-        static SYSROOT_CACHE: OnceCell<PathBuf> = once_cell::sync::OnceCell::new();
+        static SYSROOT_CACHE: OnceLock<PathBuf> = OnceLock::new();
         SYSROOT_CACHE.get_or_init(|| {
             let mut rustc = Command::new(&self.initial_rustc);
             rustc.args(&["--print", "sysroot"]);
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 89fa2b805cd..f878d634743 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -11,11 +11,11 @@ use std::io;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::str;
+use std::sync::OnceLock;
 use std::time::{Instant, SystemTime, UNIX_EPOCH};
 
 use crate::core::builder::Builder;
 use crate::core::config::{Config, TargetSelection};
-use crate::OnceCell;
 
 pub use crate::utils::dylib::{dylib_path, dylib_path_var};
 
@@ -444,7 +444,7 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf {
 }
 
 pub fn lld_flag_no_threads(is_windows: bool) -> &'static str {
-    static LLD_NO_THREADS: OnceCell<(&'static str, &'static str)> = OnceCell::new();
+    static LLD_NO_THREADS: OnceLock<(&'static str, &'static str)> = OnceLock::new();
     let (windows, other) = LLD_NO_THREADS.get_or_init(|| {
         let out = output(Command::new("lld").arg("-flavor").arg("ld").arg("--version"));
         let newer = match (out.find(char::is_numeric), out.find('.')) {
diff --git a/src/doc/unstable-book/src/language-features/link-arg-attribute.md b/src/doc/unstable-book/src/language-features/link-arg-attribute.md
new file mode 100644
index 00000000000..09915a7f274
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/link-arg-attribute.md
@@ -0,0 +1,21 @@
+# `link_arg_attribute`
+
+The tracking issue for this feature is: [#99427]
+
+------
+
+The `link_arg_attribute` feature allows passing arguments into the linker
+from inside of the source code. Order is preserved for link attributes as
+they were defined on a single extern block:
+
+```rust,no_run
+#![feature(link_arg_attribute)]
+
+#[link(kind = "link-arg", name = "--start-group")]
+#[link(kind = "static", name = "c")]
+#[link(kind = "static", name = "gcc")]
+#[link(kind = "link-arg", name = "--end-group")]
+extern "C" {}
+```
+
+[#99427]: https://github.com/rust-lang/rust/issues/99427
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bed8f6ffef5..a9c0ab557cb 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -367,7 +367,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
 
             if ending == Ending::Newline {
                 let mut clause = " ".repeat(indent.saturating_sub(1));
-                write!(clause, "<span class=\"where fmt-newline\">where{where_preds},</span>")?;
+                write!(clause, "<div class=\"where\">where{where_preds},</div>")?;
                 clause
             } else {
                 // insert a newline after a single space but before multiple spaces at the start
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 348d546c236..e076c1b92e6 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1145,7 +1145,7 @@ impl<'a> AssocItemLink<'a> {
 fn write_impl_section_heading(mut w: impl fmt::Write, title: &str, id: &str) {
     write!(
         w,
-        "<h2 id=\"{id}\" class=\"small-section-header\">\
+        "<h2 id=\"{id}\" class=\"section-header\">\
             {title}\
             <a href=\"#{id}\" class=\"anchor\">§</a>\
          </h2>"
@@ -1441,15 +1441,10 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
                     );
                 }
 
-                //use the "where" class here to make it small
-                write!(
-                    &mut out,
-                    "<span class=\"where fmt-newline\">{}</span>",
-                    impl_.print(false, cx)
-                );
+                write!(&mut out, "<div class=\"where\">{}</div>", impl_.print(false, cx));
                 for it in &impl_.items {
                     if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
-                        out.push_str("<span class=\"where fmt-newline\">    ");
+                        out.push_str("<div class=\"where\">    ");
                         let empty_set = FxHashSet::default();
                         let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
                         assoc_type(
@@ -1462,7 +1457,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
                             0,
                             cx,
                         );
-                        out.push_str(";</span>");
+                        out.push_str(";</div>");
                     }
                 }
             }
@@ -1948,7 +1943,7 @@ pub(crate) fn render_impl_summary(
         if show_def_docs {
             for it in &inner_impl.items {
                 if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
-                    w.write_str("<span class=\"where fmt-newline\">  ");
+                    w.write_str("<div class=\"where\">  ");
                     assoc_type(
                         w,
                         it,
@@ -1959,7 +1954,7 @@ pub(crate) fn render_impl_summary(
                         0,
                         cx,
                     );
-                    w.write_str(";</span>");
+                    w.write_str(";</div>");
                 }
             }
         }
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 2dac943f695..e4309c782f6 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -430,7 +430,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
             last_section = Some(my_section);
             write!(
                 w,
-                "<h2 id=\"{id}\" class=\"small-section-header\">\
+                "<h2 id=\"{id}\" class=\"section-header\">\
                     <a href=\"#{id}\">{name}</a>\
                  </h2>{ITEM_TABLE_OPEN}",
                 id = cx.derive_id(my_section.id()),
@@ -827,7 +827,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
     fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) {
         write!(
             w,
-            "<h2 id=\"{0}\" class=\"small-section-header\">\
+            "<h2 id=\"{0}\" class=\"section-header\">\
                 {1}<a href=\"#{0}\" class=\"anchor\">§</a>\
              </h2>{2}",
             id, title, extra_content
@@ -1260,7 +1260,7 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
     if let Some(inner_type) = &t.inner_type {
         write!(
             w,
-            "<h2 id=\"aliased-type\" class=\"small-section-header\">\
+            "<h2 id=\"aliased-type\" class=\"section-header\">\
                 Aliased Type<a href=\"#aliased-type\" class=\"anchor\">§</a></h2>"
         );
 
@@ -1685,7 +1685,7 @@ fn item_variants(
     let tcx = cx.tcx();
     write!(
         w,
-        "<h2 id=\"variants\" class=\"variants small-section-header\">\
+        "<h2 id=\"variants\" class=\"variants section-header\">\
             Variants{}<a href=\"#variants\" class=\"anchor\">§</a>\
         </h2>\
         {}\
@@ -1772,7 +1772,7 @@ fn item_variants(
                         write!(
                             w,
                             "<div class=\"sub-variant-field\">\
-                                 <span id=\"{id}\" class=\"small-section-header\">\
+                                 <span id=\"{id}\" class=\"section-header\">\
                                      <a href=\"#{id}\" class=\"anchor field\">§</a>\
                                      <code>{f}: {t}</code>\
                                  </span>",
@@ -1929,7 +1929,7 @@ fn item_fields(
         if fields.peek().is_some() {
             write!(
                 w,
-                "<h2 id=\"fields\" class=\"fields small-section-header\">\
+                "<h2 id=\"fields\" class=\"fields section-header\">\
                      {}{}<a href=\"#fields\" class=\"anchor\">§</a>\
                  </h2>\
                  {}",
@@ -1943,7 +1943,7 @@ fn item_fields(
                 let id = cx.derive_id(format!("{typ}.{field_name}", typ = ItemType::StructField));
                 write!(
                     w,
-                    "<span id=\"{id}\" class=\"{item_type} small-section-header\">\
+                    "<span id=\"{id}\" class=\"{item_type} section-header\">\
                          <a href=\"#{id}\" class=\"anchor field\">§</a>\
                          <code>{field_name}: {ty}</code>\
                      </span>",
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 9efdcd60117..b898eb5d381 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -205,7 +205,7 @@ ul.all-items {
 
 #toggle-all-docs,
 a.anchor,
-.small-section-header a,
+.section-header a,
 #src-sidebar a,
 .rust a,
 .sidebar h2 a,
@@ -703,11 +703,8 @@ pre, .rustdoc.src .example-wrap {
 	background: var(--table-alt-row-background-color);
 }
 
-/* Shift "where ..." part of method or fn definition down a line */
-.method .where,
-.fn .where,
-.where.fmt-newline {
-	display: block;
+/* "where ..." clauses with block display are also smaller */
+div.where {
 	white-space: pre-wrap;
 	font-size: 0.875rem;
 }
@@ -742,13 +739,13 @@ nav.sub {
 	margin: 0 0 15px 0;
 }
 
-.small-section-header {
+.section-header {
 	/* fields use <span> tags, but should get their own lines */
 	display: block;
 	position: relative;
 }
 
-.small-section-header:hover > .anchor, .impl:hover > .anchor,
+.section-header:hover > .anchor, .impl:hover > .anchor,
 .trait-impl:hover > .anchor, .variant:hover > .anchor {
 	display: initial;
 }
@@ -761,11 +758,11 @@ nav.sub {
 .anchor.field {
 	left: -5px;
 }
-.small-section-header > .anchor {
+.section-header > .anchor {
 	left: -15px;
 	padding-right: 8px;
 }
-h2.small-section-header > .anchor {
+h2.section-header > .anchor {
 	padding-right: 6px;
 }
 
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 979aebdb7be..8f68796ad26 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -287,10 +287,6 @@ function initSearch(rawSearchIndex) {
         }
     }
 
-    function isWhitespace(c) {
-        return " \t\n\r".indexOf(c) !== -1;
-    }
-
     function isSpecialStartCharacter(c) {
         return "<\"".indexOf(c) !== -1;
     }
@@ -408,7 +404,7 @@ function initSearch(rawSearchIndex) {
      * @return {boolean}
      */
     function isPathSeparator(c) {
-        return c === ":" || isWhitespace(c);
+        return c === ":" || c === " ";
     }
 
     /**
@@ -425,7 +421,7 @@ function initSearch(rawSearchIndex) {
             const c = parserState.userQuery[pos - 1];
             if (c === lookingFor) {
                 return true;
-            } else if (!isWhitespace(c)) {
+            } else if (c !== " ") {
                 break;
             }
             pos -= 1;
@@ -454,7 +450,7 @@ function initSearch(rawSearchIndex) {
     function skipWhitespace(parserState) {
         while (parserState.pos < parserState.userQuery.length) {
             const c = parserState.userQuery[parserState.pos];
-            if (!isWhitespace(c)) {
+            if (c !== " ") {
                 break;
             }
             parserState.pos += 1;
@@ -473,8 +469,6 @@ function initSearch(rawSearchIndex) {
         const path = name.trim();
         if (path.length === 0 && generics.length === 0) {
             throw ["Unexpected ", parserState.userQuery[parserState.pos]];
-        } else if (path === "*") {
-            throw ["Unexpected ", "*"];
         }
         if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) {
             throw ["Cannot have more than one element if you use quotes"];
@@ -512,18 +506,15 @@ function initSearch(rawSearchIndex) {
                 bindingName,
             };
         }
+        const quadcolon = /::\s*::/.exec(path);
         if (path.startsWith("::")) {
             throw ["Paths cannot start with ", "::"];
         } else if (path.endsWith("::")) {
             throw ["Paths cannot end with ", "::"];
-        } else if (path.includes("::::")) {
-            throw ["Unexpected ", "::::"];
-        } else if (path.includes(" ::")) {
-            throw ["Unexpected ", " ::"];
-        } else if (path.includes(":: ")) {
-            throw ["Unexpected ", ":: "];
-        }
-        const pathSegments = path.split(/::|\s+/);
+        } else if (quadcolon !== null) {
+            throw ["Unexpected ", quadcolon[0]];
+        }
+        const pathSegments = path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/);
         // In case we only have something like `<p>`, there is no name.
         if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) {
             if (generics.length > 0 || prevIs(parserState, ">")) {
@@ -604,7 +595,7 @@ function initSearch(rawSearchIndex) {
                     } else {
                         while (parserState.pos + 1 < parserState.length) {
                             const next_c = parserState.userQuery[parserState.pos + 1];
-                            if (!isWhitespace(next_c)) {
+                            if (next_c !== " ") {
                                 break;
                             }
                             parserState.pos += 1;
@@ -958,7 +949,7 @@ function initSearch(rawSearchIndex) {
                 query.literalSearch = false;
                 foundStopChar = true;
                 continue;
-            } else if (isWhitespace(c)) {
+            } else if (c === " ") {
                 skipWhitespace(parserState);
                 continue;
             }
@@ -1118,7 +1109,7 @@ function initSearch(rawSearchIndex) {
                 }
             }
         }
-        userQuery = userQuery.trim();
+        userQuery = userQuery.trim().replace(/\r|\n|\t/g, " ");
         const parserState = {
             length: userQuery.length,
             pos: 0,
diff --git a/src/librustdoc/html/templates/item_union.html b/src/librustdoc/html/templates/item_union.html
index f6d2fa34890..8db7986fa75 100644
--- a/src/librustdoc/html/templates/item_union.html
+++ b/src/librustdoc/html/templates/item_union.html
@@ -4,13 +4,13 @@
 </code></pre>
 {{ self.document() | safe }}
 {% if self.fields_iter().peek().is_some() %}
-    <h2 id="fields" class="fields small-section-header"> {# #}
+    <h2 id="fields" class="fields section-header"> {# #}
         Fields<a href="#fields" class="anchor">§</a> {# #}
     </h2>
     {% for (field, ty) in self.fields_iter() %}
         {% let name = field.name.expect("union field name") %}
         <span id="structfield.{{ name }}" {#+ #}
-            class="{{ ItemType::StructField +}} small-section-header"> {# #}
+            class="{{ ItemType::StructField +}} section-header"> {# #}
             <a href="#structfield.{{ name }}" class="anchor field">§</a> {# #}
             <code>{{ name }}: {{+ self.print_ty(ty) | safe }}</code> {# #}
         </span>
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html
index c75fc34a9df..e0516bb42fe 100644
--- a/src/librustdoc/html/templates/type_layout.html
+++ b/src/librustdoc/html/templates/type_layout.html
@@ -1,4 +1,4 @@
-<h2 id="layout" class="small-section-header"> {# #}
+<h2 id="layout" class="section-header"> {# #}
     Layout<a href="#layout" class="anchor">§</a> {# #}
 </h2> {# #}
 <div class="docblock"> {# #}
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 1ae8ac81695..49f0cad08e0 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -183,7 +183,7 @@ pub fn main() {
         // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't
         // accept a generic closure.
         let version_info = rustc_tools_util::get_version_info!();
-        handler.note_without_error(format!("Clippy version: {version_info}"));
+        handler.note(format!("Clippy version: {version_info}"));
     });
 
     exit(rustc_driver::catch_with_exit_code(move || {
diff --git a/src/tools/clippy/tests/integration.rs b/src/tools/clippy/tests/integration.rs
index 031982edbe9..267f095f9c2 100644
--- a/src/tools/clippy/tests/integration.rs
+++ b/src/tools/clippy/tests/integration.rs
@@ -69,15 +69,15 @@ fn integration_test() {
     // debug:
     eprintln!("{stderr}");
 
-    // this is an internal test to make sure we would correctly panic on a delay_span_bug
+    // this is an internal test to make sure we would correctly panic on a span_delayed_bug
     if repo_name == "matthiaskrgr/clippy_ci_panic_test" {
         // we need to kind of switch around our logic here:
         // if we find a panic, everything is fine, if we don't panic, SOMETHING is broken about our testing
 
-        // the repo basically just contains a delay_span_bug that forces rustc/clippy to panic:
+        // the repo basically just contains a span_delayed_bug that forces rustc/clippy to panic:
         /*
            #![feature(rustc_attrs)]
-           #[rustc_error(delay_span_bug_from_inside_query)]
+           #[rustc_error(span_delayed_bug_from_inside_query)]
            fn main() {}
         */
 
@@ -86,7 +86,7 @@ fn integration_test() {
             return;
         }
 
-        panic!("panic caused by delay_span_bug was NOT detected! Something is broken!");
+        panic!("panic caused by span_delayed_bug was NOT detected! Something is broken!");
     }
 
     if let Some(backtrace_start) = stderr.find("error: internal compiler error") {
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.fixed b/src/tools/clippy/tests/ui/needless_raw_string.fixed
index 4ea711fd67a..1a9c601c462 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string.fixed
@@ -1,6 +1,5 @@
 #![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
 #![warn(clippy::needless_raw_strings)]
-#![feature(c_str_literals)]
 
 fn main() {
     "aaa";
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.rs b/src/tools/clippy/tests/ui/needless_raw_string.rs
index b6239f9b1f0..1126ea5aa30 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string.rs
@@ -1,6 +1,5 @@
 #![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
 #![warn(clippy::needless_raw_strings)]
-#![feature(c_str_literals)]
 
 fn main() {
     r#"aaa"#;
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.stderr b/src/tools/clippy/tests/ui/needless_raw_string.stderr
index 276bc84c6c3..b2188698564 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string.stderr
@@ -1,5 +1,5 @@
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:6:5
+  --> $DIR/needless_raw_string.rs:5:5
    |
 LL |     r#"aaa"#;
    |     ^^^^^^^^
@@ -13,7 +13,7 @@ LL +     "aaa";
    |
 
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:9:5
+  --> $DIR/needless_raw_string.rs:8:5
    |
 LL |     br#"aaa"#;
    |     ^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     b"aaa";
    |
 
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:12:5
+  --> $DIR/needless_raw_string.rs:11:5
    |
 LL |     cr#"aaa"#;
    |     ^^^^^^^^^
@@ -37,7 +37,7 @@ LL +     c"aaa";
    |
 
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:16:5
+  --> $DIR/needless_raw_string.rs:15:5
    |
 LL | /     r#"
 LL | |         a
@@ -56,7 +56,7 @@ LL ~     ";
    |
 
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:22:5
+  --> $DIR/needless_raw_string.rs:21:5
    |
 LL |     r"no hashes";
    |     ^^^^^^^^^^^^
@@ -68,7 +68,7 @@ LL +     "no hashes";
    |
 
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:23:5
+  --> $DIR/needless_raw_string.rs:22:5
    |
 LL |     br"no hashes";
    |     ^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL +     b"no hashes";
    |
 
 error: unnecessary raw string literal
-  --> $DIR/needless_raw_string.rs:24:5
+  --> $DIR/needless_raw_string.rs:23:5
    |
 LL |     cr"no hashes";
    |     ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
index c99c2f46532..b2ad657d6b2 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
@@ -1,6 +1,5 @@
 #![allow(clippy::no_effect, unused)]
 #![warn(clippy::needless_raw_string_hashes)]
-#![feature(c_str_literals)]
 
 fn main() {
     r"\aaa";
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
index dcc2af69f4e..54d8ed76d47 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
@@ -1,6 +1,5 @@
 #![allow(clippy::no_effect, unused)]
 #![warn(clippy::needless_raw_string_hashes)]
-#![feature(c_str_literals)]
 
 fn main() {
     r#"\aaa"#;
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
index 017160b1a42..c74eff8161e 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
@@ -1,5 +1,5 @@
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:6:5
+  --> $DIR/needless_raw_string_hashes.rs:5:5
    |
 LL |     r#"\aaa"#;
    |     ^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     r"\aaa";
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:7:5
+  --> $DIR/needless_raw_string_hashes.rs:6:5
    |
 LL |     r##"Hello "world"!"##;
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     r#"Hello "world"!"#;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:8:5
+  --> $DIR/needless_raw_string_hashes.rs:7:5
    |
 LL |     r######" "### "## "# "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL +     r####" "### "## "# "####;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:9:5
+  --> $DIR/needless_raw_string_hashes.rs:8:5
    |
 LL |     r######" "aa" "# "## "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL +     r###" "aa" "# "## "###;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:10:5
+  --> $DIR/needless_raw_string_hashes.rs:9:5
    |
 LL |     br#"\aaa"#;
    |     ^^^^^^^^^^
@@ -61,7 +61,7 @@ LL +     br"\aaa";
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:11:5
+  --> $DIR/needless_raw_string_hashes.rs:10:5
    |
 LL |     br##"Hello "world"!"##;
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL +     br#"Hello "world"!"#;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:12:5
+  --> $DIR/needless_raw_string_hashes.rs:11:5
    |
 LL |     br######" "### "## "# "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL +     br####" "### "## "# "####;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:13:5
+  --> $DIR/needless_raw_string_hashes.rs:12:5
    |
 LL |     br######" "aa" "# "## "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL +     br###" "aa" "# "## "###;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:14:5
+  --> $DIR/needless_raw_string_hashes.rs:13:5
    |
 LL |     cr#"\aaa"#;
    |     ^^^^^^^^^^
@@ -109,7 +109,7 @@ LL +     cr"\aaa";
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:15:5
+  --> $DIR/needless_raw_string_hashes.rs:14:5
    |
 LL |     cr##"Hello "world"!"##;
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL +     cr#"Hello "world"!"#;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:16:5
+  --> $DIR/needless_raw_string_hashes.rs:15:5
    |
 LL |     cr######" "### "## "# "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL +     cr####" "### "## "# "####;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:17:5
+  --> $DIR/needless_raw_string_hashes.rs:16:5
    |
 LL |     cr######" "aa" "# "## "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ LL +     cr###" "aa" "# "## "###;
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:19:5
+  --> $DIR/needless_raw_string_hashes.rs:18:5
    |
 LL | /     r#"
 LL | |         \a
@@ -164,7 +164,7 @@ LL ~     ";
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:25:5
+  --> $DIR/needless_raw_string_hashes.rs:24:5
    |
 LL |     r###"rust"###;
    |     ^^^^^^^^^^^^^
@@ -176,7 +176,7 @@ LL +     r"rust";
    |
 
 error: unnecessary hashes around raw string literal
-  --> $DIR/needless_raw_string_hashes.rs:26:5
+  --> $DIR/needless_raw_string_hashes.rs:25:5
    |
 LL |     r#"hello world"#;
    |     ^^^^^^^^^^^^^^^^
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 10a11e8e291..af224360319 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -474,14 +474,12 @@ impl<'test> TestCx<'test> {
             self.fatal("missing --coverage-dump");
         };
 
-        let proc_res = self.compile_test_and_save_ir();
+        let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir();
         if !proc_res.status.success() {
             self.fatal_proc_rec("compilation failed!", &proc_res);
         }
         drop(proc_res);
 
-        let llvm_ir_path = self.output_base_name().with_extension("ll");
-
         let mut dump_command = Command::new(coverage_dump_path);
         dump_command.arg(llvm_ir_path);
         let proc_res = self.run_command_to_procres(&mut dump_command);
@@ -2785,10 +2783,54 @@ impl<'test> TestCx<'test> {
         proc_res.fatal(None, || on_failure(*self));
     }
 
+    fn get_output_file(&self, extension: &str) -> TargetLocation {
+        let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin"));
+        if thin_lto {
+            TargetLocation::ThisDirectory(self.output_base_dir())
+        } else {
+            // This works with both `--emit asm` (as default output name for the assembly)
+            // and `ptx-linker` because the latter can write output at requested location.
+            let output_path = self.output_base_name().with_extension(extension);
+            let output_file = TargetLocation::ThisFile(output_path.clone());
+            output_file
+        }
+    }
+
+    fn get_filecheck_file(&self, extension: &str) -> PathBuf {
+        let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin"));
+        if thin_lto {
+            let name = self.testpaths.file.file_stem().unwrap().to_str().unwrap();
+            let canonical_name = name.replace('-', "_");
+            let mut output_file = None;
+            for entry in self.output_base_dir().read_dir().unwrap() {
+                if let Ok(entry) = entry {
+                    let entry_path = entry.path();
+                    let entry_file = entry_path.file_name().unwrap().to_str().unwrap();
+                    if entry_file.starts_with(&format!("{}.{}", name, canonical_name))
+                        && entry_file.ends_with(extension)
+                    {
+                        assert!(
+                            output_file.is_none(),
+                            "thinlto doesn't support multiple cgu tests"
+                        );
+                        output_file = Some(entry_file.to_string());
+                    }
+                }
+            }
+            if let Some(output_file) = output_file {
+                self.output_base_dir().join(output_file)
+            } else {
+                self.output_base_name().with_extension(extension)
+            }
+        } else {
+            self.output_base_name().with_extension(extension)
+        }
+    }
+
     // codegen tests (using FileCheck)
 
-    fn compile_test_and_save_ir(&self) -> ProcRes {
-        let output_file = TargetLocation::ThisDirectory(self.output_base_dir());
+    fn compile_test_and_save_ir(&self) -> (ProcRes, PathBuf) {
+        let output_file = self.get_output_file("ll");
         let input_file = &self.testpaths.file;
         let rustc = self.make_compile_args(
             input_file,
@@ -2799,15 +2841,13 @@ impl<'test> TestCx<'test> {
             Vec::new(),
         );
 
-        self.compose_and_run_compiler(rustc, None)
+        let proc_res = self.compose_and_run_compiler(rustc, None);
+        let output_path = self.get_filecheck_file("ll");
+        (proc_res, output_path)
     }
 
     fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
-        // This works with both `--emit asm` (as default output name for the assembly)
-        // and `ptx-linker` because the latter can write output at requested location.
-        let output_path = self.output_base_name().with_extension("s");
-
-        let output_file = TargetLocation::ThisFile(output_path.clone());
+        let output_file = self.get_output_file("s");
         let input_file = &self.testpaths.file;
 
         let mut emit = Emit::None;
@@ -2837,7 +2877,9 @@ impl<'test> TestCx<'test> {
             Vec::new(),
         );
 
-        (self.compose_and_run_compiler(rustc, None), output_path)
+        let proc_res = self.compose_and_run_compiler(rustc, None);
+        let output_path = self.get_filecheck_file("s");
+        (proc_res, output_path)
     }
 
     fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
@@ -2870,7 +2912,7 @@ impl<'test> TestCx<'test> {
             self.fatal("missing --llvm-filecheck");
         }
 
-        let proc_res = self.compile_test_and_save_ir();
+        let (proc_res, output_path) = self.compile_test_and_save_ir();
         if !proc_res.status.success() {
             self.fatal_proc_rec("compilation failed!", &proc_res);
         }
@@ -2878,8 +2920,6 @@ impl<'test> TestCx<'test> {
         if let Some(PassMode::Build) = self.pass_mode() {
             return;
         }
-
-        let output_path = self.output_base_name().with_extension("ll");
         let proc_res = self.verify_with_filecheck(&output_path);
         if !proc_res.status.success() {
             self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 542c0c6cee9..d538a0c9ff5 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-c52b8763bf36027f24baabe1f97cab3d3571c9e5
+0919ad18381f6f4fcaddc809e786553e028bbde0
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index c2ef7710011..fb90559f3d1 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -384,7 +384,7 @@ pub fn report_error<'tcx, 'mir>(
 
     // Include a note like `std` does when we omit frames from a backtrace
     if was_pruned {
-        ecx.tcx.sess.diagnostic().note_without_error(
+        ecx.tcx.sess.diagnostic().note(
             "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace",
         );
     }
@@ -431,7 +431,7 @@ pub fn report_leaks<'mir, 'tcx>(
         );
     }
     if any_pruned {
-        ecx.tcx.sess.diagnostic().note_without_error(
+        ecx.tcx.sess.diagnostic().note(
             "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace",
         );
     }
@@ -456,7 +456,7 @@ pub fn report_msg<'tcx>(
     let mut err = match diag_level {
         DiagLevel::Error => sess.struct_span_err(span, title).forget_guarantee(),
         DiagLevel::Warning => sess.struct_span_warn(span, title),
-        DiagLevel::Note => sess.diagnostic().span_note_diag(span, title),
+        DiagLevel::Note => sess.diagnostic().struct_span_note(span, title),
     };
 
     // Show main message.
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 1345b22a34a..875a78974fa 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -464,7 +464,7 @@ pub fn eval_entry<'tcx>(
         // Check for thread leaks.
         if !ecx.have_all_terminated() {
             tcx.sess.err("the main thread terminated without waiting for all remaining threads");
-            tcx.sess.note_without_error("pass `-Zmiri-ignore-leaks` to disable this check");
+            tcx.sess.note("pass `-Zmiri-ignore-leaks` to disable this check");
             return None;
         }
         // Check for memory leaks.
@@ -475,7 +475,7 @@ pub fn eval_entry<'tcx>(
             let leak_message = "the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check";
             if ecx.machine.collect_leak_backtraces {
                 // If we are collecting leak backtraces, each leak is a distinct error diagnostic.
-                tcx.sess.note_without_error(leak_message);
+                tcx.sess.note(leak_message);
             } else {
                 // If we do not have backtraces, we just report an error without any span.
                 tcx.sess.err(leak_message);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
index 2ae3cd2a939..15dceeb8af2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
@@ -629,7 +629,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),
     rustc_attr!(
         TEST, rustc_error, Normal,
-        template!(Word, List: "delay_span_bug_from_inside_query"), WarnFollowingWordOnly
+        template!(Word, List: "span_delayed_bug_from_inside_query"), WarnFollowingWordOnly
     ),
     rustc_attr!(TEST, rustc_dump_user_substs, Normal, template!(Word), WarnFollowing),
     rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index b2591f016d4..27c79499868 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -110,7 +110,7 @@ struct LayoutCx<'a> {
 impl<'a> LayoutCalculator for LayoutCx<'a> {
     type TargetDataLayoutRef = &'a TargetDataLayout;
 
-    fn delay_bug(&self, txt: String) {
+    fn delayed_bug(&self, txt: String) {
         never!("{}", txt);
     }
 
diff --git a/tests/assembly/thin-lto.rs b/tests/assembly/thin-lto.rs
new file mode 100644
index 00000000000..deb8fd21d14
--- /dev/null
+++ b/tests/assembly/thin-lto.rs
@@ -0,0 +1,8 @@
+// compile-flags: -O -C lto=thin -C prefer-dynamic=no
+// only-x86_64-unknown-linux-gnu
+// assembly-output: emit-asm
+
+// CHECK: main
+
+pub fn main() {
+}
diff --git a/tests/codegen/thin-lto.rs b/tests/codegen/thin-lto.rs
new file mode 100644
index 00000000000..7991cad7a0c
--- /dev/null
+++ b/tests/codegen/thin-lto.rs
@@ -0,0 +1,7 @@
+// compile-flags: -O -C lto=thin -C prefer-dynamic=no
+// only-x86_64-unknown-linux-gnu
+
+// CHECK: main
+
+pub fn main() {
+}
diff --git a/tests/coverage/thin-lto.cov-map b/tests/coverage/thin-lto.cov-map
new file mode 100644
index 00000000000..7e84e398f84
--- /dev/null
+++ b/tests/coverage/thin-lto.cov-map
@@ -0,0 +1,8 @@
+Function name: thin_lto::main
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 01, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 2)
+
diff --git a/tests/coverage/thin-lto.coverage b/tests/coverage/thin-lto.coverage
new file mode 100644
index 00000000000..21abb5dce04
--- /dev/null
+++ b/tests/coverage/thin-lto.coverage
@@ -0,0 +1,5 @@
+   LL|       |// compile-flags: -O -C lto=thin -C prefer-dynamic=no
+   LL|       |
+   LL|      1|pub fn main() {
+   LL|      1|}
+
diff --git a/tests/coverage/thin-lto.rs b/tests/coverage/thin-lto.rs
new file mode 100644
index 00000000000..050aac26319
--- /dev/null
+++ b/tests/coverage/thin-lto.rs
@@ -0,0 +1,4 @@
+// compile-flags: -O -C lto=thin -C prefer-dynamic=no
+
+pub fn main() {
+}
diff --git a/tests/incremental/delayed_span_bug.rs b/tests/incremental/delayed_span_bug.rs
index 2529e531e30..cc9831fff96 100644
--- a/tests/incremental/delayed_span_bug.rs
+++ b/tests/incremental/delayed_span_bug.rs
@@ -1,8 +1,8 @@
 // revisions: cfail1 cfail2
 // should-ice
-// error-pattern: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]
+// error-pattern: delayed span bug triggered by #[rustc_error(span_delayed_bug_from_inside_query)]
 
 #![feature(rustc_attrs)]
 
-#[rustc_error(delay_span_bug_from_inside_query)]
+#[rustc_error(span_delayed_bug_from_inside_query)]
 fn main() {}
diff --git a/tests/run-make/no-builtins-lto/Makefile b/tests/run-make/no-builtins-lto/Makefile
index c8f05d9918b..c7be4836466 100644
--- a/tests/run-make/no-builtins-lto/Makefile
+++ b/tests/run-make/no-builtins-lto/Makefile
@@ -1,9 +1,15 @@
 include ../tools.mk
 
+# only-x86_64
+
+# We want to check that `no_builtins` is correctly participating in LTO.
+# First, verify that the `foo::foo` symbol can be found when linking.
+# Next, verify that `memcpy` can be customized using `no_builtins` under LTO.
+# Others will use the built-in memcpy.
+
 all:
-	# Compile a `#![no_builtins]` rlib crate
-	$(RUSTC) no_builtins.rs
-	# Build an executable that depends on that crate using LTO. The no_builtins crate doesn't
-	# participate in LTO, so its rlib must be explicitly linked into the final binary. Verify this by
-	# grepping the linker arguments.
-	$(RUSTC) main.rs -C lto --print link-args | $(CGREP) 'libno_builtins.rlib'
+	$(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 foo.rs
+	$(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 no_builtins.rs
+	$(RUSTC) main.rs -C lto -C opt-level=2 -C debuginfo=0 -C save-temps -C metadata=1 -C codegen-units=1
+	"$(LLVM_BIN_DIR)"/llvm-dis $(TMPDIR)/main.main.*-cgu.0.rcgu.lto.input.bc -o $(TMPDIR)/lto.ll
+	cat "$(TMPDIR)"/lto.ll | "$(LLVM_FILECHECK)" filecheck.lto.txt
diff --git a/tests/run-make/no-builtins-lto/filecheck.lto.txt b/tests/run-make/no-builtins-lto/filecheck.lto.txt
new file mode 100644
index 00000000000..79dc3a51501
--- /dev/null
+++ b/tests/run-make/no-builtins-lto/filecheck.lto.txt
@@ -0,0 +1,17 @@
+CHECK: define{{.*}} void @bar
+CHECK-NEXT: call void @no_builtins
+CHECK-NEXT: call void @llvm.memcpy
+
+CHECK: define{{.*}} i32 @main
+CHECK: call void @bar
+
+CHECK: define{{.*}} void @foo
+CHECK-NEXT: call void @llvm.memcpy
+
+CHECK: define{{.*}} void @no_builtins
+CHECK-SAME: #[[ATTR:[0-9]+]] {
+CHECK: call void @foo
+CHECK-NEXT: call{{.*}} @memcpy
+
+CHECK: attributes #[[ATTR]]
+CHECK-SAME: no-builtins
diff --git a/tests/run-make/no-builtins-lto/foo.rs b/tests/run-make/no-builtins-lto/foo.rs
new file mode 100644
index 00000000000..f09ac40b152
--- /dev/null
+++ b/tests/run-make/no-builtins-lto/foo.rs
@@ -0,0 +1,33 @@
+#![feature(lang_items, no_core)]
+#![no_std]
+#![no_core]
+#![crate_type = "lib"]
+
+#[inline(never)]
+#[no_mangle]
+pub unsafe fn foo(dest: *mut u8, src: *const u8) {
+    // should call `@llvm.memcpy`.
+    memcpy(dest, src, 1024);
+}
+
+#[no_mangle]
+#[inline(never)]
+pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, _n: usize) -> *mut u8 {
+    *dest = 0;
+    return src as *mut u8;
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+impl Copy for *mut u8 {}
+impl Copy for *const u8 {}
+
+#[lang = "drop_in_place"]
+#[allow(unconditional_recursion)]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+    // Code here does not matter - this is replaced by the
+    // real drop glue by the compiler.
+    drop_in_place(to_drop);
+}
diff --git a/tests/run-make/no-builtins-lto/main.rs b/tests/run-make/no-builtins-lto/main.rs
index 890c999c8cc..4421a2afbce 100644
--- a/tests/run-make/no-builtins-lto/main.rs
+++ b/tests/run-make/no-builtins-lto/main.rs
@@ -1,3 +1,29 @@
+#![feature(no_core, start, lang_items)]
+#![no_std]
+// We use `no_core` to reduce the LTO products is small enough.
+#![no_core]
+
 extern crate no_builtins;
+extern crate foo;
+
+#[cfg_attr(unix, link(name = "c"))]
+#[cfg_attr(target_env = "msvc", link(name = "msvcrt"))]
+extern "C" {}
+
+#[start]
+fn main(_: isize, p: *const *const u8) -> isize {
+    // Make sure the symbols are retained.
+    unsafe { bar(*p as *mut u8, *p); }
+    0
+}
+
+#[no_mangle]
+#[inline(never)]
+pub unsafe extern "C" fn bar(dest: *mut u8, src: *const u8) {
+    no_builtins::no_builtins(dest, src);
+    // should call `@llvm.memcpy`
+    foo::memcpy(dest, src, 1024);
+}
 
-fn main() {}
+#[lang = "eh_personality"]
+fn eh_personality() {}
diff --git a/tests/run-make/no-builtins-lto/no_builtins.rs b/tests/run-make/no-builtins-lto/no_builtins.rs
index 5d001031a57..33ed68e3aee 100644
--- a/tests/run-make/no-builtins-lto/no_builtins.rs
+++ b/tests/run-make/no-builtins-lto/no_builtins.rs
@@ -1,2 +1,15 @@
+#![feature(lang_items, no_core)]
+#![no_std]
+#![no_core]
 #![crate_type = "lib"]
 #![no_builtins]
+
+extern crate foo;
+
+#[no_mangle]
+pub unsafe fn no_builtins(dest: *mut u8, src: *const u8) {
+    // There should be no "undefined reference to `foo::foo'".
+    foo::foo(dest, src);
+    // should call `@memcpy` instead of `@llvm.memcpy`.
+    foo::memcpy(dest, src, 1024);
+}
diff --git a/tests/run-make/pass-linker-flags-flavor/Makefile b/tests/run-make/pass-linker-flags-flavor/Makefile
index bd3d3ed882f..1bb05d0f974 100644
--- a/tests/run-make/pass-linker-flags-flavor/Makefile
+++ b/tests/run-make/pass-linker-flags-flavor/Makefile
@@ -3,6 +3,9 @@
 include ../tools.mk
 
 all:
-	$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
-	$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
-	$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
+	$(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) empty.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
+	$(RUSTC) attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) --cfg 'feature="verbatim"' attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
+	$(RUSTC) attribute.rs -C linker-flavor=ld --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
diff --git a/tests/run-make/pass-linker-flags-flavor/attribute.rs b/tests/run-make/pass-linker-flags-flavor/attribute.rs
new file mode 100644
index 00000000000..d099165301b
--- /dev/null
+++ b/tests/run-make/pass-linker-flags-flavor/attribute.rs
@@ -0,0 +1,12 @@
+#![feature(link_arg_attribute)]
+
+#[link(kind = "static", name = "l1")]
+#[cfg_attr(feature = "verbatim", link(kind = "link-arg", name = "a1", modifiers = "+verbatim"))]
+#[cfg_attr(not(feature = "verbatim"), link(kind = "link-arg", name = "a1"))]
+#[link(kind = "static", name = "l2")]
+#[link(kind = "link-arg", name = "a2")]
+#[link(kind = "dylib", name = "d1")]
+#[link(kind = "link-arg", name = "a3")]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/run-make/pass-linker-flags-flavor/rs.rs b/tests/run-make/pass-linker-flags-flavor/empty.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/pass-linker-flags-flavor/rs.rs
+++ b/tests/run-make/pass-linker-flags-flavor/empty.rs
diff --git a/tests/run-make/pass-linker-flags-from-dep/Makefile b/tests/run-make/pass-linker-flags-from-dep/Makefile
index b57389bb7d4..48b3b26ce81 100644
--- a/tests/run-make/pass-linker-flags-from-dep/Makefile
+++ b/tests/run-make/pass-linker-flags-from-dep/Makefile
@@ -4,7 +4,9 @@ all:
 	# Build deps
 	$(RUSTC) native_dep_1.rs --crate-type=staticlib
 	$(RUSTC) native_dep_2.rs --crate-type=staticlib
-	$(RUSTC) rust_dep.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options
+	$(RUSTC) rust_dep_flag.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options
+	$(RUSTC) rust_dep_attr.rs --crate-type=lib
 
 	# Check sequence of linker args
-	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2'
+	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_flag.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2'
+	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_attr.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2'
diff --git a/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs b/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs
new file mode 100644
index 00000000000..ac5888ce610
--- /dev/null
+++ b/tests/run-make/pass-linker-flags-from-dep/rust_dep_attr.rs
@@ -0,0 +1,14 @@
+#![feature(link_arg_attribute)]
+
+#[link(kind = "static", name = "native_dep_1", modifiers = "-bundle")]
+#[link(kind = "link-arg", name = "some_flag")]
+#[link(kind = "static", name = "native_dep_2", modifiers = "-bundle")]
+extern "C" {
+    pub fn foo();
+}
+
+pub fn f() {
+    unsafe {
+        foo();
+    }
+}
diff --git a/tests/run-make/pass-linker-flags-from-dep/rust_dep.rs b/tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs
index 7f5df113934..7f5df113934 100644
--- a/tests/run-make/pass-linker-flags-from-dep/rust_dep.rs
+++ b/tests/run-make/pass-linker-flags-from-dep/rust_dep_flag.rs
diff --git a/tests/run-make/pass-linker-flags/Makefile b/tests/run-make/pass-linker-flags/Makefile
index 6ddbcbb1b08..226943e93bd 100644
--- a/tests/run-make/pass-linker-flags/Makefile
+++ b/tests/run-make/pass-linker-flags/Makefile
@@ -1,4 +1,5 @@
 include ../tools.mk
 
 all:
-	$(RUSTC) rs.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
+	$(RUSTC) empty.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
+	$(RUSTC) attribute.rs --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3'
diff --git a/tests/run-make/pass-linker-flags/attribute.rs b/tests/run-make/pass-linker-flags/attribute.rs
new file mode 100644
index 00000000000..6f784c01ff2
--- /dev/null
+++ b/tests/run-make/pass-linker-flags/attribute.rs
@@ -0,0 +1,11 @@
+#![feature(link_arg_attribute)]
+
+#[link(kind = "static", name = "l1")]
+#[link(kind = "link-arg", name = "a1")]
+#[link(kind = "static", name = "l2")]
+#[link(kind = "link-arg", name = "a2")]
+#[link(kind = "dylib", name = "d1")]
+#[link(kind = "link-arg", name = "a3")]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/run-make/pass-linker-flags/rs.rs b/tests/run-make/pass-linker-flags/empty.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/pass-linker-flags/rs.rs
+++ b/tests/run-make/pass-linker-flags/empty.rs
diff --git a/tests/run-make/valid-print-requests/valid-print-requests.stderr b/tests/run-make/valid-print-requests/valid-print-requests.stderr
index 4f57550c29a..22bb102f9c9 100644
--- a/tests/run-make/valid-print-requests/valid-print-requests.stderr
+++ b/tests/run-make/valid-print-requests/valid-print-requests.stderr
@@ -1,2 +1,2 @@
-error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `all-target-specs-json`, `link-args`, `split-debuginfo`, `deployment-target`
+error: unknown print request `uwu`. Valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
 
diff --git a/tests/run-make/wasm-spurious-import/Makefile b/tests/run-make/wasm-builtins-import/Makefile
index ff9dfeac6d0..ff9dfeac6d0 100644
--- a/tests/run-make/wasm-spurious-import/Makefile
+++ b/tests/run-make/wasm-builtins-import/Makefile
diff --git a/tests/run-make/wasm-spurious-import/main.rs b/tests/run-make/wasm-builtins-import/main.rs
index fcbead5e28b..5eb99df6ff7 100644
--- a/tests/run-make/wasm-spurious-import/main.rs
+++ b/tests/run-make/wasm-builtins-import/main.rs
@@ -8,7 +8,8 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! {
 
 #[no_mangle]
 pub fn multer(a: i128, b: i128) -> i128 {
-    // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported
-    // panic function in case of a bug. We verify that no imports exist in our verifier.
+    // Trigger usage of the __multi3 compiler intrinsic which then leads to an imported function
+    // such as panic or __multi3 (externally defined) in case of a bug. We verify that
+    // no imports exist in our verifier.
     a * b
 }
diff --git a/tests/run-make/wasm-spurious-import/verify.js b/tests/run-make/wasm-builtins-import/verify.js
index d3b2101b662..d3b2101b662 100644
--- a/tests/run-make/wasm-spurious-import/verify.js
+++ b/tests/run-make/wasm-builtins-import/verify.js
diff --git a/tests/rustdoc-gui/font-weight.goml b/tests/rustdoc-gui/font-weight.goml
index 6fad128dab8..602b8d6f5b3 100644
--- a/tests/rustdoc-gui/font-weight.goml
+++ b/tests/rustdoc-gui/font-weight.goml
@@ -2,7 +2,7 @@
 go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html"
 assert-css: ("//*[@class='rust item-decl']//a[text()='Alias']", {"font-weight": "400"})
 assert-css: (
-    "//*[@class='structfield small-section-header']//a[text()='Alias']",
+    "//*[@class='structfield section-header']//a[text()='Alias']",
     {"font-weight": "400"},
 )
 assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"})
diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml
index a7ac94c4943..19185818f40 100644
--- a/tests/rustdoc-gui/headers-color.goml
+++ b/tests/rustdoc-gui/headers-color.goml
@@ -31,7 +31,7 @@ define-function: (
             ALL,
         )
         go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-        assert-css: (".small-section-header a", {"color": |color|}, ALL)
+        assert-css: (".section-header a", {"color": |color|}, ALL)
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
         // We select headings (h2, h3, h...).
         assert-css: (".docblock > :not(p) > a", {"color": |headings_color|}, ALL)
diff --git a/tests/rustdoc-gui/where-whitespace.goml b/tests/rustdoc-gui/where-whitespace.goml
index 69e6c3356a4..da104fa4011 100644
--- a/tests/rustdoc-gui/where-whitespace.goml
+++ b/tests/rustdoc-gui/where-whitespace.goml
@@ -3,15 +3,15 @@ go-to: "file://" + |DOC_PATH| + "/lib2/trait.Whitespace.html"
 show-text: true
 // First, we check in the trait definition if the where clause is "on its own" (not on the same
 // line than "pub trait Whitespace<Idx>").
-compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y"))
+compare-elements-position-false: (".item-decl code", "div.where", ("y"))
 // And that the code following it isn't on the same line either.
-compare-elements-position-false: (".item-decl .fn", ".where.fmt-newline", ("y"))
+compare-elements-position-false: (".item-decl .fn", "div.where", ("y"))
 
 go-to: "file://" + |DOC_PATH| + "/lib2/struct.WhereWhitespace.html"
 // We make the screen a bit wider to ensure that the trait impl is on one line.
 set-window-size: (915, 915)
 
-compare-elements-position-false: ("#method\.new .fn", "#method\.new .where.fmt-newline", ("y"))
+compare-elements-position-false: ("#method\.new .fn", "#method\.new div.where", ("y"))
 // We ensure that both the trait name and the struct name are on the same line in
 // "impl<K, T> Whitespace<&K> for WhereWhitespace<T>".
 compare-elements-position: (
@@ -22,6 +22,6 @@ compare-elements-position: (
 // And we now check that the where condition isn't on the same line.
 compare-elements-position-false: (
     "#trait-implementations-list .impl h3 .trait",
-    "#trait-implementations-list .impl h3 .where.fmt-newline",
+    "#trait-implementations-list .impl h3 div.where",
     ("y"),
 )
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index ab8d72bf71b..f9f9c4f4de8 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -18,6 +18,15 @@ const PARSED = [
         error: "Found generics without a path",
     },
     {
+        query: '-> *',
+        elems: [],
+        foundElems: 0,
+        original: "-> *",
+        returned: [],
+        userQuery: "-> *",
+        error: "Unexpected `*`",
+    },
+    {
         query: 'a<"P">',
         elems: [],
         foundElems: 0,
@@ -144,6 +153,24 @@ const PARSED = [
         error: "Unexpected `::::`",
     },
     {
+        query: "a:: ::b",
+        elems: [],
+        foundElems: 0,
+        original: "a:: ::b",
+        returned: [],
+        userQuery: "a:: ::b",
+        error: "Unexpected `:: ::`",
+    },
+    {
+        query: "a::\t::b",
+        elems: [],
+        foundElems: 0,
+        original: "a:: ::b",
+        returned: [],
+        userQuery: "a:: ::b",
+        error: "Unexpected `:: ::`",
+    },
+    {
         query: "a::b::",
         elems: [],
         foundElems: 0,
@@ -315,24 +342,6 @@ const PARSED = [
         error: 'Unexpected `-` after `<`',
     },
     {
-        query: "a:: a",
-        elems: [],
-        foundElems: 0,
-        original: 'a:: a',
-        returned: [],
-        userQuery: 'a:: a',
-        error: 'Unexpected `:: `',
-    },
-    {
-        query: "a ::a",
-        elems: [],
-        foundElems: 0,
-        original: 'a ::a',
-        returned: [],
-        userQuery: 'a ::a',
-        error: 'Unexpected ` ::`',
-    },
-    {
         query: "a<a>:",
         elems: [],
         foundElems: 0,
diff --git a/tests/rustdoc-js-std/parser-paths.js b/tests/rustdoc-js-std/parser-paths.js
index 8d4dedf3f46..774e5d028cc 100644
--- a/tests/rustdoc-js-std/parser-paths.js
+++ b/tests/rustdoc-js-std/parser-paths.js
@@ -16,6 +16,54 @@ const PARSED = [
         error: null,
     },
     {
+        query: "a:: a",
+        elems: [{
+            name: "a:: a",
+            fullPath: ["a", "a"],
+            pathWithoutLast: ["a"],
+            pathLast: "a",
+            generics: [],
+            typeFilter: -1,
+        }],
+        foundElems: 1,
+        original: 'a:: a',
+        returned: [],
+        userQuery: 'a:: a',
+        error: null,
+    },
+    {
+        query: "a ::a",
+        elems: [{
+            name: "a ::a",
+            fullPath: ["a", "a"],
+            pathWithoutLast: ["a"],
+            pathLast: "a",
+            generics: [],
+            typeFilter: -1,
+        }],
+        foundElems: 1,
+        original: 'a ::a',
+        returned: [],
+        userQuery: 'a ::a',
+        error: null,
+    },
+    {
+        query: "a  ::  a",
+        elems: [{
+            name: "a  ::  a",
+            fullPath: ["a", "a"],
+            pathWithoutLast: ["a"],
+            pathLast: "a",
+            generics: [],
+            typeFilter: -1,
+        }],
+        foundElems: 1,
+        original: 'a  ::  a',
+        returned: [],
+        userQuery: 'a  ::  a',
+        error: null,
+    },
+    {
         query: 'A::B,C',
         elems: [
             {
diff --git a/tests/rustdoc-js-std/parser-separators.js b/tests/rustdoc-js-std/parser-separators.js
index 00c489b51a6..7f95f61b006 100644
--- a/tests/rustdoc-js-std/parser-separators.js
+++ b/tests/rustdoc-js-std/parser-separators.js
@@ -5,7 +5,7 @@ const PARSED = [
         query: 'aaaaaa	b',
         elems: [
             {
-                name: 'aaaaaa\tb',
+                name: 'aaaaaa b',
                 fullPath: ['aaaaaa', 'b'],
                 pathWithoutLast: ['aaaaaa'],
                 pathLast: 'b',
@@ -14,9 +14,9 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "aaaaaa	b",
+        original: "aaaaaa b",
         returned: [],
-        userQuery: "aaaaaa	b",
+        userQuery: "aaaaaa b",
         error: null,
     },
     {
@@ -40,9 +40,9 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "aaaaaa,	b",
+        original: "aaaaaa, b",
         returned: [],
-        userQuery: "aaaaaa,	b",
+        userQuery: "aaaaaa, b",
         error: null,
     },
     {
@@ -93,7 +93,7 @@ const PARSED = [
         query: 'a\tb',
         elems: [
             {
-                name: 'a\tb',
+                name: 'a b',
                 fullPath: ['a', 'b'],
                 pathWithoutLast: ['a'],
                 pathLast: 'b',
@@ -102,9 +102,9 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a\tb",
+        original: "a b",
         returned: [],
-        userQuery: "a\tb",
+        userQuery: "a b",
         error: null,
     },
     {
@@ -176,7 +176,7 @@ const PARSED = [
                 pathLast: 'a',
                 generics: [
                     {
-                        name: 'b\tc',
+                        name: 'b c',
                         fullPath: ['b', 'c'],
                         pathWithoutLast: ['b'],
                         pathLast: 'c',
@@ -187,9 +187,9 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a<b\tc>",
+        original: "a<b c>",
         returned: [],
-        userQuery: "a<b\tc>",
+        userQuery: "a<b c>",
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-weird-queries.js b/tests/rustdoc-js-std/parser-weird-queries.js
index 720ef66c165..ba68c9717c5 100644
--- a/tests/rustdoc-js-std/parser-weird-queries.js
+++ b/tests/rustdoc-js-std/parser-weird-queries.js
@@ -92,9 +92,9 @@ const PARSED = [
         query: 'mod\t:',
         elems: [],
         foundElems: 0,
-        original: 'mod\t:',
+        original: 'mod :',
         returned: [],
-        userQuery: 'mod\t:',
+        userQuery: 'mod :',
         error: "Unexpected `:` (expected path after type filter `mod:`)",
     },
 ];
diff --git a/tests/rustdoc-ui/error-in-impl-trait/README.md b/tests/rustdoc-ui/error-in-impl-trait/README.md
index 1176a4a8c4c..d969ab10ef5 100644
--- a/tests/rustdoc-ui/error-in-impl-trait/README.md
+++ b/tests/rustdoc-ui/error-in-impl-trait/README.md
@@ -1,5 +1,5 @@
 Each of these needs to be in a separate file,
-because the `delay_span_bug` ICE in rustdoc won't be triggerred
+because the `span_delayed_bug` ICE in rustdoc won't be triggerred
 if even a single other error was emitted.
 
 However, conceptually they are all testing basically the same thing.
diff --git a/tests/rustdoc-ui/unescaped_backticks.rs b/tests/rustdoc-ui/unescaped_backticks.rs
index e960e9f59e9..e813fba4717 100644
--- a/tests/rustdoc-ui/unescaped_backticks.rs
+++ b/tests/rustdoc-ui/unescaped_backticks.rs
@@ -190,7 +190,7 @@ pub fn complicated_markdown() {}
 pub mod mir {}
 
 pub mod rustc {
-    /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
+    /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to
     //~^ ERROR unescaped backtick
     /// ensure it gets used.
     pub fn ty_error_with_message() {}
diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr
index 2b4e491b1fe..bd21dcb6e1a 100644
--- a/tests/rustdoc-ui/unescaped_backticks.stderr
+++ b/tests/rustdoc-ui/unescaped_backticks.stderr
@@ -64,19 +64,19 @@ LL |         /// `cfg=... and not `#[cfg_attr]\`
    |                                          +
 
 error: unescaped backtick
-  --> $DIR/unescaped_backticks.rs:193:91
+  --> $DIR/unescaped_backticks.rs:193:93
    |
-LL |     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to
-   |                                                                                           ^
+LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to
+   |                                                                                             ^
    |
 help: the closing backtick of an inline code may be missing
    |
-LL |     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to
-   |                                                                                               +
+LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to
+   |                                                                                                 +
 help: if you meant to use a literal backtick, escape it
    |
-LL |     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given \`msg to
-   |                                                                                           +
+LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given \`msg to
+   |                                                                                             +
 
 error: unescaped backtick
   --> $DIR/unescaped_backticks.rs:202:34
diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async-fn-opaque-item.rs
index a73e84f3fdc..2c030824fe7 100644
--- a/tests/rustdoc/async-fn-opaque-item.rs
+++ b/tests/rustdoc/async-fn-opaque-item.rs
@@ -9,7 +9,7 @@
 
 // Checking there is only a "Functions" header and no "Opaque types".
 // @has async_fn_opaque_item/index.html
-// @count - '//*[@class="small-section-header"]' 1
-// @has - '//*[@class="small-section-header"]' 'Functions'
+// @count - '//*[@class="section-header"]' 1
+// @has - '//*[@class="section-header"]' 'Functions'
 
 pub async fn test() {}
diff --git a/tests/rustdoc/compiler-derive-proc-macro.rs b/tests/rustdoc/compiler-derive-proc-macro.rs
index 489ec924c1f..1c3867ced9b 100644
--- a/tests/rustdoc/compiler-derive-proc-macro.rs
+++ b/tests/rustdoc/compiler-derive-proc-macro.rs
@@ -5,9 +5,9 @@
 // @has 'foo/index.html'
 // Each compiler builtin proc-macro has a trait equivalent so we should have
 // a trait section as well.
-// @count - '//*[@id="main-content"]//*[@class="small-section-header"]' 2
-// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Traits'
-// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Derive Macros'
+// @count - '//*[@id="main-content"]//*[@class="section-header"]' 2
+// @has - '//*[@id="main-content"]//*[@class="section-header"]' 'Traits'
+// @has - '//*[@id="main-content"]//*[@class="section-header"]' 'Derive Macros'
 
 // Now checking the correct file is generated as well.
 // @has 'foo/derive.Clone.html'
diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs
index e382940a47e..ae830c03ea3 100644
--- a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs
+++ b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs
@@ -6,8 +6,8 @@
 
 // @has 'foo/index.html'
 // There should only be one struct displayed.
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs'
 // @has - '//*[@id="main-content"]//a[@href="struct.Reexport.html"]' 'Reexport'
 // @has - '//*[@id="main-content"]//*[@class="desc docblock-short"]' 'Visible. Original.'
 
diff --git a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs
index 5d2c553d8a5..2905e7d44bc 100644
--- a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs
+++ b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs
@@ -7,9 +7,9 @@
 // @has - '//*[@class="item-name"]/a[@class="type"]' 'AtomicU8'
 // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8'
 // We also ensure we don't have another item displayed.
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 2
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants'
 
 mod other {
     pub type AtomicU8 = ();
diff --git a/tests/rustdoc/issue-105735-overlapping-reexport.rs b/tests/rustdoc/issue-105735-overlapping-reexport.rs
index 50f2450b90a..7fa7df7701a 100644
--- a/tests/rustdoc/issue-105735-overlapping-reexport.rs
+++ b/tests/rustdoc/issue-105735-overlapping-reexport.rs
@@ -7,9 +7,9 @@
 // @has - '//*[@class="item-name"]/a[@class="struct"]' 'AtomicU8'
 // @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8'
 // We also ensure we don't have another item displayed.
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 2
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants'
 
 mod thing {
     pub use core::sync::atomic::AtomicU8;
diff --git a/tests/rustdoc/issue-109258-missing-private-inlining.rs b/tests/rustdoc/issue-109258-missing-private-inlining.rs
index 96f606368b2..12c5556f132 100644
--- a/tests/rustdoc/issue-109258-missing-private-inlining.rs
+++ b/tests/rustdoc/issue-109258-missing-private-inlining.rs
@@ -4,9 +4,9 @@
 
 // @has 'foo/index.html'
 // We should only have a "Re-exports" and a "Modules" headers.
-// @count - '//*[@id="main-content"]/h2[@class="small-section-header"]' 2
-// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Re-exports'
-// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Modules'
+// @count - '//*[@id="main-content"]/h2[@class="section-header"]' 2
+// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Re-exports'
+// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Modules'
 
 // @has - '//*[@id="reexport.Foo"]' 'pub use crate::issue_109258::Foo;'
 // @has - '//*[@id="reexport.Foo"]//a[@href="issue_109258/struct.Foo.html"]' 'Foo'
@@ -15,8 +15,8 @@ pub use crate::issue_109258::Foo;
 
 // @has 'foo/issue_109258/index.html'
 // We should only have a "Structs" header.
-// @count - '//*[@id="main-content"]/h2[@class="small-section-header"]' 1
-// @has - '//*[@id="main-content"]/h2[@class="small-section-header"]' 'Structs'
+// @count - '//*[@id="main-content"]/h2[@class="section-header"]' 1
+// @has - '//*[@id="main-content"]/h2[@class="section-header"]' 'Structs'
 // @has - '//*[@id="main-content"]//a[@href="struct.Foo.html"]' 'Foo'
 // @has 'foo/issue_109258/struct.Foo.html'
 pub mod issue_109258 {
diff --git a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
index 3b836a21931..9fb2f7c7c05 100644
--- a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
+++ b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
@@ -66,8 +66,8 @@ pub mod single_reexport_inherit_hidden {
 pub mod single_reexport_no_inline {
     // First we ensure that we only have re-exports and no inlined items.
     // @has 'foo/single_reexport_no_inline/index.html'
-    // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
+    // @count - '//*[@id="main-content"]/*[@class="section-header"]' 1
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports'
 
     // Now we check that we don't have links to the items, just `pub use`.
     // @has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;'
@@ -101,10 +101,10 @@ pub mod glob_reexport {
     // With glob re-exports, we don't inline `#[doc(hidden)]` items so only `module` items
     // should be inlined.
     // @has 'foo/glob_reexport/index.html'
-    // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Aliases'
+    // @count - '//*[@id="main-content"]/*[@class="section-header"]' 3
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports'
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs'
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Type Aliases'
 
     // Now we check we have 1 re-export and 2 inlined items.
     // If not item from a glob re-export is visible, we don't show the re-export.
diff --git a/tests/rustdoc/issue-110422-inner-private.rs b/tests/rustdoc/issue-110422-inner-private.rs
index ee8ed5cc6e1..43dc929ab07 100644
--- a/tests/rustdoc/issue-110422-inner-private.rs
+++ b/tests/rustdoc/issue-110422-inner-private.rs
@@ -8,11 +8,11 @@
 
 // @has 'foo/index.html'
 // Checking there is no "trait" entry.
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 4
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Macros'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 4
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Constants'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Functions'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Macros'
 
 // @has - '//a[@href="fn.foo.html"]' 'foo'
 fn foo() {
@@ -50,11 +50,11 @@ const BAR: i32 = {
 
     // @has 'foo/struct.Bar.html'
     // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub(crate) fn foo()'
-    // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
+    // @count - '//*[@id="main-content"]/*[@class="section-header"]' 3
     // We now check that the `Foo` trait is not documented nor visible on `Bar` page.
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Implementations'
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Auto Trait Implementations'
-    // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Blanket Implementations'
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Implementations'
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Auto Trait Implementations'
+    // @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Blanket Implementations'
     // @!has - '//*[@href="trait.Foo.html#method.babar"]/*[@class="code-header"]' 'fn babar()'
     impl Bar {
         fn foo() {}
diff --git a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs
index 1429b5e4741..50def2c3cd9 100644
--- a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs
+++ b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs
@@ -5,8 +5,8 @@
 #![crate_name = "foo"]
 
 // @has 'foo/index.html'
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Modules'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Modules'
 // @count - '//*[@id="main-content"]/*[@class="item-table"]//*[@class="mod"]' 2
 // @has - '//*[@id="main-content"]//*[@class="mod"]' 'banana'
 // @has - '//*[@id="main-content"]//*[@href="banana/index.html"]' 'banana'
diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc/nested-items-issue-111415.rs
index 9b7688c332c..c117569d9b4 100644
--- a/tests/rustdoc/nested-items-issue-111415.rs
+++ b/tests/rustdoc/nested-items-issue-111415.rs
@@ -5,10 +5,10 @@
 
 // @has 'foo/index.html'
 // Checking there are only three sections.
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions'
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 3
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Structs'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Functions'
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Traits'
 // Checking that there are only three items.
 // @count - '//*[@id="main-content"]//*[@class="item-name"]' 3
 // @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar'
diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html b/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html
index 46be00a0804..7d2a2589133 100644
--- a/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html
+++ b/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html
@@ -1 +1 @@
-<script type="text/json" id="notable-traits-data">{"&amp;'static [SomeStruct]":"&lt;h3&gt;Notable traits for &lt;code&gt;&amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/span&gt;"}</script>
\ No newline at end of file
+<script type="text/json" id="notable-traits-data">{"&amp;'static [SomeStruct]":"&lt;h3&gt;Notable traits for &lt;code&gt;&amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=\"where\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/div&gt;"}</script>
\ No newline at end of file
diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html b/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html
index f592e3b375c..9f71677cf4f 100644
--- a/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html
+++ b/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html
@@ -1 +1 @@
-<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;"}</script>
\ No newline at end of file
+<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=\"where\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/div&gt;"}</script>
\ No newline at end of file
diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html b/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html
index e8f4f600045..38689c79f1a 100644
--- a/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html
+++ b/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html
@@ -1 +1 @@
-<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;","Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T: &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script>
\ No newline at end of file
+<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=\"where\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/div&gt;","Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=\"where\"&gt;impl&amp;lt;T: &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/div&gt;"}</script>
\ No newline at end of file
diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html b/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html
index e7909669b15..c137be9e3a5 100644
--- a/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html
+++ b/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html
@@ -1 +1 @@
-<script type="text/json" id="notable-traits-data">{"Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T: &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script>
\ No newline at end of file
+<script type="text/json" id="notable-traits-data">{"Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=\"where\"&gt;impl&amp;lt;T: &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/div&gt;"}</script>
\ No newline at end of file
diff --git a/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html b/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html
index 5f54b7522ae..cce8739df16 100644
--- a/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html
+++ b/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html
@@ -1 +1 @@
-<script type="text/json" id="notable-traits-data">{"Odd":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\"&gt;Iterator&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/span&gt;&lt;span class=\"where fmt-newline\"&gt;    type &lt;a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\"&gt;Item&lt;/a&gt; = &lt;a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\"&gt;usize&lt;/a&gt;;&lt;/span&gt;"}</script>
\ No newline at end of file
+<script type="text/json" id="notable-traits-data">{"Odd":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;&lt;div class=\"where\"&gt;impl &lt;a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\"&gt;Iterator&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/div&gt;&lt;div class=\"where\"&gt;    type &lt;a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\"&gt;Item&lt;/a&gt; = &lt;a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\"&gt;usize&lt;/a&gt;;&lt;/div&gt;"}</script>
\ No newline at end of file
diff --git a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs
index d8953eaf597..ae0aead244b 100644
--- a/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs
+++ b/tests/rustdoc/pub-reexport-of-pub-reexport-46506.rs
@@ -4,8 +4,8 @@
 #![crate_name = "foo"]
 
 // @has 'foo/associations/index.html'
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Traits'
 // @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy'
 // @has 'foo/associations/trait.GroupedBy.html'
 pub mod associations {
@@ -16,8 +16,8 @@ pub mod associations {
 }
 
 // @has 'foo/prelude/index.html'
-// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
-// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
+// @count - '//*[@id="main-content"]/*[@class="section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports'
 // @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;'
 pub mod prelude {
     pub use associations::GroupedBy;
diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs
index 7f56b2ffeb8..6f264969e54 100644
--- a/tests/rustdoc/rfc-2632-const-trait-impl.rs
+++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs
@@ -23,7 +23,7 @@ pub trait Tr<T> {
     // @!has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const'
     // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn'
     // @!has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
-    // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn'
+    // @has - '//section[@id="method.a"]/h4[@class="code-header"]/div[@class="where"]' ': Fn'
     fn a<A: /* ~const */ Fn() + ~const Destruct>()
     where
         Option<A>: /* ~const */ Fn() + ~const Destruct,
@@ -35,7 +35,7 @@ pub trait Tr<T> {
 // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]' '~const'
 // @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Fn'
 // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where"]' '~const'
-// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn'
+// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/div[@class="where"]' ': Fn'
 impl<T: /* ~const */ Fn() + ~const Destruct> const Tr<T> for T
 where
     Option<T>: /* ~const */ Fn() + ~const Destruct,
@@ -49,8 +49,8 @@ where
 
 // @!has foo/fn.foo.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const'
 // @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn'
-// @!has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' '~const'
-// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Fn'
+// @!has - '//pre[@class="rust item-decl"]/code/div[@class="where"]' '~const'
+// @has - '//pre[@class="rust item-decl"]/code/div[@class="where"]' ': Fn'
 pub const fn foo<F: /* ~const */ Fn() + ~const Destruct>()
 where
     Option<F>: /* ~const */ Fn() + ~const Destruct,
@@ -62,7 +62,7 @@ impl<T> S<T> {
     // @!has foo/struct.S.html '//section[@id="method.foo"]/h4[@class="code-header"]' '~const'
     // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn'
     // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
-    // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn'
+    // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/div[@class="where"]' ': Fn'
     pub const fn foo<B, C: /* ~const */ Fn() + ~const Destruct>()
     where
         B: /* ~const */ Fn() + ~const Destruct,
diff --git a/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs b/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs
index ff84352d716..bea25c75aa4 100644
--- a/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs
+++ b/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs
@@ -13,14 +13,14 @@ pub struct Pair<A, B> {
 // @count - '//*[@id="aliased-type"]' 1
 // @count - '//*[@id="variants"]' 0
 // @count - '//*[@id="fields"]' 1
-// @count - '//span[@class="where fmt-newline"]' 0
+// @count - '//div[@class="where"]' 0
 pub type ReversedTypesPair<Q, R> = Pair<R, Q>;
 
 // @has 'inner_types_lazy/type.ReadWrite.html'
 // @count - '//*[@id="aliased-type"]' 1
 // @count - '//*[@id="variants"]' 0
 // @count - '//*[@id="fields"]' 1
-// @count - '//span[@class="where fmt-newline"]' 2
+// @count - '//div[@class="where"]' 2
 pub type ReadWrite<R, W> = Pair<R, W>
 where
     R: std::io::Read,
@@ -30,5 +30,5 @@ where
 // @count - '//*[@id="aliased-type"]' 1
 // @count - '//*[@id="variants"]' 0
 // @count - '//*[@id="fields"]' 1
-// @count - '//span[@class="where fmt-newline"]' 0
+// @count - '//div[@class="where"]' 0
 pub type VecPair<U, V> = Pair<Vec<U>, Vec<V>>;
diff --git a/tests/rustdoc/typedef-inner-variants.rs b/tests/rustdoc/typedef-inner-variants.rs
index b734714fd64..4d0ff85551c 100644
--- a/tests/rustdoc/typedef-inner-variants.rs
+++ b/tests/rustdoc/typedef-inner-variants.rs
@@ -65,7 +65,7 @@ pub union OneOr<A: Copy> {
 // @count - '//*[@id="aliased-type"]' 1
 // @count - '//*[@id="variants"]' 0
 // @count - '//*[@id="fields"]' 1
-// @count - '//*[@class="structfield small-section-header"]' 2
+// @count - '//*[@class="structfield section-header"]' 2
 // @matches - '//pre[@class="rust item-decl"]//code' "union OneOrF64"
 pub type OneOrF64 = OneOr<f64>;
 
@@ -81,7 +81,7 @@ pub struct One<T> {
 // @count - '//*[@id="aliased-type"]' 1
 // @count - '//*[@id="variants"]' 0
 // @count - '//*[@id="fields"]' 1
-// @count - '//*[@class="structfield small-section-header"]' 1
+// @count - '//*[@class="structfield section-header"]' 1
 // @matches - '//pre[@class="rust item-decl"]//code' "struct OneU64"
 // @matches - '//pre[@class="rust item-decl"]//code' "pub val"
 pub type OneU64 = One<u64>;
diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc/where.SWhere_Echo_impl.html
index 7517eb090f4..726196281a5 100644
--- a/tests/rustdoc/where.SWhere_Echo_impl.html
+++ b/tests/rustdoc/where.SWhere_Echo_impl.html
@@ -1,2 +1,2 @@
-<h3 class="code-header">impl&lt;D&gt; <a class="struct" href="struct.Delta.html" title="struct foo::Delta">Delta</a>&lt;D&gt;<span class="where fmt-newline">where
-    D: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></h3>
\ No newline at end of file
+<h3 class="code-header">impl&lt;D&gt; <a class="struct" href="struct.Delta.html" title="struct foo::Delta">Delta</a>&lt;D&gt;<div class="where">where
+    D: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</div></h3>
\ No newline at end of file
diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc/where.bravo_trait_decl.html
index 00524201a8a..3f1c994b0b2 100644
--- a/tests/rustdoc/where.bravo_trait_decl.html
+++ b/tests/rustdoc/where.bravo_trait_decl.html
@@ -1,5 +1,5 @@
-<code>pub trait Bravo&lt;B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span>{
+<code>pub trait Bravo&lt;B&gt;<div class="where">where
+    B: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</div>{
     // Required method
     fn <a href="#tymethod.get" class="fn">get</a>(&amp;self, B: B);
 }</code>
\ No newline at end of file
diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc/where.charlie_fn_decl.html
index 8e3bc8b01ec..4dd410435c1 100644
--- a/tests/rustdoc/where.charlie_fn_decl.html
+++ b/tests/rustdoc/where.charlie_fn_decl.html
@@ -1,2 +1,2 @@
-<code>pub fn charlie&lt;C&gt;()<span class="where fmt-newline">where
-    C: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></code>
\ No newline at end of file
+<code>pub fn charlie&lt;C&gt;()<div class="where">where
+    C: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</div></code>
\ No newline at end of file
diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc/where.golf_type_alias_decl.html
index 8da5402f900..ab60bb262da 100644
--- a/tests/rustdoc/where.golf_type_alias_decl.html
+++ b/tests/rustdoc/where.golf_type_alias_decl.html
@@ -1,2 +1,2 @@
-<code>pub type Golf&lt;T&gt;<span class="where fmt-newline">where
-    T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span> = <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>;</code>
\ No newline at end of file
+<code>pub type Golf&lt;T&gt;<div class="where">where
+    T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</div> = <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>;</code>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.enum.html b/tests/rustdoc/whitespace-after-where-clause.enum.html
index ff4971f33cd..25e02145323 100644
--- a/tests/rustdoc/whitespace-after-where-clause.enum.html
+++ b/tests/rustdoc/whitespace-after-where-clause.enum.html
@@ -1,5 +1,5 @@
-<pre class="rust item-decl"><code>pub enum Cow&lt;'a, B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
+<pre class="rust item-decl"><code>pub enum Cow&lt;'a, B&gt;<div class="where">where
+    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</div>{
     Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>),
     Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc/whitespace-after-where-clause.struct.html
index ca685358633..bc62a3a0015 100644
--- a/tests/rustdoc/whitespace-after-where-clause.struct.html
+++ b/tests/rustdoc/whitespace-after-where-clause.struct.html
@@ -1,5 +1,5 @@
-<pre class="rust item-decl"><code>pub struct Struct&lt;'a, B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
+<pre class="rust item-decl"><code>pub struct Struct&lt;'a, B&gt;<div class="where">where
+    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</div>{
     pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>,
     pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.trait.html b/tests/rustdoc/whitespace-after-where-clause.trait.html
index 0928b48e6b6..0e25ed86a7c 100644
--- a/tests/rustdoc/whitespace-after-where-clause.trait.html
+++ b/tests/rustdoc/whitespace-after-where-clause.trait.html
@@ -1,5 +1,5 @@
-<pre class="rust item-decl"><code>pub trait ToOwned&lt;T&gt;<span class="where fmt-newline">where
-    T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span>{
+<pre class="rust item-decl"><code>pub trait ToOwned&lt;T&gt;<div class="where">where
+    T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</div>{
     type <a href="#associatedtype.Owned" class="associatedtype">Owned</a>;
 
     // Required methods
diff --git a/tests/rustdoc/whitespace-after-where-clause.union.html b/tests/rustdoc/whitespace-after-where-clause.union.html
index 40b0c671284..7e0d5f8717a 100644
--- a/tests/rustdoc/whitespace-after-where-clause.union.html
+++ b/tests/rustdoc/whitespace-after-where-clause.union.html
@@ -1,4 +1,4 @@
-<pre class="rust item-decl"><code>pub union Union&lt;'a, B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
+<pre class="rust item-decl"><code>pub union Union&lt;'a, B&gt;<div class="where">where
+    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</div>{
     /* private fields */
 }</code></pre>
\ No newline at end of file
diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr
index 3234945e0df..7f9324035e4 100644
--- a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr
+++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr
@@ -5,7 +5,7 @@ LL |     let _array: [u32; <A as Foo>::Y];
    |                        ^ cannot perform const operation using `A`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr
index 0c8dc9d7fd6..8898880586c 100644
--- a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr
+++ b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr
@@ -5,7 +5,7 @@ LL |     links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
    |                  ^^^^^^^^ cannot perform const operation using `A`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
index f1f22e2342d..ce7fce25993 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -5,7 +5,7 @@ LL |     let _: [u8; foo::<T>()];
    |                       ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:16:23
@@ -14,7 +14,7 @@ LL |     let _: [u8; bar::<N>()];
    |                       ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:18:23
@@ -23,7 +23,7 @@ LL |     let _: [u8; faz::<'a>(&())];
    |                       ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:20:23
@@ -32,7 +32,7 @@ LL |     let _: [u8; baz::<'a>(&())];
    |                       ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:21:23
@@ -41,7 +41,7 @@ LL |     let _: [u8; faz::<'b>(&())];
    |                       ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:23:23
@@ -50,7 +50,7 @@ LL |     let _: [u8; baz::<'b>(&())];
    |                       ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:26:23
@@ -59,7 +59,7 @@ LL |     let _ = [0; bar::<N>()];
    |                       ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:28:23
@@ -68,7 +68,7 @@ LL |     let _ = [0; faz::<'a>(&())];
    |                       ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:30:23
@@ -77,7 +77,7 @@ LL |     let _ = [0; baz::<'a>(&())];
    |                       ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:31:23
@@ -86,7 +86,7 @@ LL |     let _ = [0; faz::<'b>(&())];
    |                       ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:33:23
@@ -95,7 +95,7 @@ LL |     let _ = [0; baz::<'b>(&())];
    |                       ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:34:24
@@ -104,7 +104,7 @@ LL |     let _: Foo<{ foo::<T>() }>;
    |                        ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:35:24
@@ -113,7 +113,7 @@ LL |     let _: Foo<{ bar::<N>() }>;
    |                        ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:37:24
@@ -122,7 +122,7 @@ LL |     let _: Foo<{ faz::<'a>(&()) }>;
    |                        ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:39:24
@@ -131,7 +131,7 @@ LL |     let _: Foo<{ baz::<'a>(&()) }>;
    |                        ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:40:24
@@ -140,7 +140,7 @@ LL |     let _: Foo<{ faz::<'b>(&()) }>;
    |                        ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:42:24
@@ -149,7 +149,7 @@ LL |     let _: Foo<{ baz::<'b>(&()) }>;
    |                        ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:43:27
@@ -158,7 +158,7 @@ LL |     let _ = Foo::<{ foo::<T>() }>;
    |                           ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:44:27
@@ -167,7 +167,7 @@ LL |     let _ = Foo::<{ bar::<N>() }>;
    |                           ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:46:27
@@ -176,7 +176,7 @@ LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    |                           ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:48:27
@@ -185,7 +185,7 @@ LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    |                           ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:49:27
@@ -194,7 +194,7 @@ LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    |                           ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/const-arg-in-const-arg.rs:51:27
@@ -203,7 +203,7 @@ LL |     let _ = Foo::<{ baz::<'b>(&()) }>;
    |                           ^^ cannot perform const operation using `'b`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0747]: unresolved item provided when a constant was expected
   --> $DIR/const-arg-in-const-arg.rs:16:23
diff --git a/tests/ui/const-generics/const-argument-if-length.min.stderr b/tests/ui/const-generics/const-argument-if-length.min.stderr
index 3ba9ffebd4d..b9d9bcc9270 100644
--- a/tests/ui/const-generics/const-argument-if-length.min.stderr
+++ b/tests/ui/const-generics/const-argument-if-length.min.stderr
@@ -5,7 +5,7 @@ LL |     pad: [u8; is_zst::<T>()],
    |                        ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/const-argument-if-length.rs:15:12
diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr
index 52b7f2a37de..a1254672c9d 100644
--- a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr
+++ b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr
@@ -5,7 +5,7 @@ LL |         let _: &'a ();
    |                 ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr b/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr
index b836cfeaedb..199546c0883 100644
--- a/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr
+++ b/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr
@@ -5,7 +5,7 @@ LL | struct Foo<const N: usize, const M: usize = { N + 1 }>;
    |                                               ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-generic-default-expr.rs:9:62
@@ -14,7 +14,7 @@ LL | struct Bar<T, const TYPE_SIZE: usize = { std::mem::size_of::<T>() }>(T);
    |                                                              ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/early/macro_rules-braces.stderr b/tests/ui/const-generics/early/macro_rules-braces.stderr
index 49382dbf0bd..32695066801 100644
--- a/tests/ui/const-generics/early/macro_rules-braces.stderr
+++ b/tests/ui/const-generics/early/macro_rules-braces.stderr
@@ -27,7 +27,7 @@ LL |     let _: foo!({{ N }});
    |                    ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/macro_rules-braces.rs:36:19
@@ -36,7 +36,7 @@ LL |     let _: bar!({ N });
    |                   ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/macro_rules-braces.rs:41:20
@@ -45,7 +45,7 @@ LL |     let _: baz!({{ N }});
    |                    ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/macro_rules-braces.rs:46:19
@@ -54,7 +54,7 @@ LL |     let _: biz!({ N });
    |                   ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
index 64d1e0bcff4..1f4b892e20f 100644
--- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
@@ -5,7 +5,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    |                                                ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/array-size-in-generic-struct-param.rs:23:15
@@ -14,7 +14,7 @@ LL |     arr: [u8; CFG.arr_size],
    |               ^^^ cannot perform const operation using `CFG`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `CFG`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: `Config` is forbidden as the type of a const generic parameter
   --> $DIR/array-size-in-generic-struct-param.rs:21:21
diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
index d674e3acdff..f454ff4e6c0 100644
--- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
@@ -5,7 +5,7 @@ LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    |                                ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/dependence_lint.rs:21:37
@@ -14,7 +14,7 @@ LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable,
    |                                     ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 warning: cannot use constants which depend on generic parameters in types
   --> $DIR/dependence_lint.rs:10:9
diff --git a/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr
index 3b456324819..9c4e3d8583c 100644
--- a/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr
@@ -5,7 +5,7 @@ LL | type Arr<const N: usize> = [u8; N - 1];
    |                                 ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
index ea6f5f69276..2454b311921 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr
@@ -5,7 +5,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    |                 ^^^ cannot perform const operation using `LHS`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `LHS`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/issue-72787.rs:11:24
@@ -14,7 +14,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    |                        ^^^ cannot perform const operation using `RHS`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `RHS`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/issue-72787.rs:23:25
@@ -23,7 +23,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                         ^ cannot perform const operation using `I`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `I`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/issue-72787.rs:23:36
@@ -32,7 +32,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                    ^ cannot perform const operation using `J`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `J`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr
index ef9ee6d7cfc..c504464127a 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr
@@ -5,7 +5,7 @@ LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                 ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
index f0e0a4b9711..78717028f65 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr
@@ -5,7 +5,7 @@ LL |         let _: &'a ();
    |                 ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0308]: mismatched types
   --> $DIR/issue-74713.rs:3:10
diff --git a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
index 4c45339b93b..95f75c32186 100644
--- a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
+++ b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
@@ -5,7 +5,7 @@ LL |     T: Trait<{std::intrinsics::type_name::<T>()}>
    |                                            ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: `&'static str` is forbidden as the type of a const generic parameter
   --> $DIR/intrinsics-type_name-as-const-argument.rs:10:22
diff --git a/tests/ui/const-generics/issue-46511.stderr b/tests/ui/const-generics/issue-46511.stderr
index 58c93a1fab4..d57295fa2fa 100644
--- a/tests/ui/const-generics/issue-46511.stderr
+++ b/tests/ui/const-generics/issue-46511.stderr
@@ -5,7 +5,7 @@ LL |     _a: [u8; std::mem::size_of::<&'a mut u8>()]
    |                                   ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0392]: parameter `'a` is never used
   --> $DIR/issue-46511.rs:3:12
diff --git a/tests/ui/const-generics/issues/issue-67375.min.stderr b/tests/ui/const-generics/issues/issue-67375.min.stderr
index 5256d96c876..7671e3c4688 100644
--- a/tests/ui/const-generics/issues/issue-67375.min.stderr
+++ b/tests/ui/const-generics/issues/issue-67375.min.stderr
@@ -5,7 +5,7 @@ LL |     inner: [(); { [|_: &T| {}; 0].len() }],
    |                         ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0392]: parameter `T` is never used
   --> $DIR/issue-67375.rs:5:12
diff --git a/tests/ui/const-generics/issues/issue-67945-1.min.stderr b/tests/ui/const-generics/issues/issue-67945-1.min.stderr
index eee04eb75a2..1d071da903f 100644
--- a/tests/ui/const-generics/issues/issue-67945-1.min.stderr
+++ b/tests/ui/const-generics/issues/issue-67945-1.min.stderr
@@ -5,7 +5,7 @@ LL |         let x: S = MaybeUninit::uninit();
    |                ^ cannot perform const operation using `S`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/issue-67945-1.rs:13:45
@@ -14,7 +14,7 @@ LL |         let b = &*(&x as *const _ as *const S);
    |                                             ^ cannot perform const operation using `S`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0392]: parameter `S` is never used
   --> $DIR/issue-67945-1.rs:7:12
diff --git a/tests/ui/const-generics/issues/issue-67945-3.min.stderr b/tests/ui/const-generics/issues/issue-67945-3.min.stderr
index 8e6b4b20409..e34869c7938 100644
--- a/tests/ui/const-generics/issues/issue-67945-3.min.stderr
+++ b/tests/ui/const-generics/issues/issue-67945-3.min.stderr
@@ -5,7 +5,7 @@ LL |         let x: Option<S> = None;
    |                       ^ cannot perform const operation using `S`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0392]: parameter `S` is never used
   --> $DIR/issue-67945-3.rs:9:12
diff --git a/tests/ui/const-generics/issues/issue-67945-4.min.stderr b/tests/ui/const-generics/issues/issue-67945-4.min.stderr
index f9520872ddd..280c6f4f2cd 100644
--- a/tests/ui/const-generics/issues/issue-67945-4.min.stderr
+++ b/tests/ui/const-generics/issues/issue-67945-4.min.stderr
@@ -5,7 +5,7 @@ LL |         let x: Option<Box<S>> = None;
    |                           ^ cannot perform const operation using `S`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0392]: parameter `S` is never used
   --> $DIR/issue-67945-4.rs:8:12
diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr
index 3740ced90b1..ecf24a356de 100644
--- a/tests/ui/const-generics/issues/issue-68366.min.stderr
+++ b/tests/ui/const-generics/issues/issue-68366.min.stderr
@@ -5,7 +5,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |                                     ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
   --> $DIR/issue-68366.rs:11:7
diff --git a/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr b/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr
index 3b53e18e6f5..da2fbc52a6c 100644
--- a/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr
+++ b/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr
@@ -5,7 +5,7 @@ LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
    |                                              ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/issue-76701-ty-param-in-const.rs:6:42
@@ -14,7 +14,7 @@ LL | fn const_param<const N: usize>() -> [u8; N + 1] {
    |                                          ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-80062.stderr b/tests/ui/const-generics/issues/issue-80062.stderr
index 5f53dca4bed..5da8e45fac8 100644
--- a/tests/ui/const-generics/issues/issue-80062.stderr
+++ b/tests/ui/const-generics/issues/issue-80062.stderr
@@ -5,7 +5,7 @@ LL |     let _: [u8; sof::<T>()];
    |                       ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-80375.stderr b/tests/ui/const-generics/issues/issue-80375.stderr
index 6abbf1c0f75..015196f8605 100644
--- a/tests/ui/const-generics/issues/issue-80375.stderr
+++ b/tests/ui/const-generics/issues/issue-80375.stderr
@@ -5,7 +5,7 @@ LL | struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
    |                                         ^^^^^ cannot perform const operation using `COUNT`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `COUNT`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/legacy-const-generics-bad.stderr b/tests/ui/const-generics/legacy-const-generics-bad.stderr
index 3c78dd6c780..83c71e07253 100644
--- a/tests/ui/const-generics/legacy-const-generics-bad.stderr
+++ b/tests/ui/const-generics/legacy-const-generics-bad.stderr
@@ -13,7 +13,7 @@ LL |     legacy_const_generics::foo(0, N + 1, 2);
    |                                   ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/min_const_generics/complex-expression.stderr b/tests/ui/const-generics/min_const_generics/complex-expression.stderr
index deabd05a6d5..3affdcf9b03 100644
--- a/tests/ui/const-generics/min_const_generics/complex-expression.stderr
+++ b/tests/ui/const-generics/min_const_generics/complex-expression.stderr
@@ -5,7 +5,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]);
    |                                      ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-expression.rs:13:40
@@ -14,7 +14,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]);
    |                                        ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-expression.rs:17:17
@@ -23,7 +23,7 @@ LL |     let _: [u8; N + 1];
    |                 ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-expression.rs:22:17
@@ -32,7 +32,7 @@ LL |     let _ = [0; N + 1];
    |                 ^ cannot perform const operation using `N`
    |
    = help: const parameters may only be used as standalone arguments, i.e. `N`
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-expression.rs:26:45
@@ -41,7 +41,7 @@ LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
    |                                             ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-expression.rs:29:47
@@ -50,7 +50,7 @@ LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
    |                                               ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/complex-expression.rs:33:32
@@ -59,7 +59,7 @@ LL |     let _: [u8; size_of::<*mut T>() + 1];
    |                                ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 warning: cannot use constants which depend on generic parameters in types
   --> $DIR/complex-expression.rs:38:17
diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
index 7726016eb83..909b0476999 100644
--- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
+++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
@@ -5,7 +5,7 @@ LL |     test::<{ let _: &'a (); 3 },>();
    |                      ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
   --> $DIR/forbid-non-static-lifetimes.rs:21:16
@@ -14,7 +14,7 @@ LL |     [(); (|_: &'a u8| (), 0).1];
    |                ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
index 16a7687c00b..e9216fc12a2 100644
--- a/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
+++ b/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
@@ -5,7 +5,7 @@ LL |     fn t1() -> [u8; std::mem::size_of::<Self>()];
    |                                         ^^^^ cannot perform const operation using `Self`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic `Self` types are currently not permitted in anonymous constants
   --> $DIR/self-ty-in-const-1.rs:12:41
diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr
index 5a947677678..38b25445f61 100644
--- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr
+++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr
@@ -5,7 +5,7 @@ LL |         let x: &'a ();
    |                 ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
index a5e70f6b9e6..320c9c1c84d 100644
--- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
+++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
@@ -11,7 +11,7 @@ LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
    |                                            ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error[E0128]: generic parameters with a default cannot use forward declared identifiers
   --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21
diff --git a/tests/ui/consts/const-eval/size-of-t.stderr b/tests/ui/consts/const-eval/size-of-t.stderr
index ff09f5aee1c..418ac6f612c 100644
--- a/tests/ui/consts/const-eval/size-of-t.stderr
+++ b/tests/ui/consts/const-eval/size-of-t.stderr
@@ -5,7 +5,7 @@ LL |     let _arr: [u8; size_of::<T>()];
    |                              ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/raw-ptr-const.rs b/tests/ui/consts/raw-ptr-const.rs
index fc774be54df..541c5fd1ab1 100644
--- a/tests/ui/consts/raw-ptr-const.rs
+++ b/tests/ui/consts/raw-ptr-const.rs
@@ -1,4 +1,4 @@
-// This is a regression test for a `delay_span_bug` during interning when a constant
+// This is a regression test for a `span_delayed_bug` during interning when a constant
 // evaluates to a (non-dangling) raw pointer.  For now this errors; potentially it
 // could also be allowed.
 
diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr
index e641bba541e..c13ae4e7862 100644
--- a/tests/ui/error-codes/E0458.stderr
+++ b/tests/ui/error-codes/E0458.stderr
@@ -1,4 +1,4 @@
-error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib
+error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib, link-arg
   --> $DIR/E0458.rs:1:15
    |
 LL | #[link(kind = "wonderful_unicorn")] extern "C" {}
diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs b/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs
new file mode 100644
index 00000000000..9036095fbc4
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.rs
@@ -0,0 +1,5 @@
+#[link(kind = "link-arg", name = "foo")]
+//~^ ERROR link kind `link-arg` is unstable
+extern "C" {}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr
new file mode 100644
index 00000000000..673835b8b9e
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.stderr
@@ -0,0 +1,12 @@
+error[E0658]: link kind `link-arg` is unstable
+  --> $DIR/feature-gate-link-arg-attribute.rs:1:15
+   |
+LL | #[link(kind = "link-arg", name = "foo")]
+   |               ^^^^^^^^^^
+   |
+   = note: see issue #99427 <https://github.com/rust-lang/rust/issues/99427> for more information
+   = help: add `#![feature(link_arg_attribute)]` to the crate attributes to enable
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.stderr b/tests/ui/generic-associated-types/bugs/issue-88382.stderr
index 624fe2799e0..9b061528e3b 100644
--- a/tests/ui/generic-associated-types/bugs/issue-88382.stderr
+++ b/tests/ui/generic-associated-types/bugs/issue-88382.stderr
@@ -16,6 +16,10 @@ note: required by a bound in `do_something`
    |
 LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
    |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
+help: consider wrapping the function in a closure
+   |
+LL |     do_something(SomeImplementation(), |arg0: &mut std::iter::Empty<usize>| test(/* &mut <_ as Iterable>::Iterator<'_> */));
+   |                                        ++++++++++++++++++++++++++++++++++++     ++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generics/param-in-ct-in-ty-param-default.stderr b/tests/ui/generics/param-in-ct-in-ty-param-default.stderr
index 3d2a26e33c3..03dbb3eb9fc 100644
--- a/tests/ui/generics/param-in-ct-in-ty-param-default.stderr
+++ b/tests/ui/generics/param-in-ct-in-ty-param-default.stderr
@@ -5,7 +5,7 @@ LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
    |                                            ^ cannot perform const operation using `T`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
index 83791f0d3af..046d35e4e4a 100644
--- a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
+++ b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
@@ -1,4 +1,4 @@
-error: internal compiler error: no errors encountered even though `delay_span_bug` issued
+error: internal compiler error: no errors encountered even though `span_delayed_bug` issued
 
 error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }}
    |
diff --git a/tests/ui/imports/no-pub-reexports-but-used.rs b/tests/ui/imports/no-pub-reexports-but-used.rs
new file mode 100644
index 00000000000..28991bde829
--- /dev/null
+++ b/tests/ui/imports/no-pub-reexports-but-used.rs
@@ -0,0 +1,15 @@
+// check-pass
+// https://github.com/rust-lang/rust/issues/115966
+
+mod m {
+    pub(crate) type A = u8;
+}
+
+#[warn(unused_imports)] //~ NOTE: the lint level is defined here
+pub use m::*;
+//~^ WARNING: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
+//~| NOTE: the most public imported item is `pub(crate)`
+
+fn main() {
+    let _: A;
+}
diff --git a/tests/ui/imports/no-pub-reexports-but-used.stderr b/tests/ui/imports/no-pub-reexports-but-used.stderr
new file mode 100644
index 00000000000..b693dea1935
--- /dev/null
+++ b/tests/ui/imports/no-pub-reexports-but-used.stderr
@@ -0,0 +1,20 @@
+warning: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
+  --> $DIR/no-pub-reexports-but-used.rs:9:9
+   |
+LL | pub use m::*;
+   |         ^^^^
+   |
+note: the most public imported item is `pub(crate)`
+  --> $DIR/no-pub-reexports-but-used.rs:9:9
+   |
+LL | pub use m::*;
+   |         ^^^^
+   = help: reduce the glob import's visibility or increase visibility of imported items
+note: the lint level is defined here
+  --> $DIR/no-pub-reexports-but-used.rs:8:8
+   |
+LL | #[warn(unused_imports)]
+   |        ^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/imports/reexports.rs b/tests/ui/imports/reexports.rs
index cb1a3ebe180..2a1a62834ce 100644
--- a/tests/ui/imports/reexports.rs
+++ b/tests/ui/imports/reexports.rs
@@ -9,7 +9,7 @@ mod a {
         //~^ ERROR cannot be re-exported
         //~| WARNING unused import: `super::foo`
         pub use super::*;
-        //~^ WARNING glob import doesn't reexport anything because no candidate is public enough
+        //~^ WARNING glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
         //~| WARNING unused import: `super::*`
     }
 }
diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr
index 401e422af0f..bf4ba474875 100644
--- a/tests/ui/imports/reexports.stderr
+++ b/tests/ui/imports/reexports.stderr
@@ -56,11 +56,18 @@ note: the lint level is defined here
 LL | #![warn(unused_imports)]
    |         ^^^^^^^^^^^^^^
 
-warning: glob import doesn't reexport anything because no candidate is public enough
+warning: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
   --> $DIR/reexports.rs:11:17
    |
 LL |         pub use super::*;
    |                 ^^^^^^^^
+   |
+note: the most public imported item is `pub(a)`
+  --> $DIR/reexports.rs:11:17
+   |
+LL |         pub use super::*;
+   |                 ^^^^^^^^
+   = help: reduce the glob import's visibility or increase visibility of imported items
 
 warning: unused import: `super::*`
   --> $DIR/reexports.rs:11:17
diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr
index e6ff9d5a0df..bf91dc72cc1 100644
--- a/tests/ui/intrinsics/const-eval-select-bad.stderr
+++ b/tests/ui/intrinsics/const-eval-select-bad.stderr
@@ -86,6 +86,10 @@ LL |     const_eval_select((true,), foo, baz);
               found function signature `fn(i32) -> _`
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     const_eval_select((true,), |arg0: bool| foo(/* i32 */), baz);
+   |                                ++++++++++++    +++++++++++
 
 error: this argument must be a `const fn`
   --> $DIR/const-eval-select-bad.rs:42:29
diff --git a/tests/ui/issues/issue-76077.stderr b/tests/ui/issues/issue-76077.stderr
index 4c510e91ada..3fef5ffce30 100644
--- a/tests/ui/issues/issue-76077.stderr
+++ b/tests/ui/issues/issue-76077.stderr
@@ -4,7 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields
 LL |     foo::Foo {};
    |     ^^^^^^^^
    |
-   = note: ... and other private field `you_cant_use_this_field` that was not provided
+   = note: private field `you_cant_use_this_field` that was not provided
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
index 02ca10b2eb6..ec4aea62391 100644
--- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
+++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
@@ -5,7 +5,7 @@ LL |     beta: [(); foo::<&'a ()>()],
    |                       ^^ cannot perform const operation using `'a`
    |
    = note: lifetime parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic `Self` types are currently not permitted in anonymous constants
   --> $DIR/issue-64173-unused-lifetimes.rs:4:28
diff --git a/tests/ui/mismatched_types/E0631.stderr b/tests/ui/mismatched_types/E0631.stderr
index 410ea4b0b34..9ba8f5035c5 100644
--- a/tests/ui/mismatched_types/E0631.stderr
+++ b/tests/ui/mismatched_types/E0631.stderr
@@ -48,6 +48,10 @@ note: required by a bound in `foo`
    |
 LL | fn foo<F: Fn(usize)>(_: F) {}
    |           ^^^^^^^^^ required by this bound in `foo`
+help: consider wrapping the function in a closure
+   |
+LL |     foo(|arg0: usize| f(/* u64 */));
+   |         +++++++++++++  +++++++++++
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:10:9
@@ -67,6 +71,10 @@ note: required by a bound in `bar`
    |
 LL | fn bar<F: Fn<(usize,)>>(_: F) {}
    |           ^^^^^^^^^^^^ required by this bound in `bar`
+help: consider wrapping the function in a closure
+   |
+LL |     bar(|arg0: usize| f(/* u64 */));
+   |         +++++++++++++  +++++++++++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/mismatched_types/closure-ref-114180.stderr b/tests/ui/mismatched_types/closure-ref-114180.stderr
index 798c4e00aa7..27649822e69 100644
--- a/tests/ui/mismatched_types/closure-ref-114180.stderr
+++ b/tests/ui/mismatched_types/closure-ref-114180.stderr
@@ -12,6 +12,10 @@ LL |     v.sort_by(compare);
               found closure signature `fn((_,), (_,)) -> _`
 note: required by a bound in `slice::<impl [T]>::sort_by`
   --> $SRC_DIR/alloc/src/slice.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     v.sort_by(|arg0, arg1| compare(*arg0, *arg1));
+   |               ++++++++++++        ++++++++++++++
 help: consider adjusting the signature so it borrows its arguments
    |
 LL |     let compare = |&(a,), &(e,)| todo!();
diff --git a/tests/ui/mismatched_types/fn-variance-1.stderr b/tests/ui/mismatched_types/fn-variance-1.stderr
index 5794e606eeb..fdb2e6f0097 100644
--- a/tests/ui/mismatched_types/fn-variance-1.stderr
+++ b/tests/ui/mismatched_types/fn-variance-1.stderr
@@ -16,6 +16,10 @@ note: required by a bound in `apply`
    |
 LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
    |                                     ^^^^^^^^^ required by this bound in `apply`
+help: consider wrapping the function in a closure
+   |
+LL |     apply(&3, |x| takes_mut(&mut *x));
+   |               +++          +++++++++
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/fn-variance-1.rs:15:19
@@ -35,6 +39,10 @@ note: required by a bound in `apply`
    |
 LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
    |                                     ^^^^^^^^^ required by this bound in `apply`
+help: consider wrapping the function in a closure
+   |
+LL |     apply(&mut 3, |x| takes_imm(&*x));
+   |                   +++          +++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr b/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr
index 3db9803d58f..0ed57466e9c 100644
--- a/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr
+++ b/tests/ui/mismatched_types/suggest-option-asderef-inference-var.stderr
@@ -13,6 +13,10 @@ LL |     let _has_inference_vars: Option<i32> = Some(0).map(deref_int);
               found function signature `for<'a> fn(&'a i32) -> _`
 note: required by a bound in `Option::<T>::map`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _has_inference_vars: Option<i32> = Some(0).map(|a| deref_int(&a));
+   |                                                        +++          ++++
 help: consider adjusting the signature so it does not borrow its argument
    |
 LL - fn deref_int(a: &i32) -> i32 {
diff --git a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr
index 3175a258906..1ac057a5f38 100644
--- a/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr
+++ b/tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr
@@ -13,6 +13,10 @@ LL |     let _ = produces_string().and_then(takes_str_but_too_many_refs);
               found function signature `for<'a, 'b> fn(&'a &'b str) -> _`
 note: required by a bound in `Option::<T>::and_then`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _ = produces_string().and_then(|arg0: String| takes_str_but_too_many_refs(/* &&str */));
+   |                                        ++++++++++++++                            +++++++++++++
 
 error[E0277]: expected a `FnOnce(String)` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
   --> $DIR/suggest-option-asderef-unfixable.rs:26:40
@@ -68,6 +72,10 @@ LL |     let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
               found function signature `for<'a, 'b> fn(&'a &'b str) -> _`
 note: required by a bound in `Option::<T>::and_then`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _ = Some(TypeWithoutDeref).and_then(|arg0: TypeWithoutDeref| takes_str_but_too_many_refs(/* &&str */));
+   |                                             ++++++++++++++++++++++++                            +++++++++++++
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/mismatched_types/suggest-option-asderef.fixed b/tests/ui/mismatched_types/suggest-option-asderef.fixed
deleted file mode 100644
index fc488b790b3..00000000000
--- a/tests/ui/mismatched_types/suggest-option-asderef.fixed
+++ /dev/null
@@ -1,39 +0,0 @@
-// run-rustfix
-
-fn produces_string() -> Option<String> {
-    Some("my cool string".to_owned())
-}
-
-fn takes_str(_: &str) -> Option<()> {
-    Some(())
-}
-
-fn takes_str_mut(_: &mut str) -> Option<()> {
-    Some(())
-}
-
-fn generic<T>(_: T) -> Option<()> {
-    Some(())
-}
-
-fn generic_ref<T>(_: T) -> Option<()> {
-    //~^ HELP consider adjusting the signature so it does not borrow its argument
-    Some(())
-}
-
-fn main() {
-    let _: Option<()> = produces_string().as_deref().and_then(takes_str);
-    //~^ ERROR type mismatch in function arguments
-    //~| HELP call `Option::as_deref()` first
-    let _: Option<Option<()>> = produces_string().as_deref().map(takes_str);
-    //~^ ERROR type mismatch in function arguments
-    //~| HELP call `Option::as_deref()` first
-    let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut);
-    //~^ ERROR type mismatch in function arguments
-    //~| HELP call `Option::as_deref_mut()` first
-    let _ = produces_string().and_then(generic);
-
-    let _ = produces_string().as_deref().and_then(generic_ref);
-    //~^ ERROR type mismatch in function arguments
-    //~| HELP call `Option::as_deref()` first
-}
diff --git a/tests/ui/mismatched_types/suggest-option-asderef.rs b/tests/ui/mismatched_types/suggest-option-asderef.rs
index 28f46808a39..5f5617e1741 100644
--- a/tests/ui/mismatched_types/suggest-option-asderef.rs
+++ b/tests/ui/mismatched_types/suggest-option-asderef.rs
@@ -1,4 +1,4 @@
-// run-rustfix
+// this isn't auto-fixable now because we produce two similar suggestions
 
 fn produces_string() -> Option<String> {
     Some("my cool string".to_owned())
@@ -25,15 +25,19 @@ fn main() {
     let _: Option<()> = produces_string().and_then(takes_str);
     //~^ ERROR type mismatch in function arguments
     //~| HELP call `Option::as_deref()` first
+    //~| HELP consider wrapping the function in a closure
     let _: Option<Option<()>> = produces_string().map(takes_str);
     //~^ ERROR type mismatch in function arguments
     //~| HELP call `Option::as_deref()` first
+    //~| HELP consider wrapping the function in a closure
     let _: Option<Option<()>> = produces_string().map(takes_str_mut);
     //~^ ERROR type mismatch in function arguments
     //~| HELP call `Option::as_deref_mut()` first
+    //~| HELP consider wrapping the function in a closure
     let _ = produces_string().and_then(generic);
 
     let _ = produces_string().and_then(generic_ref);
     //~^ ERROR type mismatch in function arguments
     //~| HELP call `Option::as_deref()` first
+    //~| HELP consider wrapping the function in a closure
 }
diff --git a/tests/ui/mismatched_types/suggest-option-asderef.stderr b/tests/ui/mismatched_types/suggest-option-asderef.stderr
index bfea0867350..1702a7f1dec 100644
--- a/tests/ui/mismatched_types/suggest-option-asderef.stderr
+++ b/tests/ui/mismatched_types/suggest-option-asderef.stderr
@@ -13,13 +13,17 @@ LL |     let _: Option<()> = produces_string().and_then(takes_str);
               found function signature `for<'a> fn(&'a str) -> _`
 note: required by a bound in `Option::<T>::and_then`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _: Option<()> = produces_string().and_then(|arg0: String| takes_str(/* &str */));
+   |                                                    ++++++++++++++          ++++++++++++
 help: call `Option::as_deref()` first
    |
 LL |     let _: Option<()> = produces_string().as_deref().and_then(takes_str);
    |                                          +++++++++++
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/suggest-option-asderef.rs:28:55
+  --> $DIR/suggest-option-asderef.rs:29:55
    |
 LL | fn takes_str(_: &str) -> Option<()> {
    | ----------------------------------- found signature defined here
@@ -33,13 +37,17 @@ LL |     let _: Option<Option<()>> = produces_string().map(takes_str);
               found function signature `for<'a> fn(&'a str) -> _`
 note: required by a bound in `Option::<T>::map`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _: Option<Option<()>> = produces_string().map(|arg0: String| takes_str(/* &str */));
+   |                                                       ++++++++++++++          ++++++++++++
 help: call `Option::as_deref()` first
    |
 LL |     let _: Option<Option<()>> = produces_string().as_deref().map(takes_str);
    |                                                  +++++++++++
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/suggest-option-asderef.rs:31:55
+  --> $DIR/suggest-option-asderef.rs:33:55
    |
 LL | fn takes_str_mut(_: &mut str) -> Option<()> {
    | ------------------------------------------- found signature defined here
@@ -53,13 +61,17 @@ LL |     let _: Option<Option<()>> = produces_string().map(takes_str_mut);
               found function signature `for<'a> fn(&'a mut str) -> _`
 note: required by a bound in `Option::<T>::map`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _: Option<Option<()>> = produces_string().map(|arg0: String| takes_str_mut(/* &mut str */));
+   |                                                       ++++++++++++++              ++++++++++++++++
 help: call `Option::as_deref_mut()` first
    |
 LL |     let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut);
    |                                                  +++++++++++++++
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/suggest-option-asderef.rs:36:40
+  --> $DIR/suggest-option-asderef.rs:39:40
    |
 LL | fn generic_ref<T>(_: &T) -> Option<()> {
    | -------------------------------------- found signature defined here
@@ -73,6 +85,10 @@ LL |     let _ = produces_string().and_then(generic_ref);
               found function signature `for<'a> fn(&'a _) -> _`
 note: required by a bound in `Option::<T>::and_then`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |     let _ = produces_string().and_then(|arg0: String| generic_ref(&arg0));
+   |                                        ++++++++++++++            +++++++
 help: consider adjusting the signature so it does not borrow its argument
    |
 LL - fn generic_ref<T>(_: &T) -> Option<()> {
diff --git a/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index a900a49c710..d92d5dbd16f 100644
--- a/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/tests/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -16,6 +16,10 @@ note: required by a bound in `call_it`
    |
 LL | fn call_it<F: FnMut(isize, isize) -> isize>(y: isize, mut f: F) -> isize {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call_it`
+help: consider wrapping the function in a closure
+   |
+LL |     let z = call_it(3, |arg0: isize, arg1: isize| f(/* usize */, arg1));
+   |                        ++++++++++++++++++++++++++  +++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/native-library-link-flags/link-arg-from-rs.rs b/tests/ui/native-library-link-flags/link-arg-from-rs.rs
index 075e4d9e79e..4a6017fea33 100644
--- a/tests/ui/native-library-link-flags/link-arg-from-rs.rs
+++ b/tests/ui/native-library-link-flags/link-arg-from-rs.rs
@@ -1,8 +1,7 @@
-// link-arg is not supposed to be usable in #[link] attributes
+#![feature(link_arg_attribute)]
 
-// compile-flags:
-// error-pattern: error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib
-
-#[link(kind = "link-arg")]
+#[link(kind = "link-arg", name = "arg", modifiers = "+bundle")]
+//~^ ERROR linking modifier `bundle` is only compatible with `static` linking kind
 extern "C" {}
+
 pub fn main() {}
diff --git a/tests/ui/native-library-link-flags/link-arg-from-rs.stderr b/tests/ui/native-library-link-flags/link-arg-from-rs.stderr
index 69a7825c0b1..f31e15f1da6 100644
--- a/tests/ui/native-library-link-flags/link-arg-from-rs.stderr
+++ b/tests/ui/native-library-link-flags/link-arg-from-rs.stderr
@@ -1,16 +1,8 @@
-error[E0458]: unknown link kind `link-arg`, expected one of: static, dylib, framework, raw-dylib
-  --> $DIR/link-arg-from-rs.rs:6:15
+error: linking modifier `bundle` is only compatible with `static` linking kind
+  --> $DIR/link-arg-from-rs.rs:3:53
    |
-LL | #[link(kind = "link-arg")]
-   |               ^^^^^^^^^^ unknown link kind
+LL | #[link(kind = "link-arg", name = "arg", modifiers = "+bundle")]
+   |                                                     ^^^^^^^^^
 
-error[E0459]: `#[link]` attribute requires a `name = "string"` argument
-  --> $DIR/link-arg-from-rs.rs:6:1
-   |
-LL | #[link(kind = "link-arg")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0458, E0459.
-For more information about an error, try `rustc --explain E0458`.
diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs b/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs
new file mode 100644
index 00000000000..5fabf31cecd
--- /dev/null
+++ b/tests/ui/nll/polonius/location-insensitive-scopes-liveness.rs
@@ -0,0 +1,46 @@
+// This is a non-regression test about differences in scopes computed by NLLs and `-Zpolonius=next`
+// found during the crater run for PR #117593.
+//
+// Live loans were computed too early compared to some of the liveness data coming from later passes
+// than `liveness::trace`, on some specific CFGs shapes: a variable was dead during tracing but its
+// regions were marked live later, and live loans were not recomputed at this point.
+
+// check-pass
+// revisions: nll polonius
+// [polonius] compile-flags: -Zpolonius=next
+
+// minimized from wavefc-cli-3.0.0
+fn repro1() {
+    let a = 0;
+    let closure = || {
+        let _b = a;
+    };
+
+    let callback = if true { Some(closure) } else { None };
+    do_it(callback);
+}
+fn do_it<F>(_: Option<F>)
+where
+    F: Fn(),
+{
+}
+
+// minimized from simple-server-0.4.0
+fn repro2() {
+    let mut a = &();
+    let s = S(&mut a);
+    let _ = if true { Some(s) } else { None };
+}
+struct S<'a>(&'a mut &'a ());
+
+// minimized from https://github.com/SHaaD94/AICup2022
+fn repro3() {
+    let runner = ();
+    let writer = debug_interface(&runner);
+    let _ = if true { Some(writer) } else { None };
+}
+fn debug_interface(_: &()) -> &mut dyn std::io::Write {
+    unimplemented!()
+}
+
+fn main() {}
diff --git a/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr b/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
index df5968ba323..93a39edbb82 100644
--- a/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
+++ b/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
@@ -22,12 +22,18 @@ note: consider marking `Full` as `pub` in the imported module
 LL |     pub use self::Lieutenant::{JuniorGrade, Full};
    |                                             ^^^^
 
-error: glob import doesn't reexport anything because no candidate is public enough
+error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
   --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13
    |
 LL |     pub use self::Professor::*;
    |             ^^^^^^^^^^^^^^^^^^
    |
+note: the most public imported item is `pub(self)`
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13
+   |
+LL |     pub use self::Professor::*;
+   |             ^^^^^^^^^^^^^^^^^^
+   = help: reduce the glob import's visibility or increase visibility of imported items
 note: the lint level is defined here
   --> $DIR/issue-46209-private-enum-variant-reexport.rs:1:8
    |
@@ -46,11 +52,18 @@ error: unused imports: `Full`, `JuniorGrade`
 LL |     pub use self::Lieutenant::{JuniorGrade, Full};
    |                                ^^^^^^^^^^^  ^^^^
 
-error: glob import doesn't reexport anything because no candidate is public enough
+error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13
+   |
+LL |     pub use self::PettyOfficer::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the most public imported item is `pub(self)`
   --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13
    |
 LL |     pub use self::PettyOfficer::*;
    |             ^^^^^^^^^^^^^^^^^^^^^
+   = help: reduce the glob import's visibility or increase visibility of imported items
 
 error: unused import: `self::PettyOfficer::*`
   --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13
@@ -58,11 +71,18 @@ error: unused import: `self::PettyOfficer::*`
 LL |     pub use self::PettyOfficer::*;
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-error: glob import doesn't reexport anything because no candidate is public enough
+error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13
+   |
+LL |     pub use self::Crewman::*;
+   |             ^^^^^^^^^^^^^^^^
+   |
+note: the most public imported item is `pub(crate)`
   --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13
    |
 LL |     pub use self::Crewman::*;
    |             ^^^^^^^^^^^^^^^^
+   = help: reduce the glob import's visibility or increase visibility of imported items
 
 error: unused import: `self::Crewman::*`
   --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13
diff --git a/tests/ui/privacy/issue-79593.stderr b/tests/ui/privacy/issue-79593.stderr
index 21ba760ad0b..5bb69836f60 100644
--- a/tests/ui/privacy/issue-79593.stderr
+++ b/tests/ui/privacy/issue-79593.stderr
@@ -16,7 +16,7 @@ error: cannot construct `Pub` with struct literal syntax due to private fields
 LL |     foo::Pub {};
    |     ^^^^^^^^
    |
-   = note: ... and other private field `private` that was not provided
+   = note: private field `private` that was not provided
 
 error[E0063]: missing field `y` in initializer of `Enum`
   --> $DIR/issue-79593.rs:23:5
diff --git a/tests/ui/privacy/private-variant-reexport.stderr b/tests/ui/privacy/private-variant-reexport.stderr
index 2f041934a81..d73bd1a8cc2 100644
--- a/tests/ui/privacy/private-variant-reexport.stderr
+++ b/tests/ui/privacy/private-variant-reexport.stderr
@@ -30,12 +30,18 @@ LL |     pub use ::E::V::{self};
    |
    = note: consider declaring type or module `V` with `pub`
 
-error: glob import doesn't reexport anything because no candidate is public enough
+error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
   --> $DIR/private-variant-reexport.rs:15:13
    |
 LL |     pub use ::E::*;
    |             ^^^^^^
    |
+note: the most public imported item is `pub(crate)`
+  --> $DIR/private-variant-reexport.rs:15:13
+   |
+LL |     pub use ::E::*;
+   |             ^^^^^^
+   = help: reduce the glob import's visibility or increase visibility of imported items
 note: the lint level is defined here
   --> $DIR/private-variant-reexport.rs:13:8
    |
diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr
index 2224f1c60d6..8b01e8c3c10 100644
--- a/tests/ui/privacy/suggest-box-new.stderr
+++ b/tests/ui/privacy/suggest-box-new.stderr
@@ -56,7 +56,7 @@ error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to pri
 LL |     let _ = std::collections::HashMap {};
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: ... and other private field `base` that was not provided
+   = note: private field `base` that was not provided
 help: you might have meant to use an associated function to build this type
    |
 LL |     let _ = std::collections::HashMap::new();
@@ -78,7 +78,7 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi
 LL |     let _ = Box {};
    |             ^^^
    |
-   = note: ... and other private fields `0` and `1` that were not provided
+   = note: private fields `0` and `1` that were not provided
 help: you might have meant to use an associated function to build this type
    |
 LL |     let _ = Box::new(_);
diff --git a/tests/ui/proc-macro/literal-to-string.rs b/tests/ui/proc-macro/literal-to-string.rs
index 494d17cbeea..eb009036a9a 100644
--- a/tests/ui/proc-macro/literal-to-string.rs
+++ b/tests/ui/proc-macro/literal-to-string.rs
@@ -1,6 +1,5 @@
 // check-pass
 // edition: 2021
-#![feature(c_str_literals)]
 
 // aux-build: print-tokens.rs
 extern crate print_tokens;
diff --git a/tests/ui/proc-macro/literal-to-string.stdout b/tests/ui/proc-macro/literal-to-string.stdout
index 7b27fcf798b..ec6427545f4 100644
--- a/tests/ui/proc-macro/literal-to-string.stdout
+++ b/tests/ui/proc-macro/literal-to-string.stdout
@@ -3,91 +3,91 @@ TokenStream [
         kind: Integer,
         symbol: "1",
         suffix: None,
-        span: #0 bytes(172..173),
+        span: #0 bytes(144..145),
     },
     Literal {
         kind: Integer,
         symbol: "17",
         suffix: Some("u8"),
-        span: #0 bytes(182..186),
+        span: #0 bytes(154..158),
     },
     Literal {
         kind: Float,
         symbol: "42.",
         suffix: None,
-        span: #0 bytes(195..198),
+        span: #0 bytes(167..170),
     },
     Literal {
         kind: Float,
         symbol: "3.14",
         suffix: Some("f32"),
-        span: #0 bytes(207..214),
+        span: #0 bytes(179..186),
     },
     Literal {
         kind: Byte,
         symbol: "a",
         suffix: None,
-        span: #0 bytes(223..227),
+        span: #0 bytes(195..199),
     },
     Literal {
         kind: Byte,
         symbol: "\xFF",
         suffix: None,
-        span: #0 bytes(236..243),
+        span: #0 bytes(208..215),
     },
     Literal {
         kind: Char,
         symbol: "c",
         suffix: None,
-        span: #0 bytes(252..255),
+        span: #0 bytes(224..227),
     },
     Literal {
         kind: Char,
         symbol: "\x32",
         suffix: None,
-        span: #0 bytes(264..270),
+        span: #0 bytes(236..242),
     },
     Literal {
         kind: Str,
         symbol: "\\"str\\"",
         suffix: None,
-        span: #0 bytes(279..288),
+        span: #0 bytes(251..260),
     },
     Literal {
         kind: StrRaw(1),
         symbol: "\"raw\" str",
         suffix: None,
-        span: #0 bytes(297..311),
+        span: #0 bytes(269..283),
     },
     Literal {
         kind: StrRaw(3),
         symbol: "very ##\"raw\"## str",
         suffix: None,
-        span: #0 bytes(320..347),
+        span: #0 bytes(292..319),
     },
     Literal {
         kind: ByteStr,
         symbol: "\\"byte\\" str",
         suffix: None,
-        span: #0 bytes(356..371),
+        span: #0 bytes(328..343),
     },
     Literal {
         kind: ByteStrRaw(1),
         symbol: "\"raw\" \"byte\" str",
         suffix: None,
-        span: #0 bytes(380..402),
+        span: #0 bytes(352..374),
     },
     Literal {
         kind: CStr,
         symbol: "\\"c\\" str",
         suffix: None,
-        span: #0 bytes(411..423),
+        span: #0 bytes(383..395),
     },
     Literal {
         kind: CStrRaw(1),
         symbol: "\"raw\" \"c\" str",
         suffix: None,
-        span: #0 bytes(432..451),
+        span: #0 bytes(404..423),
     },
 ]
 1
diff --git a/tests/ui/resolve/issue-39559.stderr b/tests/ui/resolve/issue-39559.stderr
index e7d26d63be3..0aab54fe59d 100644
--- a/tests/ui/resolve/issue-39559.stderr
+++ b/tests/ui/resolve/issue-39559.stderr
@@ -5,7 +5,7 @@ LL |     entries: [T; D::dim()],
    |                  ^^^^^^ cannot perform const operation using `D`
    |
    = note: type parameters may not be used in const expressions
-   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs
index 5037396000b..5609dc51a67 100644
--- a/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs
+++ b/tests/ui/rfcs/rfc-3348-c-string-literals/basic.rs
@@ -1,8 +1,6 @@
 // run-pass
 // edition: 2021
 
-#![feature(c_str_literals)]
-
 fn main() {
     assert_eq!(b"test\0", c"test".to_bytes_with_nul());
 }
diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs
deleted file mode 100644
index ddd6d9a25da..00000000000
--- a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// gate-test-c_str_literals
-// known-bug: #113333
-// edition: 2021
-
-macro_rules! m {
-    ($t:tt) => {}
-}
-
-fn main() {
-    c"foo";
-    // FIXME(c_str_literals): This should be ``c".."` literals are experimental`
-
-    m!(c"test");
-    // FIXME(c_str_literals): This should be ``c".."` literals are experimental`
-}
diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr b/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr
deleted file mode 100644
index ea666e43308..00000000000
--- a/tests/ui/rfcs/rfc-3348-c-string-literals/gate.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0658]: `c".."` literals are experimental
-  --> $DIR/gate.rs:10:5
-   |
-LL |     c"foo";
-   |     ^^^^^^
-   |
-   = note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information
-   = help: add `#![feature(c_str_literals)]` to the crate attributes to enable
-
-error[E0658]: `c".."` literals are experimental
-  --> $DIR/gate.rs:13:8
-   |
-LL |     m!(c"test");
-   |        ^^^^^^^
-   |
-   = note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information
-   = help: add `#![feature(c_str_literals)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs
index 369173e2318..a7e36b2233e 100644
--- a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs
+++ b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs
Binary files differdiff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr
index 82d9f9cb320..ff9006f6f97 100644
--- a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr
+++ b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.stderr
Binary files differdiff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs
index 380445d7a7f..8a5f514db7f 100644
--- a/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs
+++ b/tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs
@@ -1,8 +1,6 @@
 // run-pass
 // edition: 2021
 
-#![feature(c_str_literals)]
-
 fn main() {
     assert_eq!(
         c"\xEF\x80🦀\u{1F980}".to_bytes_with_nul(),
diff --git a/tests/ui/suggestions/enum-variant-arg-mismatch.stderr b/tests/ui/suggestions/enum-variant-arg-mismatch.stderr
index 6d72dabf70e..16f03d16d8c 100644
--- a/tests/ui/suggestions/enum-variant-arg-mismatch.stderr
+++ b/tests/ui/suggestions/enum-variant-arg-mismatch.stderr
@@ -16,6 +16,10 @@ note: required by a bound in `map`
    |
 LL | fn map<'a, F: Fn(String) -> Sexpr<'a>>(f: F) {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map`
+help: consider wrapping the function in a closure
+   |
+LL |     map(|arg0: String| Sexpr::Ident(/* &str */));
+   |         ++++++++++++++             ++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr b/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr
index d78de6a460c..ee924522564 100644
--- a/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr
+++ b/tests/ui/suggestions/late-bound-in-borrow-closure-sugg.stderr
@@ -16,6 +16,10 @@ note: required by a bound in `Trader::<'a>::set_closure`
    |
 LL |     pub fn set_closure(&mut self, function: impl Fn(&mut Trader) + 'a) {
    |                                                  ^^^^^^^^^^^^^^^ required by this bound in `Trader::<'a>::set_closure`
+help: consider wrapping the function in a closure
+   |
+LL |     trader.set_closure(|arg0: &mut Trader<'_>| closure(*arg0));
+   |                        +++++++++++++++++++++++        +++++++
 help: consider adjusting the signature so it borrows its argument
    |
 LL |     let closure = |trader : &mut Trader| {
diff --git a/tests/ui/traits/subtype-recursion-limit.rs b/tests/ui/traits/subtype-recursion-limit.rs
new file mode 100644
index 00000000000..5804748844e
--- /dev/null
+++ b/tests/ui/traits/subtype-recursion-limit.rs
@@ -0,0 +1,17 @@
+// Variant of #117151 when the overflow comes entirely from subtype predicates.
+
+#![allow(unreachable_code)]
+
+use std::ptr;
+
+fn main() {
+    // Give x and y completely unconstrained types. Using a function call
+    // or `as` cast would create a well-formed predicate.
+    let x = return;
+    let y = return;
+    let mut w = (x, y);
+    //~^ ERROR overflow evaluating the requirement
+    // Avoid creating lifetimes, `Sized` bounds or function calls.
+    let a = (ptr::addr_of!(y), ptr::addr_of!(x));
+    w = a;
+}
diff --git a/tests/ui/traits/subtype-recursion-limit.stderr b/tests/ui/traits/subtype-recursion-limit.stderr
new file mode 100644
index 00000000000..5310f822cc3
--- /dev/null
+++ b/tests/ui/traits/subtype-recursion-limit.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `_ <: *const _`
+  --> $DIR/subtype-recursion-limit.rs:12:17
+   |
+LL |     let mut w = (x, y);
+   |                 ^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/well-formed-recursion-limit.rs b/tests/ui/traits/well-formed-recursion-limit.rs
new file mode 100644
index 00000000000..056cf947d4b
--- /dev/null
+++ b/tests/ui/traits/well-formed-recursion-limit.rs
@@ -0,0 +1,27 @@
+// Regression test for #117151, this used to hang the compiler
+
+pub type ISO<A: 'static, B: 'static> = (Box<dyn Fn(A) -> B>, Box<dyn Fn(B) -> A>);
+pub fn iso<A: 'static, B: 'static, F1, F2>(a: F1, b: F2) -> ISO<A, B>
+where
+    F1: 'static + Fn(A) -> B,
+    F2: 'static + Fn(B) -> A,
+{
+    (Box::new(a), Box::new(b))
+}
+pub fn iso_un_option<A: 'static, B: 'static>(i: ISO<Option<A>, Option<B>>) -> ISO<A, B> {
+    let (ab, ba) = (i.ab, i.ba);
+    //~^ ERROR no field `ab` on type
+    //~| ERROR no field `ba` on type
+    let left = move |o_a| match o_a {
+        //~^ ERROR overflow evaluating the requirement
+        None => panic!("absured"),
+        Some(a) => a,
+    };
+    let right = move |o_b| match o_b {
+        None => panic!("absurd"),
+        Some(b) => b,
+    };
+    iso(left, right)
+}
+
+fn main() {}
diff --git a/tests/ui/traits/well-formed-recursion-limit.stderr b/tests/ui/traits/well-formed-recursion-limit.stderr
new file mode 100644
index 00000000000..6f5fda02315
--- /dev/null
+++ b/tests/ui/traits/well-formed-recursion-limit.stderr
@@ -0,0 +1,22 @@
+error[E0609]: no field `ab` on type `(Box<(dyn Fn(Option<A>) -> Option<B> + 'static)>, Box<(dyn Fn(Option<B>) -> Option<A> + 'static)>)`
+  --> $DIR/well-formed-recursion-limit.rs:12:23
+   |
+LL |     let (ab, ba) = (i.ab, i.ba);
+   |                       ^^ unknown field
+
+error[E0609]: no field `ba` on type `(Box<(dyn Fn(Option<A>) -> Option<B> + 'static)>, Box<(dyn Fn(Option<B>) -> Option<A> + 'static)>)`
+  --> $DIR/well-formed-recursion-limit.rs:12:29
+   |
+LL |     let (ab, ba) = (i.ab, i.ba);
+   |                             ^^ unknown field
+
+error[E0275]: overflow evaluating the requirement `_ <: Option<_>`
+  --> $DIR/well-formed-recursion-limit.rs:15:33
+   |
+LL |     let left = move |o_a| match o_a {
+   |                                 ^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0275, E0609.
+For more information about an error, try `rustc --explain E0275`.
diff --git a/tests/ui/treat-err-as-bug/delay_span_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
index f667f8eb996..dda35b9b92a 100644
--- a/tests/ui/treat-err-as-bug/delay_span_bug.rs
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
@@ -1,12 +1,12 @@
 // compile-flags: -Ztreat-err-as-bug
 // failure-status: 101
 // error-pattern: aborting due to `-Z treat-err-as-bug=1`
-// error-pattern: [trigger_delay_span_bug] triggering a delay span bug for testing incremental
+// error-pattern: [trigger_span_delayed_bug] triggering a span delayed bug for testing incremental
 // normalize-stderr-test "note: .*\n\n" -> ""
 // normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> ""
 // rustc-env:RUST_BACKTRACE=0
 
 #![feature(rustc_attrs)]
 
-#[rustc_error(delay_span_bug_from_inside_query)]
+#[rustc_error(span_delayed_bug_from_inside_query)]
 fn main() {}
diff --git a/tests/ui/treat-err-as-bug/delay_span_bug.stderr b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
index 06a31ae86b2..a61ffaea8c2 100644
--- a/tests/ui/treat-err-as-bug/delay_span_bug.stderr
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr
@@ -1,5 +1,5 @@
-error: internal compiler error: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]
-  --> $DIR/delay_span_bug.rs:12:1
+error: internal compiler error: delayed span bug triggered by #[rustc_error(span_delayed_bug_from_inside_query)]
+  --> $DIR/span_delayed_bug.rs:12:1
    |
 LL | fn main() {}
    | ^^^^^^^^^
@@ -7,5 +7,5 @@ LL | fn main() {}
 error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
-#0 [trigger_delay_span_bug] triggering a delay span bug for testing incremental
+#0 [trigger_span_delayed_bug] triggering a span delayed bug for testing incremental
 end of query stack
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
index 844103d77a8..d4e2f953533 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
@@ -1,4 +1,4 @@
-error: internal compiler error: no errors encountered even though `delay_span_bug` issued
+error: internal compiler error: no errors encountered even though `span_delayed_bug` issued
 
 error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }}
    |
diff --git a/tests/ui/type-inference/generalize-subtyped-variables.rs b/tests/ui/type-inference/generalize-subtyped-variables.rs
new file mode 100644
index 00000000000..f93408a43db
--- /dev/null
+++ b/tests/ui/type-inference/generalize-subtyped-variables.rs
@@ -0,0 +1,25 @@
+// Test for specific details of how we handle higher-ranked subtyping to make
+// sure that any changes are made deliberately.
+//
+// - `let y = x` creates a `Subtype` obligation that is deferred for later.
+// - `w = a` sets the type of `x` to `Option<for<'a> fn(&'a ())>` and generalizes
+//   `z` first to `Option<_>` and then to `Option<fn(&'0 ())>`.
+//  - The various subtyping obligations are then processed.
+//
+// This requires that
+// 1. the `Subtype` obligation from `y = x` isn't processed while the types of
+//    `w` and `a` are being unified.
+// 2. the pending subtype obligation isn't considered when determining the type
+//    to generalize `z` to first (when related to the type of `y`).
+//
+// Found when considering fixes to #117151
+// check-pass
+
+fn main() {
+    let mut x = None;
+    let y = x;
+    let z = Default::default();
+    let mut w = (&mut x, z, z);
+    let a = (&mut None::<fn(&())>, y, None::<fn(&'static ())>);
+    w = a;
+}
diff --git a/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
index eab494ffbdf..899dd02583a 100644
--- a/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
+++ b/tests/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
@@ -4,7 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields
 LL |     foo::Foo {};
    |     ^^^^^^^^
    |
-   = note: ... and other private field `you_cant_use_this_field` that was not provided
+   = note: private field `you_cant_use_this_field` that was not provided
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr
index 51491407c49..41391720a28 100644
--- a/tests/ui/typeck/mismatched-map-under-self.stderr
+++ b/tests/ui/typeck/mismatched-map-under-self.stderr
@@ -30,6 +30,10 @@ LL |         self.map(Insertable::values).unwrap_or_default()
               found function signature `for<'a> fn(&'a _) -> _`
 note: required by a bound in `Option::<T>::map`
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: consider wrapping the function in a closure
+   |
+LL |         self.map(|arg0: T| Insertable::values(&arg0)).unwrap_or_default()
+   |                  +++++++++                   +++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr b/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr
index 96998ca244d..003eaa40592 100644
--- a/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr
+++ b/tests/ui/typeck/missing-private-fields-in-struct-literal.stderr
@@ -9,7 +9,7 @@ LL |         a: (),
 LL |         b: (),
    |         ----- private field
    |
-   = note: ... and other private fields `c`, `d` and `e` that were not provided
+   = note: ...and other private fields `c`, `d` and `e` that were not provided
 
 error: aborting due to 1 previous error
 
diff --git a/triagebot.toml b/triagebot.toml
index ed9d59b1bb9..24926690cfe 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -627,7 +627,7 @@ cc = ["@nnethercote"]
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
-users_on_vacation = ["jyn514", "oli-obk"]
+users_on_vacation = ["jyn514", "oli-obk", "wesleywiser"]
 
 [assign.adhoc_groups]
 compiler-team = [