about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT432
-rw-r--r--Cargo.lock45
-rw-r--r--compiler/rustc_ast/src/token.rs41
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs32
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs27
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs20
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/abi.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/archive.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs5
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs37
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs24
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs242
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs19
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs204
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs17
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs67
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs26
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs52
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs31
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/abi.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/misc.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/write.rs1
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs16
-rw-r--r--compiler/rustc_const_eval/src/lib.rs8
-rw-r--r--compiler/rustc_const_eval/src/might_permit_raw_init.rs44
-rw-r--r--compiler/rustc_const_eval/src/util/might_permit_raw_init.rs151
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs17
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0045.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0092.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0161.md7
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0579.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0622.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0743.md2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl68
-rw-r--r--compiler/rustc_error_messages/locales/en-US/compiletest.ftl5
-rw-r--r--compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl (renamed from compiler/rustc_error_messages/locales/en-US/typeck.ftl)64
-rw-r--r--compiler/rustc_error_messages/locales/en-US/lint.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/middle.ftl3
-rw-r--r--compiler/rustc_error_messages/locales/en-US/parser.ftl2
-rw-r--r--compiler/rustc_error_messages/src/lib.rs27
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs14
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs37
-rw-r--r--compiler/rustc_errors/src/lib.rs14
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs20
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_hir/src/def.rs115
-rw-r--r--compiler/rustc_hir/src/hir.rs11
-rw-r--r--compiler/rustc_hir/src/intravisit.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs78
-rw-r--r--compiler/rustc_hir_analysis/src/check/callee.rs274
-rw-r--r--compiler/rustc_hir_analysis/src/check/cast.rs77
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/check/demand.rs46
-rw-r--r--compiler/rustc_hir_analysis/src/check/expr.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs119
-rw-r--r--compiler/rustc_hir_analysis/src/check/generator_interior.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/check/inherited.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/check/method/prelude2021.rs112
-rw-r--r--compiler/rustc_hir_analysis/src/check/method/probe.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/check/method/suggest.rs54
-rw-r--r--compiler/rustc_hir_analysis/src/check/op.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/check/pat.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/check/upvar.rs26
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1203
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs480
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs707
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs117
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs89
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/mem_categorization.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs29
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs42
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs3
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs18
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs4
-rw-r--r--compiler/rustc_interface/src/queries.rs4
-rw-r--r--compiler/rustc_lint/src/array_into_iter.rs62
-rw-r--r--compiler/rustc_lint/src/builtin.rs659
-rw-r--r--compiler/rustc_lint/src/context.rs66
-rw-r--r--compiler/rustc_lint/src/early.rs6
-rw-r--r--compiler/rustc_lint/src/enum_intrinsics_non_enums.rs26
-rw-r--r--compiler/rustc_lint/src/expect.rs14
-rw-r--r--compiler/rustc_lint/src/hidden_unicode_codepoints.rs94
-rw-r--r--compiler/rustc_lint/src/internal.rs207
-rw-r--r--compiler/rustc_lint/src/let_underscore.rs67
-rw-r--r--compiler/rustc_lint/src/levels.rs953
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/methods.rs19
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs68
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs104
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs103
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs23
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs156
-rw-r--r--compiler/rustc_lint/src/pass_by_value.rs16
-rw-r--r--compiler/rustc_lint/src/redundant_semicolon.rs19
-rw-r--r--compiler/rustc_lint/src/traits.rs34
-rw-r--r--compiler/rustc_lint/src/types.rs257
-rw-r--r--compiler/rustc_lint/src/unused.rs148
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs31
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs37
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs9
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs33
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_middle/Cargo.toml2
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs38
-rw-r--r--compiler/rustc_middle/src/error.rs7
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs56
-rw-r--r--compiler/rustc_middle/src/lint.rs296
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs11
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs16
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs8
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs11
-rw-r--r--compiler/rustc_middle/src/ty/context.rs66
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2356
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs5
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs16
-rw-r--r--compiler/rustc_middle/src/ty/query.rs3
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs1
-rw-r--r--compiler/rustc_middle/src/ty/util.rs16
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs8
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs24
-rw-r--r--compiler/rustc_mir_build/src/lints.rs24
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs89
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs34
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs5
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs18
-rw-r--r--compiler/rustc_mir_transform/src/check_packed_ref.rs40
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs22
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs6
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs14
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs16
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs10
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs102
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs18
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs3
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs32
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs6
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs3
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs53
-rw-r--r--compiler/rustc_passes/src/check_const.rs26
-rw-r--r--compiler/rustc_passes/src/dead.rs66
-rw-r--r--compiler/rustc_passes/src/liveness.rs65
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs10
-rw-r--r--compiler/rustc_passes/src/stability.rs29
-rw-r--r--compiler/rustc_privacy/src/lib.rs4
-rw-r--r--compiler/rustc_query_impl/src/keys.rs18
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs6
-rw-r--r--compiler/rustc_query_system/src/ich/hcx.rs4
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs3
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs15
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs25
-rw-r--r--compiler/rustc_resolve/src/ident.rs22
-rw-r--r--compiler/rustc_resolve/src/late.rs49
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs615
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs55
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs3
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs5
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs14
-rw-r--r--compiler/rustc_span/src/def_id.rs20
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs2
-rw-r--r--compiler/rustc_target/src/abi/mod.rs70
-rw-r--r--compiler/rustc_target/src/spec/i386_apple_ios.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_linux_android.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_haiku.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/i686_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/linux_kernel_base.rs3
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs3
-rw-r--r--compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs11
-rw-r--r--compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs11
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_tvos.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_fuchsia.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_linux_android.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_pc_solaris.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_sun_solaris.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_none.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_redox.rs3
-rw-r--r--compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs50
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs27
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs8
-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.rs67
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs44
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs47
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs58
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs26
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs2
-rw-r--r--compiler/rustc_transmute/src/lib.rs15
-rw-r--r--compiler/rustc_ty_utils/Cargo.toml2
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs518
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs12
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs8
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs1804
-rw-r--r--compiler/rustc_ty_utils/src/layout_sanity_check.rs (renamed from compiler/rustc_middle/src/ty/layout_sanity_check.rs)2
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs7
-rw-r--r--config.toml.example10
-rw-r--r--library/alloc/src/collections/btree/map.rs12
-rw-r--r--library/alloc/src/collections/btree/set.rs12
-rw-r--r--library/alloc/src/sync.rs48
-rw-r--r--library/alloc/src/task.rs6
-rw-r--r--library/alloc/src/vec/in_place_collect.rs14
-rw-r--r--library/alloc/src/vec/in_place_drop.rs15
-rw-r--r--library/alloc/src/vec/into_iter.rs7
-rw-r--r--library/alloc/src/vec/mod.rs83
-rw-r--r--library/alloc/tests/vec.rs65
-rw-r--r--library/core/src/cell.rs1
-rw-r--r--library/core/src/char/methods.rs32
-rw-r--r--library/core/src/const_closure.rs64
-rw-r--r--library/core/src/convert/mod.rs209
-rw-r--r--library/core/src/fmt/mod.rs2
-rw-r--r--library/core/src/future/ready.rs24
-rw-r--r--library/core/src/intrinsics.rs38
-rw-r--r--library/core/src/iter/traits/collect.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs19
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/marker.rs1
-rw-r--r--library/core/src/num/mod.rs34
-rw-r--r--library/core/src/num/nonzero.rs154
-rw-r--r--library/core/src/ops/try_trait.rs2
-rw-r--r--library/core/src/option.rs17
-rw-r--r--library/core/src/result.rs31
-rw-r--r--library/core/src/slice/mod.rs15
-rw-r--r--library/core/src/slice/raw.rs24
-rw-r--r--library/core/src/str/traits.rs14
-rw-r--r--library/core/src/time.rs137
-rw-r--r--library/core/tests/ascii.rs18
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/time.rs24
-rw-r--r--library/std/src/collections/hash/map.rs3
-rw-r--r--library/std/src/collections/hash/map/tests.rs6
-rw-r--r--library/std/src/collections/hash/set.rs3
-rw-r--r--library/std/src/collections/hash/set/tests.rs6
-rw-r--r--library/std/src/env.rs2
-rw-r--r--library/std/src/lib.rs4
-rw-r--r--library/std/src/os/fd/mod.rs13
-rw-r--r--library/std/src/os/fd/owned.rs6
-rw-r--r--library/std/src/os/fd/raw.rs18
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/unix/io/fd.rs8
-rw-r--r--library/std/src/os/unix/io/mod.rs11
-rw-r--r--library/std/src/os/unix/io/raw.rs6
-rw-r--r--library/std/src/os/unix/io/tests.rs (renamed from library/std/src/os/unix/io/fd/tests.rs)0
-rw-r--r--library/std/src/os/wasi/io/mod.rs8
-rw-r--r--library/std/src/sys/unix/fs.rs62
-rw-r--r--library/std/src/sys/unix/time.rs34
-rw-r--r--library/std/src/sys/wasi/fs.rs19
-rw-r--r--library/std/src/sys/wasi/stdio.rs27
-rw-r--r--library/std/src/sys/wasi/time.rs4
-rw-r--r--library/std/src/sys/windows/fs.rs8
-rw-r--r--library/std/src/thread/mod.rs2
-rw-r--r--library/test/src/bench.rs21
-rw-r--r--library/test/src/lib.rs61
-rw-r--r--library/test/src/tests.rs90
-rw-r--r--library/test/src/types.rs15
-rw-r--r--src/bootstrap/CHANGELOG.md2
-rw-r--r--src/bootstrap/channel.rs68
-rw-r--r--src/bootstrap/compile.rs15
-rw-r--r--src/bootstrap/config.rs29
-rw-r--r--src/bootstrap/dist.rs41
-rw-r--r--src/bootstrap/lib.rs19
-rw-r--r--src/bootstrap/native.rs52
-rw-r--r--src/bootstrap/sanity.rs2
-rw-r--r--src/bootstrap/tarball.rs6
-rw-r--r--src/bootstrap/tool.rs2
-rw-r--r--src/ci/docker/README.md16
-rw-r--r--src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile35
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh26
-rw-r--r--src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config726
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile1
-rwxr-xr-xsrc/ci/run.sh5
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/etc/natvis/libcore.natvis4
-rw-r--r--src/librustdoc/clean/inline.rs4
-rw-r--r--src/librustdoc/clean/mod.rs9
-rw-r--r--src/librustdoc/clean/simplify.rs39
-rw-r--r--src/librustdoc/clean/types.rs27
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/librustdoc/core.rs16
-rw-r--r--src/librustdoc/doctest.rs1
-rw-r--r--src/librustdoc/fold.rs2
-rw-r--r--src/librustdoc/formats/cache.rs11
-rw-r--r--src/librustdoc/html/format.rs26
-rw-r--r--src/librustdoc/html/markdown.rs7
-rw-r--r--src/librustdoc/html/render/mod.rs11
-rw-r--r--src/librustdoc/html/render/print_item.rs6
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css86
-rw-r--r--src/librustdoc/html/static/css/settings.css3
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css58
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css64
-rw-r--r--src/librustdoc/html/static/css/themes/light.css60
-rw-r--r--src/librustdoc/json/mod.rs1
-rw-r--r--src/librustdoc/passes/bare_urls.rs6
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs92
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs10
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs12
-rw-r--r--src/librustdoc/passes/html_tags.rs11
-rw-r--r--src/librustdoc/visit.rs2
m---------src/llvm-project0
-rw-r--r--src/test/assembly/x86-stack-probes.rs42
-rw-r--r--src/test/codegen/abi-main-signature-32bit-c-int.rs2
-rw-r--r--src/test/codegen/binary-search-index-no-bound-check.rs20
-rw-r--r--src/test/codegen/stack-probes-call.rs24
-rw-r--r--src/test/codegen/stack-probes-inline.rs32
-rw-r--r--src/test/codegen/stack-probes.rs22
-rw-r--r--src/test/run-make/macos-fat-archive/Makefile10
-rw-r--r--src/test/run-make/macos-fat-archive/lib.rs3
-rw-r--r--src/test/run-make/macos-fat-archive/native-library.c1
-rw-r--r--src/test/rustdoc-gui/anchor-navigable.goml2
-rw-r--r--src/test/rustdoc-gui/font-weight.goml4
-rw-r--r--src/test/rustdoc-gui/no-docblock.goml8
-rw-r--r--src/test/rustdoc-gui/search-result-color.goml641
-rw-r--r--src/test/rustdoc-gui/sidebar-links-color.goml233
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile-scroll.goml6
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile.goml7
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code-display.goml19
-rw-r--r--src/test/rustdoc-gui/src-font-size.goml8
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs12
-rw-r--r--src/test/rustdoc-js-std/asrawfd.js6
-rw-r--r--src/test/rustdoc-ui/bare-urls.stderr2
-rw-r--r--src/test/rustdoc-ui/check-attr-test.stderr2
-rw-r--r--src/test/rustdoc-ui/check-attr.stderr2
-rw-r--r--src/test/rustdoc-ui/check-cfg-test.stderr2
-rw-r--r--src/test/rustdoc-ui/check-fail.stderr2
-rw-r--r--src/test/rustdoc-ui/check.stderr4
-rw-r--r--src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr2
-rw-r--r--src/test/rustdoc-ui/diagnostic-width.stderr2
-rw-r--r--src/test/rustdoc-ui/doc-attr.stderr4
-rw-r--r--src/test/rustdoc-ui/doc-include-suggestion.stderr2
-rw-r--r--src/test/rustdoc-ui/doc-spotlight.stderr8
-rw-r--r--src/test/rustdoc-ui/doc-test-attr.stderr4
-rw-r--r--src/test/rustdoc-ui/doctest-edition.stderr2
-rw-r--r--src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr6
-rw-r--r--src/test/rustdoc-ui/ignore-block-help.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.private.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.public.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/warning-crlf.stderr2
-rw-r--r--src/test/rustdoc-ui/invalid-doc-attr.stderr6
-rw-r--r--src/test/rustdoc-ui/invalid-syntax.rs6
-rw-r--r--src/test/rustdoc-ui/invalid-syntax.stderr19
-rw-r--r--src/test/rustdoc-ui/issue-74134.private.stderr2
-rw-r--r--src/test/rustdoc-ui/issue-74134.public.stderr2
-rw-r--r--src/test/rustdoc-ui/lint-group.stderr2
-rw-r--r--src/test/rustdoc-ui/macro-docs.stderr2
-rw-r--r--src/test/rustdoc-ui/no-crate-level-doc-lint.stderr4
-rw-r--r--src/test/rustdoc-ui/pub-export-lint.stderr2
-rw-r--r--src/test/rustdoc-ui/reference-link-reports-error-once.stderr2
-rw-r--r--src/test/rustdoc-ui/renamed-lint-still-applies.stderr4
-rw-r--r--src/test/rustdoc/anchors.no_const_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_trait_method_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_tymethod_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_type_anchor.html2
-rw-r--r--src/test/rustdoc/array-links.link_box_generic.html1
-rw-r--r--src/test/rustdoc/array-links.link_box_u32.html1
-rw-r--r--src/test/rustdoc/array-links.link_slice_generic.html1
-rw-r--r--src/test/rustdoc/array-links.link_slice_u32.html1
-rw-r--r--src/test/rustdoc/array-links.rs28
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html1
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html1
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs40
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs40
-rw-r--r--src/test/rustdoc/rfc-2632-const-trait-impl.rs8
-rw-r--r--src/test/rustdoc/safe-intrinsic.rs2
-rw-r--r--src/test/rustdoc/toggle-trait-fn.rs12
-rw-r--r--src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs8
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-for-crate.rs8
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs10
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs4
-rw-r--r--src/test/ui-fulldeps/auxiliary/lint-tool-test.rs8
-rw-r--r--src/test/ui-fulldeps/internal-lints/default_hash_types.stderr2
-rw-r--r--src/test/ui-fulldeps/internal-lints/diagnostics.rs10
-rw-r--r--src/test/ui-fulldeps/internal-lints/diagnostics.stderr2
-rw-r--r--src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr2
-rw-r--r--src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr2
-rw-r--r--src/test/ui-fulldeps/internal-lints/query_stability.stderr2
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs253
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr229
-rw-r--r--src/test/ui/abi/stack-probes-lto.rs2
-rw-r--r--src/test/ui/abi/stack-probes.rs29
-rw-r--r--src/test/ui/abi/unsupported.aarch64.stderr2
-rw-r--r--src/test/ui/abi/unsupported.arm.stderr2
-rw-r--r--src/test/ui/abi/unsupported.x64.stderr2
-rw-r--r--src/test/ui/abi/x86stdcall.rs26
-rw-r--r--src/test/ui/abi/x86stdcall2.rs12
-rw-r--r--src/test/ui/anon-params/anon-params-deprecated.stderr4
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-0.stderr4
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-1.stderr4
-rw-r--r--src/test/ui/asm/aarch64/type-check-3.stderr2
-rw-r--r--src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr2
-rw-r--r--src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr2
-rw-r--r--src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr2
-rw-r--r--src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr2
-rw-r--r--src/test/ui/asm/naked-functions-ffi.stderr2
-rw-r--r--src/test/ui/asm/named-asm-labels.stderr6
-rw-r--r--src/test/ui/asm/x86_64/type-check-3.stderr2
-rw-r--r--src/test/ui/associated-consts/defaults-not-assumed-fail.stderr6
-rw-r--r--src/test/ui/associated-types/defaults-specialization.stderr2
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr4
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-warning.stderr4
-rw-r--r--src/test/ui/async-await/large_moves.attribute.stderr2
-rw-r--r--src/test/ui/async-await/large_moves.option.stderr2
-rw-r--r--src/test/ui/attributes/doc-attr.stderr4
-rw-r--r--src/test/ui/attributes/invalid-doc-attr.stderr6
-rw-r--r--src/test/ui/auto-traits/suspicious-impls-lint.stderr10
-rw-r--r--src/test/ui/binding/issue-53114-safety-checks.stderr10
-rw-r--r--src/test/ui/block-result/consider-removing-last-semi.stderr6
-rw-r--r--src/test/ui/block-result/issue-11714.stderr2
-rw-r--r--src/test/ui/block-result/issue-13428.stderr2
-rw-r--r--src/test/ui/borrowck/issue-102209.rs28
-rw-r--r--src/test/ui/borrowck/issue-102209.stderr22
-rw-r--r--src/test/ui/borrowck/issue-81899.stderr4
-rw-r--r--src/test/ui/borrowck/issue-88434-minimal-example.stderr4
-rw-r--r--src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr4
-rw-r--r--src/test/ui/cenum_impl_drop_cast.stderr8
-rw-r--r--src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr2
-rw-r--r--src/test/ui/check-cfg/compact-values.stderr2
-rw-r--r--src/test/ui/check-cfg/empty-values.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-value.stderr2
-rw-r--r--src/test/ui/check-cfg/no-values.stderr2
-rw-r--r--src/test/ui/check-cfg/well-known-values.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-90465.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr2
-rw-r--r--src/test/ui/closures/old-closure-expression-remove-semicolon.fixed2
-rw-r--r--src/test/ui/closures/old-closure-expression-remove-semicolon.rs2
-rw-r--r--src/test/ui/closures/old-closure-expression-remove-semicolon.stderr2
-rw-r--r--src/test/ui/coercion/coercion-missing-tail-expected-type.stderr4
-rw-r--r--src/test/ui/coherence/coherence-fn-implied-bounds.stderr6
-rw-r--r--src/test/ui/coherence/coherence-free-vs-bound-region.stderr6
-rw-r--r--src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr2
-rw-r--r--src/test/ui/coherence/coherence-subtyping.stderr2
-rw-r--r--src/test/ui/coherence/coherence-wasm-bindgen.stderr8
-rw-r--r--src/test/ui/conflicting-repr-hints.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/function-call.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-102074.rs23
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr10
-rw-r--r--src/test/ui/const-generics/invariant.stderr2
-rw-r--r--src/test/ui/const-generics/issue-80471.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-83466.stderr2
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-expression.stderr2
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr2
-rw-r--r--src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr2
-rw-r--r--src/test/ui/const_prop/issue-102553.rs24
-rw-r--r--src/test/ui/consts/assert-type-intrinsics.rs9
-rw-r--r--src/test/ui/consts/assert-type-intrinsics.stderr32
-rw-r--r--src/test/ui/consts/assoc_const_generic_impl.stderr8
-rw-r--r--src/test/ui/consts/const-err-early.stderr24
-rw-r--r--src/test/ui/consts/const-err-multi.stderr20
-rw-r--r--src/test/ui/consts/const-err.stderr8
-rw-r--r--src/test/ui/consts/const-eval/conditional_array_execution.stderr12
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-2.stderr4
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow2.stderr36
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow2b.stderr36
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow2c.stderr36
-rw-r--r--src/test/ui/consts/const-eval/const-eval-query-stack.stderr12
-rw-r--r--src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr56
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr16
-rw-r--r--src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr2
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const.stderr8
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const2.stderr8
-rw-r--r--src/test/ui/consts/const-eval/format.stderr10
-rw-r--r--src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr8
-rw-r--r--src/test/ui/consts/const-eval/issue-43197.stderr20
-rw-r--r--src/test/ui/consts/const-eval/issue-44578.stderr8
-rw-r--r--src/test/ui/consts/const-eval/issue-50814-2.stderr4
-rw-r--r--src/test/ui/consts/const-eval/issue-50814.stderr4
-rw-r--r--src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr4
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.noopt.stderr12
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.opt.stderr12
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr12
-rw-r--r--src/test/ui/consts/const-eval/pub_const_err.stderr8
-rw-r--r--src/test/ui/consts/const-eval/pub_const_err_bin.stderr8
-rw-r--r--src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr4
-rw-r--r--src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr4
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.32bit.stderr12
-rw-r--r--src/test/ui/consts/const-eval/ub-enum.64bit.stderr12
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr12
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr12
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr16
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr16
-rw-r--r--src/test/ui/consts/const-eval/unused-broken-const.stderr4
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr2
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr2
-rw-r--r--src/test/ui/consts/const-external-macro-const-err.stderr4
-rw-r--r--src/test/ui/consts/const-float-bits-reject-conv.stderr18
-rw-r--r--src/test/ui/consts/const-fn-error.stderr4
-rw-r--r--src/test/ui/consts/const-for.stderr4
-rw-r--r--src/test/ui/consts/const-len-underflow-separate-spans.stderr4
-rw-r--r--src/test/ui/consts/const-prop-read-static-in-const.stderr4
-rw-r--r--src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr6
-rw-r--r--src/test/ui/consts/const-slice-oob.stderr4
-rw-r--r--src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr2
-rw-r--r--src/test/ui/consts/const_in_pattern/incomplete-slice.stderr2
-rw-r--r--src/test/ui/consts/const_in_pattern/issue-44333.stderr4
-rw-r--r--src/test/ui/consts/const_in_pattern/reject_non_structural.stderr4
-rw-r--r--src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr2
-rw-r--r--src/test/ui/consts/const_limit/const_eval_limit_reached.stderr4
-rw-r--r--src/test/ui/consts/constifconst-call-in-const-position.rs22
-rw-r--r--src/test/ui/consts/constifconst-call-in-const-position.stderr18
-rw-r--r--src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr8
-rw-r--r--src/test/ui/consts/invalid-union.32bit.stderr4
-rw-r--r--src/test/ui/consts/invalid-union.64bit.stderr4
-rw-r--r--src/test/ui/consts/issue-56164.stderr4
-rw-r--r--src/test/ui/consts/issue-66693.stderr4
-rw-r--r--src/test/ui/consts/issue-miri-1910.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const_2.stderr4
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr12
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr16
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr16
-rw-r--r--src/test/ui/consts/ptr_comparisons.stderr6
-rw-r--r--src/test/ui/consts/recursive.stderr6
-rw-r--r--src/test/ui/consts/refs_check_const_eq-issue-88384.stderr2
-rw-r--r--src/test/ui/consts/trait_specialization.stderr2
-rw-r--r--src/test/ui/consts/uninhabited-const-issue-61744.stderr4
-rw-r--r--src/test/ui/derive-uninhabited-enum-38885.stderr2
-rw-r--r--src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr2
-rw-r--r--src/test/ui/derives/deriving-with-repr-packed.stderr20
-rw-r--r--src/test/ui/deriving/deriving-default-enum.rs10
-rw-r--r--src/test/ui/destructuring-assignment/warn-unused-duplication.stderr2
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-ty.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-31424.stderr2
-rw-r--r--src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr4
-rw-r--r--src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr4
-rw-r--r--src/test/ui/dyn-keyword/dyn-angle-brackets.stderr4
-rw-r--r--src/test/ui/editions/edition-raw-pointer-method-2015.stderr4
-rw-r--r--src/test/ui/empty/empty-attributes.stderr2
-rw-r--r--src/test/ui/enum-discriminant/discriminant_size.stderr2
-rw-r--r--src/test/ui/enum-discriminant/issue-43398.stderr2
-rw-r--r--src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr2
-rw-r--r--src/test/ui/enum-discriminant/repr128.stderr2
-rw-r--r--src/test/ui/enum/enum-discrim-too-small2.stderr4
-rw-r--r--src/test/ui/error-codes/E0017.stderr2
-rw-r--r--src/test/ui/error-codes/E0094.rs2
-rw-r--r--src/test/ui/error-codes/E0094.stderr2
-rw-r--r--src/test/ui/error-codes/E0283.stderr4
-rw-r--r--src/test/ui/error-codes/E0308.rs2
-rw-r--r--src/test/ui/error-codes/E0308.stderr2
-rw-r--r--src/test/ui/error-codes/E0388.stderr2
-rw-r--r--src/test/ui/error-codes/E0520.stderr2
-rw-r--r--src/test/ui/error-codes/E0585.stderr2
-rw-r--r--src/test/ui/error-codes/E0771.stderr2
-rw-r--r--src/test/ui/error-codes/E0790.stderr20
-rw-r--r--src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr2
-rw-r--r--src/test/ui/expr/if/if-let.stderr2
-rw-r--r--src/test/ui/extern/extern-no-mangle.stderr2
-rw-r--r--src/test/ui/extern/extern-with-type-bounds.rs2
-rw-r--r--src/test/ui/extern/extern-with-type-bounds.stderr2
-rw-r--r--src/test/ui/feature-gates/bench.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-repr-simd.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-strict_provenance.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr2
-rw-r--r--src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr2
-rw-r--r--src/test/ui/fmt/auxiliary/format-string-proc-macro.rs28
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-102057.rs19
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-102057.stderr45
-rw-r--r--src/test/ui/fmt/format-args-capture-macro-hygiene.rs18
-rw-r--r--src/test/ui/fmt/format-args-capture-macro-hygiene.stderr37
-rw-r--r--src/test/ui/fmt/format-concat-span.stderr11
-rw-r--r--src/test/ui/fmt/format-expanded-string.rs (renamed from src/test/ui/fmt/format-concat-span.rs)9
-rw-r--r--src/test/ui/fmt/format-expanded-string.stderr19
-rw-r--r--src/test/ui/for-loop-while/while-let-2.stderr2
-rw-r--r--src/test/ui/future-incompatible-lint-group.stderr8
-rw-r--r--src/test/ui/generator/issue-52398.stderr2
-rw-r--r--src/test/ui/generator/issue-57084.stderr2
-rw-r--r--src/test/ui/generator/match-bindings.stderr2
-rw-r--r--src/test/ui/generator/print/generator-print-verbose-1.stderr8
-rw-r--r--src/test/ui/generator/reborrow-mut-upvar.stderr2
-rw-r--r--src/test/ui/generator/too-live-local-in-immovable-gen.stderr2
-rw-r--r--src/test/ui/generator/yield-in-args-rev.stderr2
-rw-r--r--src/test/ui/generator/yield-in-box.stderr2
-rw-r--r--src/test/ui/generator/yield-in-initializer.stderr2
-rw-r--r--src/test/ui/generator/yield-subtype.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-102114.rs16
-rw-r--r--src/test/ui/generic-associated-types/issue-102114.stderr12
-rw-r--r--src/test/ui/generic-associated-types/issue-102333.rs15
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-specialization.stderr2
-rw-r--r--src/test/ui/generics/issue-94923.rs49
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr2
-rw-r--r--src/test/ui/impl-trait/equality-rpass.stderr2
-rw-r--r--src/test/ui/impl-trait/equality.stderr2
-rw-r--r--src/test/ui/impl-trait/equality2.stderr2
-rw-r--r--src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs11
-rw-r--r--src/test/ui/impl-trait/in-trait/foreign.rs9
-rw-r--r--src/test/ui/impl-trait/in-trait/issue-102571.rs24
-rw-r--r--src/test/ui/impl-trait/in-trait/issue-102571.stderr14
-rw-r--r--src/test/ui/impl-trait/issue-100075-2.stderr2
-rw-r--r--src/test/ui/impl-trait/issue-102605.rs15
-rw-r--r--src/test/ui/impl-trait/issue-102605.stderr41
-rw-r--r--src/test/ui/impl-trait/issue-87450.stderr2
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait.rs1
-rw-r--r--src/test/ui/impl-trait/nested-return-type2-tait.stderr17
-rw-r--r--src/test/ui/impl-trait/nested-return-type2.rs1
-rw-r--r--src/test/ui/impl-trait/nested-return-type2.stderr17
-rw-r--r--src/test/ui/impl-trait/nested-return-type3-tait.rs1
-rw-r--r--src/test/ui/impl-trait/nested-return-type3-tait.stderr17
-rw-r--r--src/test/ui/impl-trait/nested-return-type3-tait2.rs1
-rw-r--r--src/test/ui/impl-trait/nested-return-type3-tait2.stderr17
-rw-r--r--src/test/ui/impl-trait/nested-return-type3-tait3.rs1
-rw-r--r--src/test/ui/impl-trait/nested-return-type3-tait3.stderr17
-rw-r--r--src/test/ui/impl-trait/nested-return-type3.rs1
-rw-r--r--src/test/ui/impl-trait/nested-return-type3.stderr17
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr2
-rw-r--r--src/test/ui/imports/local-modularized-tricky-fail-2.stderr2
-rw-r--r--src/test/ui/inference/inference-variable-behind-raw-pointer.stderr2
-rw-r--r--src/test/ui/inference/inference_unstable.stderr2
-rw-r--r--src/test/ui/inference/need_type_info/concrete-impl.stderr9
-rw-r--r--src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs11
-rw-r--r--src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr9
-rw-r--r--src/test/ui/intrinsics/intrinsic-alignment.rs1
-rw-r--r--src/test/ui/intrinsics/intrinsics-integer.rs6
-rw-r--r--src/test/ui/intrinsics/panic-uninitialized-zeroed.rs250
-rw-r--r--src/test/ui/intrinsics/safe-intrinsic-mismatch.rs11
-rw-r--r--src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr14
-rw-r--r--src/test/ui/issues/issue-11958.stderr4
-rw-r--r--src/test/ui/issues/issue-1460.stderr2
-rw-r--r--src/test/ui/issues/issue-16250.stderr12
-rw-r--r--src/test/ui/issues/issue-16256.stderr2
-rw-r--r--src/test/ui/issues/issue-24013.stderr5
-rw-r--r--src/test/ui/issues/issue-28344.stderr2
-rw-r--r--src/test/ui/issues/issue-47094.stderr2
-rw-r--r--src/test/ui/issues/issue-47486.stderr5
-rw-r--r--src/test/ui/issues/issue-47725.stderr2
-rw-r--r--src/test/ui/issues/issue-50781.stderr10
-rw-r--r--src/test/ui/issues/issue-54044.stderr2
-rw-r--r--src/test/ui/issues/issue-55380.stderr2
-rw-r--r--src/test/ui/issues/issue-58734.stderr2
-rw-r--r--src/test/ui/issues/issue-60622.stderr4
-rw-r--r--src/test/ui/issues/issue-6458-4.stderr2
-rw-r--r--src/test/ui/issues/issue-72278.stderr2
-rw-r--r--src/test/ui/issues/issue-78957.stderr2
-rw-r--r--src/test/ui/issues/issue-86756.stderr2
-rw-r--r--src/test/ui/issues/issue-8727.stderr2
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-2018.stderr2
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.stderr2
-rw-r--r--src/test/ui/lang-items/issue-83471.stderr2
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.stderr2
-rw-r--r--src/test/ui/limits/issue-55878.stderr4
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-early.stderr2
-rw-r--r--src/test/ui/lint/auxiliary/trivial-cast-ice.rs7
-rw-r--r--src/test/ui/lint/bare-trait-objects-path.stderr2
-rw-r--r--src/test/ui/lint/clashing-extern-fn.stderr6
-rw-r--r--src/test/ui/lint/cli-lint-override.forbid_warn.stderr2
-rw-r--r--src/test/ui/lint/cli-lint-override.force_warn_deny.stderr2
-rw-r--r--src/test/ui/lint/cli-lint-override.warn_deny.stderr2
-rw-r--r--src/test/ui/lint/dead-code/issue-85071-2.stderr10
-rw-r--r--src/test/ui/lint/dead-code/issue-85071.stderr10
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.stderr2
-rw-r--r--src/test/ui/lint/deny-overflowing-literals.stderr2
-rw-r--r--src/test/ui/lint/expansion-time.stderr8
-rw-r--r--src/test/ui/lint/fn_must_use.stderr2
-rw-r--r--src/test/ui/lint/forbid-group-group-2.stderr4
-rw-r--r--src/test/ui/lint/forbid-group-member.stderr2
-rw-r--r--src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr4
-rw-r--r--src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr4
-rw-r--r--src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/force-warn/cap-lints-allow.stderr2
-rw-r--r--src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/force-warn/deny-by-default-lint.stderr4
-rw-r--r--src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr2
-rw-r--r--src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/inclusive-range-pattern-syntax.stderr4
-rw-r--r--src/test/ui/lint/inert-attr-macro.stderr10
-rw-r--r--src/test/ui/lint/inline-trait-and-foreign-items.stderr4
-rw-r--r--src/test/ui/lint/invalid_value.rs5
-rw-r--r--src/test/ui/lint/invalid_value.stderr74
-rw-r--r--src/test/ui/lint/issue-14309.stderr10
-rw-r--r--src/test/ui/lint/issue-1866.stderr4
-rw-r--r--src/test/ui/lint/issue-63364.stderr2
-rw-r--r--src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr4
-rw-r--r--src/test/ui/lint/issue-79744.stderr2
-rw-r--r--src/test/ui/lint/issue-80988.stderr2
-rw-r--r--src/test/ui/lint/issue-83477.stderr2
-rw-r--r--src/test/ui/lint/issue-86600-lint-twice.stderr2
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-early.stderr4
-rw-r--r--src/test/ui/lint/lint-attr-everywhere-late.stderr120
-rw-r--r--src/test/ui/lint/lint-const-item-mutation.stderr2
-rw-r--r--src/test/ui/lint/lint-ctypes-73249-2.stderr2
-rw-r--r--src/test/ui/lint/lint-ctypes-73249-3.stderr2
-rw-r--r--src/test/ui/lint/lint-ctypes-73249-5.stderr2
-rw-r--r--src/test/ui/lint/lint-ctypes-73251-1.stderr2
-rw-r--r--src/test/ui/lint/lint-ctypes-73251-2.stderr2
-rw-r--r--src/test/ui/lint/lint-ctypes-enum.stderr10
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.stderr4
-rw-r--r--src/test/ui/lint/lint-ctypes.stderr10
-rw-r--r--src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr2
-rw-r--r--src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr2
-rw-r--r--src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr2
-rw-r--r--src/test/ui/lint/lint-non-snake-case-crate-2.stderr2
-rw-r--r--src/test/ui/lint/lint-pre-expansion-extern-module.stderr2
-rw-r--r--src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr2
-rw-r--r--src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr2
-rw-r--r--src/test/ui/lint/lint-temporary-cstring-as-param.stderr4
-rw-r--r--src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr4
-rw-r--r--src/test/ui/lint/lint-type-limits2.stderr4
-rw-r--r--src/test/ui/lint/lint-type-limits3.stderr4
-rw-r--r--src/test/ui/lint/lint-type-overflow.stderr2
-rw-r--r--src/test/ui/lint/lint-type-overflow2.stderr4
-rw-r--r--src/test/ui/lint/lint-unconditional-recursion.stderr2
-rw-r--r--src/test/ui/lint/lint-unsafe-code.stderr2
-rw-r--r--src/test/ui/lint/must_not_suspend/boxed.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/dedup.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/gated.stderr2
-rw-r--r--src/test/ui/lint/must_not_suspend/mutex.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/trait.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/unit.stderr10
-rw-r--r--src/test/ui/lint/must_not_suspend/warn.stderr10
-rw-r--r--src/test/ui/lint/noop-method-call.rs1
-rw-r--r--src/test/ui/lint/noop-method-call.stderr14
-rw-r--r--src/test/ui/lint/opaque-ty-ffi-unsafe.stderr2
-rw-r--r--src/test/ui/lint/outer-forbid.stderr4
-rw-r--r--src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr2
-rw-r--r--src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr2
-rw-r--r--src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr2
-rw-r--r--src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr2
-rw-r--r--src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr16
-rw-r--r--src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr2
-rw-r--r--src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr4
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr8
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr2
-rw-r--r--src/test/ui/lint/trivial-cast-ice.rs12
-rw-r--r--src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr4
-rw-r--r--src/test/ui/lint/trivial-casts.stderr4
-rw-r--r--src/test/ui/lint/trivial_casts.stderr4
-rw-r--r--src/test/ui/lint/type-overflow.stderr4
-rw-r--r--src/test/ui/lint/unaligned_references.stderr80
-rw-r--r--src/test/ui/lint/unaligned_references_external_macro.stderr16
-rw-r--r--src/test/ui/lint/unreachable_pub.stderr2
-rw-r--r--src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr2
-rw-r--r--src/test/ui/lint/unused/must-use-box-from-raw.stderr2
-rw-r--r--src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr2
-rw-r--r--src/test/ui/lint/unused/must_use-tuple.stderr2
-rw-r--r--src/test/ui/lint/unused/unused-attr-duplicate.stderr10
-rw-r--r--src/test/ui/lint/unused/unused-closure.stderr2
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr2
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr2
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.stderr10
-rw-r--r--src/test/ui/lint/unused/useless-comment.stderr2
-rw-r--r--src/test/ui/liveness/liveness-asm.stderr2
-rw-r--r--src/test/ui/liveness/liveness-consts.stderr4
-rw-r--r--src/test/ui/liveness/liveness-dead.stderr2
-rw-r--r--src/test/ui/liveness/liveness-return-last-stmt-semi.rs1
-rw-r--r--src/test/ui/liveness/liveness-return-last-stmt-semi.stderr10
-rw-r--r--src/test/ui/liveness/liveness-unused.stderr2
-rw-r--r--src/test/ui/liveness/liveness-upvars.stderr4
-rw-r--r--src/test/ui/macros/issue-39404.stderr2
-rw-r--r--src/test/ui/macros/issue-84195-lint-anon-const.stderr4
-rw-r--r--src/test/ui/macros/lint-trailing-macro-call.stderr2
-rw-r--r--src/test/ui/macros/macro-context.stderr2
-rw-r--r--src/test/ui/macros/macro-in-expression-context.stderr2
-rw-r--r--src/test/ui/macros/macro-match-nonterminal.stderr2
-rw-r--r--src/test/ui/macros/macro-missing-fragment-deduplication.stderr2
-rw-r--r--src/test/ui/macros/macro-missing-fragment.stderr4
-rw-r--r--src/test/ui/macros/macro-or-patterns-back-compat.stderr4
-rw-r--r--src/test/ui/macros/macro-use-all-and-none.stderr2
-rw-r--r--src/test/ui/macros/macros-nonfatal-errors.rs21
-rw-r--r--src/test/ui/macros/macros-nonfatal-errors.stderr12
-rw-r--r--src/test/ui/macros/must-use-in-macro-55516.stderr2
-rw-r--r--src/test/ui/malformed/malformed-regressions.stderr2
-rw-r--r--src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr2
-rw-r--r--src/test/ui/match/issue-41255.stderr4
-rw-r--r--src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr4
-rw-r--r--src/test/ui/methods/method-call-lifetime-args-lint.stderr4
-rw-r--r--src/test/ui/methods/method-call-lifetime-args-unresolved.stderr2
-rw-r--r--src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr2
-rw-r--r--src/test/ui/mir/thir-constparam-temp.stderr2
-rw-r--r--src/test/ui/modules/special_module_name.stderr2
-rw-r--r--src/test/ui/moves/move-out-of-slice-2.stderr2
-rw-r--r--src/test/ui/never_type/issue-52443.stderr4
-rw-r--r--src/test/ui/nll/issue-48623-generator.stderr2
-rw-r--r--src/test/ui/nll/issue-51191.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-captures.stderr8
-rw-r--r--src/test/ui/no-patterns-in-args-2.stderr4
-rw-r--r--src/test/ui/non-fmt-panic.stderr2
-rw-r--r--src/test/ui/packed/issue-27060-rpass.stderr32
-rw-r--r--src/test/ui/packed/issue-27060.stderr10
-rw-r--r--src/test/ui/packed/packed-struct-borrow-element-64bit.stderr16
-rw-r--r--src/test/ui/packed/packed-struct-borrow-element.stderr24
-rw-r--r--src/test/ui/parser/assoc-static-semantic-fail.stderr2
-rw-r--r--src/test/ui/parser/default.stderr2
-rw-r--r--src/test/ui/parser/doc-after-struct-field.rs4
-rw-r--r--src/test/ui/parser/doc-after-struct-field.stderr4
-rw-r--r--src/test/ui/parser/doc-before-extern-rbrace.stderr2
-rw-r--r--src/test/ui/parser/doc-before-fn-rbrace.rs2
-rw-r--r--src/test/ui/parser/doc-before-fn-rbrace.stderr2
-rw-r--r--src/test/ui/parser/doc-before-rbrace.rs2
-rw-r--r--src/test/ui/parser/doc-before-rbrace.stderr2
-rw-r--r--src/test/ui/parser/doc-before-semi.rs2
-rw-r--r--src/test/ui/parser/doc-before-semi.stderr2
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-1.rs2
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-1.stderr2
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-2.rs2
-rw-r--r--src/test/ui/parser/doc-before-struct-rbrace-2.stderr2
-rw-r--r--src/test/ui/parser/doc-inside-trait-item.stderr2
-rw-r--r--src/test/ui/parser/expr-as-stmt-2.stderr5
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr9
-rw-r--r--src/test/ui/parser/fn-field-parse-error-ice.rs2
-rw-r--r--src/test/ui/parser/fn-field-parse-error-ice.stderr10
-rw-r--r--src/test/ui/parser/issues/issue-34222-1.stderr2
-rw-r--r--src/test/ui/parser/issues/issue-48636.stderr2
-rw-r--r--src/test/ui/parser/macro/issue-33569.stderr2
-rw-r--r--src/test/ui/parser/recover-range-pats.stderr4
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr2
-rw-r--r--src/test/ui/parser/trait-object-trait-parens.stderr2
-rw-r--r--src/test/ui/parser/type-alias-where-fixable.stderr2
-rw-r--r--src/test/ui/parser/unicode-control-codepoints.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/consts-opaque.stderr2
-rw-r--r--src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr2
-rw-r--r--src/test/ui/polymorphization/const_parameters/closures.stderr2
-rw-r--r--src/test/ui/polymorphization/const_parameters/functions.stderr2
-rw-r--r--src/test/ui/polymorphization/generators.stderr2
-rw-r--r--src/test/ui/polymorphization/promoted-function-2.stderr2
-rw-r--r--src/test/ui/privacy/issue-30079.stderr2
-rw-r--r--src/test/ui/privacy/private-in-public-assoc-ty.stderr2
-rw-r--r--src/test/ui/privacy/private-in-public-non-principal.stderr2
-rw-r--r--src/test/ui/privacy/private-in-public-warn.stderr4
-rw-r--r--src/test/ui/privacy/where-priv-type.stderr2
-rw-r--r--src/test/ui/proc-macro/attr-complex-fn.stdout4
-rw-r--r--src/test/ui/proc-macro/capture-macro-rules-invoke.stdout12
-rw-r--r--src/test/ui/proc-macro/debug/dump-debug-span-debug.rs7
-rw-r--r--src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr127
-rw-r--r--src/test/ui/proc-macro/debug/dump-debug.stderr6
-rw-r--r--src/test/ui/proc-macro/derive-helper-shadowing.stderr2
-rw-r--r--src/test/ui/proc-macro/dollar-crate-issue-57089.stdout8
-rw-r--r--src/test/ui/proc-macro/dollar-crate-issue-62325.stdout8
-rw-r--r--src/test/ui/proc-macro/dollar-crate.stdout24
-rw-r--r--src/test/ui/proc-macro/generate-mod.stderr18
-rw-r--r--src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr2
-rw-r--r--src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr2
-rw-r--r--src/test/ui/proc-macro/inner-attrs.stdout4
-rw-r--r--src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr10
-rw-r--r--src/test/ui/proc-macro/issue-75930-derive-cfg.stderr2
-rw-r--r--src/test/ui/proc-macro/issue-75930-derive-cfg.stdout20
-rw-r--r--src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout4
-rw-r--r--src/test/ui/proc-macro/meta-macro-hygiene.stdout2
-rw-r--r--src/test/ui/proc-macro/proc-macro-attributes.stderr2
-rw-r--r--src/test/ui/proc-macro/proc-macro-gates.stderr2
-rw-r--r--src/test/ui/proc-macro/three-equals.stderr6
-rw-r--r--src/test/ui/process/process-panic-after-fork.rs1
-rw-r--r--src/test/ui/pub/pub-reexport-priv-extern-crate.stderr2
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence.stderr4
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence2.stderr4
-rw-r--r--src/test/ui/recursion/issue-83150.stderr2
-rw-r--r--src/test/ui/regions/issue-102374.rs20
-rw-r--r--src/test/ui/regions/issue-102374.stderr14
-rw-r--r--src/test/ui/regions/region-bound-on-closure-outlives-call.stderr2
-rw-r--r--src/test/ui/repr/repr-transparent-issue-87496.stderr2
-rw-r--r--src/test/ui/repr/repr-transparent-non-exhaustive.rs24
-rw-r--r--src/test/ui/repr/repr-transparent-non-exhaustive.stderr30
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr4
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr48
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr8
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/warns.stderr4
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs9
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr16
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr16
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr16
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs15
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr19
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs9
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr24
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr14
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs20
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr8
-rw-r--r--src/test/ui/rust-2018/async-ident-allowed.stderr4
-rw-r--r--src/test/ui/rust-2018/async-ident.stderr4
-rw-r--r--src/test/ui/rust-2018/dyn-keyword.stderr4
-rw-r--r--src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr4
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr4
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-paths.stderr4
-rw-r--r--src/test/ui/rust-2018/edition-lint-paths.stderr4
-rw-r--r--src/test/ui/rust-2018/extern-crate-rename.stderr4
-rw-r--r--src/test/ui/rust-2018/extern-crate-submod.stderr4
-rw-r--r--src/test/ui/rust-2018/try-ident.stderr4
-rw-r--r--src/test/ui/rust-2018/try-macro.stderr4
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.stderr4
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr4
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.stderr4
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.stderr4
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-macros.stderr4
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr4
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.stderr4
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.stderr4
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.stderr4
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.stderr4
-rw-r--r--src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr4
-rw-r--r--src/test/ui/rustdoc/doc-test-attr.stderr4
-rw-r--r--src/test/ui/rustdoc/feature-gate-doc_primitive.stderr2
-rw-r--r--src/test/ui/sanitize/inline-always.stderr2
-rw-r--r--src/test/ui/simd/target-feature-mixup.rs1
-rw-r--r--src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr2
-rw-r--r--src/test/ui/specialization/assoc-ty-graph-cycle.stderr2
-rw-r--r--src/test/ui/specialization/cross-crate-defaults.stderr2
-rw-r--r--src/test/ui/specialization/default-associated-type-bound-1.stderr2
-rw-r--r--src/test/ui/specialization/default-associated-type-bound-2.stderr2
-rw-r--r--src/test/ui/specialization/default-generic-associated-type-bound.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/out-of-order.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/overlap-projection.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/projection.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-no-default.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr2
-rw-r--r--src/test/ui/specialization/defaultimpl/validation.stderr2
-rw-r--r--src/test/ui/specialization/issue-35376.stderr2
-rw-r--r--src/test/ui/specialization/issue-36804.stderr2
-rw-r--r--src/test/ui/specialization/issue-38091-2.stderr2
-rw-r--r--src/test/ui/specialization/issue-38091.stderr2
-rw-r--r--src/test/ui/specialization/issue-39448.stderr2
-rw-r--r--src/test/ui/specialization/issue-39618.stderr2
-rw-r--r--src/test/ui/specialization/issue-50452-fail.stderr2
-rw-r--r--src/test/ui/specialization/issue-50452.stderr2
-rw-r--r--src/test/ui/specialization/issue-52050.stderr2
-rw-r--r--src/test/ui/specialization/issue-63716-parse-async.stderr2
-rw-r--r--src/test/ui/specialization/issue-70442.stderr2
-rw-r--r--src/test/ui/specialization/non-defaulted-item-fail.stderr2
-rw-r--r--src/test/ui/specialization/specialization-allowed-cross-crate.stderr2
-rw-r--r--src/test/ui/specialization/specialization-assoc-fns.stderr2
-rw-r--r--src/test/ui/specialization/specialization-basics.stderr2
-rw-r--r--src/test/ui/specialization/specialization-cross-crate.stderr2
-rw-r--r--src/test/ui/specialization/specialization-default-methods.stderr2
-rw-r--r--src/test/ui/specialization/specialization-default-projection.stderr2
-rw-r--r--src/test/ui/specialization/specialization-default-types.stderr2
-rw-r--r--src/test/ui/specialization/specialization-no-default.stderr2
-rw-r--r--src/test/ui/specialization/specialization-on-projection.stderr2
-rw-r--r--src/test/ui/specialization/specialization-out-of-order.stderr2
-rw-r--r--src/test/ui/specialization/specialization-overlap-negative.stderr2
-rw-r--r--src/test/ui/specialization/specialization-overlap-projection.stderr2
-rw-r--r--src/test/ui/specialization/specialization-overlap.stderr2
-rw-r--r--src/test/ui/specialization/specialization-polarity.stderr2
-rw-r--r--src/test/ui/specialization/specialization-projection-alias.stderr2
-rw-r--r--src/test/ui/specialization/specialization-projection.stderr2
-rw-r--r--src/test/ui/specialization/specialization-supertraits.stderr2
-rw-r--r--src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr2
-rw-r--r--src/test/ui/specialization/specialization-translate-projections-with-params.stderr2
-rw-r--r--src/test/ui/specialization/specialization-translate-projections.stderr2
-rw-r--r--src/test/ui/specialization/transmute-specialization.stderr2
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr2
-rw-r--r--src/test/ui/statics/uninhabited-static.stderr8
-rw-r--r--src/test/ui/stats/hir-stats.rs1
-rw-r--r--src/test/ui/stats/hir-stats.stderr92
-rw-r--r--src/test/ui/structs-enums/rec-align-u32.rs1
-rw-r--r--src/test/ui/structs-enums/rec-align-u64.rs1
-rw-r--r--src/test/ui/structs/incomplete-fn-in-struct-definition.rs5
-rw-r--r--src/test/ui/structs/incomplete-fn-in-struct-definition.stderr15
-rw-r--r--src/test/ui/suggestions/boxed-variant-field.rs1
-rw-r--r--src/test/ui/suggestions/boxed-variant-field.stderr4
-rw-r--r--src/test/ui/suggestions/into-convert.rs26
-rw-r--r--src/test/ui/suggestions/into-convert.stderr44
-rw-r--r--src/test/ui/suggestions/issue-61963.stderr4
-rw-r--r--src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr2
-rw-r--r--src/test/ui/suggestions/sugg-else-for-closure.fixed8
-rw-r--r--src/test/ui/suggestions/sugg-else-for-closure.rs8
-rw-r--r--src/test/ui/suggestions/sugg-else-for-closure.stderr23
-rw-r--r--src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr2
-rw-r--r--src/test/ui/test-attrs/test-on-not-fn.stderr24
-rw-r--r--src/test/ui/traits/bound/not-on-bare-trait.stderr2
-rw-r--r--src/test/ui/traits/issue-91949-hangs-on-recursion.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/negative-default-impls.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/negative-specializes-negative.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/negative-specializes-positive.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/positive-specializes-negative.stderr2
-rw-r--r--src/test/ui/traits/object/issue-33140-traitobject-crate.stderr4
-rw-r--r--src/test/ui/traits/static-method-generic-inference.stderr4
-rw-r--r--src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr4
-rw-r--r--src/test/ui/traits/unspecified-self-in-trait-ref.stderr2
-rw-r--r--src/test/ui/transmutability/issue-101739-1.rs21
-rw-r--r--src/test/ui/transmutability/issue-101739-1.stderr16
-rw-r--r--src/test/ui/transmutability/issue-101739-2.rs37
-rw-r--r--src/test/ui/transmutability/issue-101739-2.stderr20
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr2
-rw-r--r--src/test/ui/type/issue-101866.rs15
-rw-r--r--src/test/ui/type/issue-101866.stderr18
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr2
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr2
-rw-r--r--src/test/ui/union/union-repr-c.stderr10
-rw-r--r--src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr2
-rw-r--r--src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr4
-rw-r--r--src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr2
-rw-r--r--src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr4
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr4
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr4
-rw-r--r--src/test/ui/unsized-locals/borrow-after-move.stderr2
-rw-r--r--src/test/ui/unsized-locals/by-value-trait-object-safety.stderr2
-rw-r--r--src/test/ui/unsized-locals/double-move.stderr2
-rw-r--r--src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr2
-rw-r--r--src/test/ui/unsized-locals/issue-50940-with-feature.stderr2
-rw-r--r--src/test/ui/unwind-abis/feature-gate-c-unwind.stderr2
-rw-r--r--src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr18
-rw-r--r--src/test/ui/where-clauses/higher-ranked-fn-type.rs25
-rw-r--r--src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr18
-rw-r--r--src/tools/build-manifest/src/main.rs10
-rw-r--r--src/tools/build-manifest/src/versions.rs8
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/module_style.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs46
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr2
-rw-r--r--src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr2
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr2
-rw-r--r--src/tools/clippy/tests/ui/approx_const.stderr2
-rw-r--r--src/tools/clippy/tests/ui/as_conversions.stderr2
-rw-r--r--src/tools/clippy/tests/ui/asm_syntax.stderr4
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_constants.stderr2
-rw-r--r--src/tools/clippy/tests/ui/await_holding_lock.stderr2
-rw-r--r--src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr2
-rw-r--r--src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr2
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.stderr2
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr2
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr2
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr2
-rw-r--r--src/tools/clippy/tests/ui/box_collection.stderr2
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr2
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr10
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr10
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr10
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr2
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8.stderr2
-rw-r--r--src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr2
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr2
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity.stderr2
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr2
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.stderr2
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/comparison_chain.stderr2
-rw-r--r--src/tools/clippy/tests/ui/copy_iterator.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-360.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6254.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7868.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7869.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9463.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr2
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.stderr2
-rw-r--r--src/tools/clippy/tests/ui/default_union_representation.stderr2
-rw-r--r--src/tools/clippy/tests/ui/derive.stderr2
-rw-r--r--src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr2
-rw-r--r--src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr2
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr2
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.stderr2
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.stderr4
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.stderr2
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.stderr2
-rw-r--r--src/tools/clippy/tests/ui/else_if_without_else.stderr2
-rw-r--r--src/tools/clippy/tests/ui/empty_enum.stderr2
-rw-r--r--src/tools/clippy/tests/ui/empty_loop.stderr2
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_no_std.stderr2
-rw-r--r--src/tools/clippy/tests/ui/expect.stderr2
-rw-r--r--src/tools/clippy/tests/ui/fallible_impl_from.stderr10
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.stderr2
-rw-r--r--src/tools/clippy/tests/ui/filetype_is_file.stderr2
-rw-r--r--src/tools/clippy/tests/ui/float_cmp.stderr2
-rw-r--r--src/tools/clippy/tests/ui/float_cmp_const.stderr2
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr2
-rw-r--r--src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr2
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.stderr2
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.stderr2
-rw-r--r--src/tools/clippy/tests/ui/format_args_unfixable.stderr2
-rw-r--r--src/tools/clippy/tests/ui/format_push_string.stderr2
-rw-r--r--src/tools/clippy/tests/ui/formatting.stderr4
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr2
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.stderr2
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.stderr2
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.stderr2
-rw-r--r--src/tools/clippy/tests/ui/if_not_else.stderr2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else.stderr2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.stderr2
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.stderr2
-rw-r--r--src/tools/clippy/tests/ui/impl.stderr2
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr2
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_slice.stderr2
-rw-r--r--src/tools/clippy/tests/ui/inefficient_to_string.stderr2
-rw-r--r--src/tools/clippy/tests/ui/infinite_loop.stderr2
-rw-r--r--src/tools/clippy/tests/ui/inherent_to_string.stderr4
-rw-r--r--src/tools/clippy/tests/ui/inspect_for_each.stderr2
-rw-r--r--src/tools/clippy/tests/ui/integer_division.stderr2
-rw-r--r--src/tools/clippy/tests/ui/issue_4266.stderr2
-rw-r--r--src/tools/clippy/tests/ui/iter_nth.stderr2
-rw-r--r--src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr2
-rw-r--r--src/tools/clippy/tests/ui/large_stack_arrays.stderr2
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.stderr2
-rw-r--r--src/tools/clippy/tests/ui/let_if_seq.stderr2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_drop.stderr2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_lock.stderr2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_must_use.stderr2
-rw-r--r--src/tools/clippy/tests/ui/linkedlist.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_find.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_flatten.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.stderr2
-rw-r--r--src/tools/clippy/tests/ui/map_err.stderr2
-rw-r--r--src/tools/clippy/tests/ui/match_overlapping_arm.stderr2
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms.stderr2
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr2
-rw-r--r--src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.stderr2
-rw-r--r--src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr2
-rw-r--r--src/tools/clippy/tests/ui/mismatching_type_param_order.stderr2
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.stderr2
-rw-r--r--src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr2
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr2
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr2
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr2
-rw-r--r--src/tools/clippy/tests/ui/mut_from_ref.stderr2
-rw-r--r--src/tools/clippy/tests/ui/mut_range_bound.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_continue.stderr2
-rw-r--r--src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr2
-rw-r--r--src/tools/clippy/tests/ui/octal_escapes.stderr2
-rw-r--r--src/tools/clippy/tests/ui/ok_expect.stderr2
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion.stderr2
-rw-r--r--src/tools/clippy/tests/ui/only_used_in_recursion2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/option_env_unwrap.stderr2
-rw-r--r--src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr2
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.stderr2
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr2
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr2
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr2
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr2
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr2
-rw-r--r--src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr2
-rw-r--r--src/tools/clippy/tests/ui/proc_macro.stderr2
-rw-r--r--src/tools/clippy/tests/ui/pub_use.stderr2
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr2
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr2
-rw-r--r--src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr2
-rw-r--r--src/tools/clippy/tests/ui/rc_mutex.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr2
-rw-r--r--src/tools/clippy/tests/ui/regex.stderr2
-rw-r--r--src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr2
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.stderr2
-rw-r--r--src/tools/clippy/tests/ui/result_unit_error.stderr2
-rw-r--r--src/tools/clippy/tests/ui/return_self_not_must_use.stderr2
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr2
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.stderr2
-rw-r--r--src/tools/clippy/tests/ui/same_name_method.stderr2
-rw-r--r--src/tools/clippy/tests/ui/search_is_some.stderr2
-rw-r--r--src/tools/clippy/tests/ui/shadow.stderr6
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr2
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr2
-rw-r--r--src/tools/clippy/tests/ui/similar_names.stderr2
-rw-r--r--src/tools/clippy/tests/ui/single_char_lifetime_names.stderr2
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr2
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr2
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr2
-rw-r--r--src/tools/clippy/tests/ui/skip_while_next.stderr2
-rw-r--r--src/tools/clippy/tests/ui/stable_sort_primitive.stderr2
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr6
-rw-r--r--src/tools/clippy/tests/ui/str_to_string.stderr2
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.stderr2
-rw-r--r--src/tools/clippy/tests/ui/struct_excessive_bools.stderr2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.stderr2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_map.stderr2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_splitn.stderr2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr2
-rw-r--r--src/tools/clippy/tests/ui/swap.stderr4
-rw-r--r--src/tools/clippy/tests/ui/trailing_empty_array.stderr2
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr2
-rw-r--r--src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr2
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr2
-rw-r--r--src/tools/clippy/tests/ui/undropped_manually_drops.stderr2
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unit_hash.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_self_imports.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unneeded_field_pattern.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unused_async.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unused_peekable.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unused_self.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unwrap.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unwrap_expect_used.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unwrap_in_result.stderr2
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion_try.stderr2
-rw-r--r--src/tools/clippy/tests/ui/vec_resize_to_zero.stderr2
-rw-r--r--src/tools/clippy/tests/ui/verbose_file_reads.stderr2
-rw-r--r--src/tools/clippy/tests/ui/vtable_address_comparisons.stderr2
-rw-r--r--src/tools/clippy/tests/ui/wild_in_or_pats.stderr2
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.stderr2
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr2
-rw-r--r--src/tools/clippy/tests/ui/zero_div_zero.stderr2
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr2
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr2
-rw-r--r--src/tools/compiletest/src/main.rs5
-rw-r--r--src/tools/miri/src/lib.rs2
-rw-r--r--src/tools/miri/src/stacked_borrows/stack.rs2
-rw-r--r--src/tools/miri/tests/fail/erroneous_const2.stderr2
-rw-r--r--src/tools/remote-test-server/src/main.rs48
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs2
-rw-r--r--src/tools/tidy/src/deps.rs33
-rw-r--r--src/tools/tidy/src/features.rs4
1378 files changed, 16446 insertions, 10714 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index dc9abf84b8e..11335879bd4 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -23,65 +23,251 @@ The Rust Project includes packages written by third parties.
 The following third party packages are included, and carry
 their own copyright notices and license terms:
 
-* LLVM. Code for this package is found in src/llvm-project.
-
-    Copyright (c) 2003-2013 University of Illinois at
-    Urbana-Champaign.  All rights reserved.
-
-    Developed by:
-
-        LLVM Team
-
-        University of Illinois at Urbana-Champaign
-
-        http://llvm.org
-
-    Permission is hereby granted, free of charge, to any
-    person obtaining a copy of this software and associated
-    documentation files (the "Software"), to deal with the
-    Software without restriction, including without
-    limitation the rights to use, copy, modify, merge,
-    publish, distribute, sublicense, and/or sell copies of
-    the Software, and to permit persons to whom the Software
-    is furnished to do so, subject to the following
-    conditions:
-
-        * Redistributions of source code must retain the
-          above copyright notice, this list of conditions
-          and the following disclaimers.
-
-        * Redistributions in binary form must reproduce the
-          above copyright notice, this list of conditions
-          and the following disclaimers in the documentation
-          and/or other materials provided with the
-          distribution.
-
-        * Neither the names of the LLVM Team, University of
-          Illinois at Urbana-Champaign, nor the names of its
-          contributors may be used to endorse or promote
-          products derived from this Software without
-          specific prior written permission.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-    ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-    TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-    PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
-    SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE
-    FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-    OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-    OTHER DEALINGS WITH THE SOFTWARE.
-
-* Additional libraries included in LLVM carry separate
-  BSD-compatible licenses. See src/llvm-project/llvm/LICENSE.TXT
-  for details.
-
-* compiler-rt, in src/compiler-rt is dual licensed under
-  LLVM's license and MIT:
-
-    Copyright (c) 2009-2014 by the contributors listed in
-    CREDITS.TXT
-
+* LLVM, located in src/llvm-project, is licensed under the following
+  terms.
+
+    ==============================================================================
+    The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+    ==============================================================================
+
+                                    Apache License
+                              Version 2.0, January 2004
+                            http://www.apache.org/licenses/
+
+        TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+        1. Definitions.
+
+          "License" shall mean the terms and conditions for use, reproduction,
+          and distribution as defined by Sections 1 through 9 of this document.
+
+          "Licensor" shall mean the copyright owner or entity authorized by
+          the copyright owner that is granting the License.
+
+          "Legal Entity" shall mean the union of the acting entity and all
+          other entities that control, are controlled by, or are under common
+          control with that entity. For the purposes of this definition,
+          "control" means (i) the power, direct or indirect, to cause the
+          direction or management of such entity, whether by contract or
+          otherwise, or (ii) ownership of fifty percent (50%) or more of the
+          outstanding shares, or (iii) beneficial ownership of such entity.
+
+          "You" (or "Your") shall mean an individual or Legal Entity
+          exercising permissions granted by this License.
+
+          "Source" form shall mean the preferred form for making modifications,
+          including but not limited to software source code, documentation
+          source, and configuration files.
+
+          "Object" form shall mean any form resulting from mechanical
+          transformation or translation of a Source form, including but
+          not limited to compiled object code, generated documentation,
+          and conversions to other media types.
+
+          "Work" shall mean the work of authorship, whether in Source or
+          Object form, made available under the License, as indicated by a
+          copyright notice that is included in or attached to the work
+          (an example is provided in the Appendix below).
+
+          "Derivative Works" shall mean any work, whether in Source or Object
+          form, that is based on (or derived from) the Work and for which the
+          editorial revisions, annotations, elaborations, or other modifications
+          represent, as a whole, an original work of authorship. For the purposes
+          of this License, Derivative Works shall not include works that remain
+          separable from, or merely link (or bind by name) to the interfaces of,
+          the Work and Derivative Works thereof.
+
+          "Contribution" shall mean any work of authorship, including
+          the original version of the Work and any modifications or additions
+          to that Work or Derivative Works thereof, that is intentionally
+          submitted to Licensor for inclusion in the Work by the copyright owner
+          or by an individual or Legal Entity authorized to submit on behalf of
+          the copyright owner. For the purposes of this definition, "submitted"
+          means any form of electronic, verbal, or written communication sent
+          to the Licensor or its representatives, including but not limited to
+          communication on electronic mailing lists, source code control systems,
+          and issue tracking systems that are managed by, or on behalf of, the
+          Licensor for the purpose of discussing and improving the Work, but
+          excluding communication that is conspicuously marked or otherwise
+          designated in writing by the copyright owner as "Not a Contribution."
+
+          "Contributor" shall mean Licensor and any individual or Legal Entity
+          on behalf of whom a Contribution has been received by Licensor and
+          subsequently incorporated within the Work.
+
+        2. Grant of Copyright License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          copyright license to reproduce, prepare Derivative Works of,
+          publicly display, publicly perform, sublicense, and distribute the
+          Work and such Derivative Works in Source or Object form.
+
+        3. Grant of Patent License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          (except as stated in this section) patent license to make, have made,
+          use, offer to sell, sell, import, and otherwise transfer the Work,
+          where such license applies only to those patent claims licensable
+          by such Contributor that are necessarily infringed by their
+          Contribution(s) alone or by combination of their Contribution(s)
+          with the Work to which such Contribution(s) was submitted. If You
+          institute patent litigation against any entity (including a
+          cross-claim or counterclaim in a lawsuit) alleging that the Work
+          or a Contribution incorporated within the Work constitutes direct
+          or contributory patent infringement, then any patent licenses
+          granted to You under this License for that Work shall terminate
+          as of the date such litigation is filed.
+
+        4. Redistribution. You may reproduce and distribute copies of the
+          Work or Derivative Works thereof in any medium, with or without
+          modifications, and in Source or Object form, provided that You
+          meet the following conditions:
+
+          (a) You must give any other recipients of the Work or
+              Derivative Works a copy of this License; and
+
+          (b) You must cause any modified files to carry prominent notices
+              stating that You changed the files; and
+
+          (c) You must retain, in the Source form of any Derivative Works
+              that You distribute, all copyright, patent, trademark, and
+              attribution notices from the Source form of the Work,
+              excluding those notices that do not pertain to any part of
+              the Derivative Works; and
+
+          (d) If the Work includes a "NOTICE" text file as part of its
+              distribution, then any Derivative Works that You distribute must
+              include a readable copy of the attribution notices contained
+              within such NOTICE file, excluding those notices that do not
+              pertain to any part of the Derivative Works, in at least one
+              of the following places: within a NOTICE text file distributed
+              as part of the Derivative Works; within the Source form or
+              documentation, if provided along with the Derivative Works; or,
+              within a display generated by the Derivative Works, if and
+              wherever such third-party notices normally appear. The contents
+              of the NOTICE file are for informational purposes only and
+              do not modify the License. You may add Your own attribution
+              notices within Derivative Works that You distribute, alongside
+              or as an addendum to the NOTICE text from the Work, provided
+              that such additional attribution notices cannot be construed
+              as modifying the License.
+
+          You may add Your own copyright statement to Your modifications and
+          may provide additional or different license terms and conditions
+          for use, reproduction, or distribution of Your modifications, or
+          for any such Derivative Works as a whole, provided Your use,
+          reproduction, and distribution of the Work otherwise complies with
+          the conditions stated in this License.
+
+        5. Submission of Contributions. Unless You explicitly state otherwise,
+          any Contribution intentionally submitted for inclusion in the Work
+          by You to the Licensor shall be under the terms and conditions of
+          this License, without any additional terms or conditions.
+          Notwithstanding the above, nothing herein shall supersede or modify
+          the terms of any separate license agreement you may have executed
+          with Licensor regarding such Contributions.
+
+        6. Trademarks. This License does not grant permission to use the trade
+          names, trademarks, service marks, or product names of the Licensor,
+          except as required for reasonable and customary use in describing the
+          origin of the Work and reproducing the content of the NOTICE file.
+
+        7. Disclaimer of Warranty. Unless required by applicable law or
+          agreed to in writing, Licensor provides the Work (and each
+          Contributor provides its Contributions) on an "AS IS" BASIS,
+          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+          implied, including, without limitation, any warranties or conditions
+          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+          PARTICULAR PURPOSE. You are solely responsible for determining the
+          appropriateness of using or redistributing the Work and assume any
+          risks associated with Your exercise of permissions under this License.
+
+        8. Limitation of Liability. In no event and under no legal theory,
+          whether in tort (including negligence), contract, or otherwise,
+          unless required by applicable law (such as deliberate and grossly
+          negligent acts) or agreed to in writing, shall any Contributor be
+          liable to You for damages, including any direct, indirect, special,
+          incidental, or consequential damages of any character arising as a
+          result of this License or out of the use or inability to use the
+          Work (including but not limited to damages for loss of goodwill,
+          work stoppage, computer failure or malfunction, or any and all
+          other commercial damages or losses), even if such Contributor
+          has been advised of the possibility of such damages.
+
+        9. Accepting Warranty or Additional Liability. While redistributing
+          the Work or Derivative Works thereof, You may choose to offer,
+          and charge a fee for, acceptance of support, warranty, indemnity,
+          or other liability obligations and/or rights consistent with this
+          License. However, in accepting such obligations, You may act only
+          on Your own behalf and on Your sole responsibility, not on behalf
+          of any other Contributor, and only if You agree to indemnify,
+          defend, and hold each Contributor harmless for any liability
+          incurred by, or claims asserted against, such Contributor by reason
+          of your accepting any such warranty or additional liability.
+
+        END OF TERMS AND CONDITIONS
+
+        APPENDIX: How to apply the Apache License to your work.
+
+          To apply the Apache License to your work, attach the following
+          boilerplate notice, with the fields enclosed by brackets "[]"
+          replaced with your own identifying information. (Don't include
+          the brackets!)  The text should be enclosed in the appropriate
+          comment syntax for the file format. We also recommend that a
+          file or class name and description of purpose be included on the
+          same "printed page" as the copyright notice for easier
+          identification within third-party archives.
+
+        Copyright [yyyy] [name of copyright owner]
+
+        Licensed under the Apache License, Version 2.0 (the "License");
+        you may not use this file except in compliance with the License.
+        You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software
+        distributed under the License is distributed on an "AS IS" BASIS,
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions and
+        limitations under the License.
+
+
+    ---- LLVM Exceptions to the Apache 2.0 License ----
+
+    As an exception, if, as a result of your compiling your source code, portions
+    of this Software are embedded into an Object form of such source code, you
+    may redistribute such embedded portions in such Object form without complying
+    with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+    In addition, if you combine or link compiled forms of this Software with
+    software that is licensed under the GPLv2 ("Combined Software") and if a
+    court of competent jurisdiction determines that the patent provision (Section
+    3), the indemnity provision (Section 9) or other Section of the License
+    conflicts with the conditions of the GPLv2, you may retroactively and
+    prospectively choose to deem waived or otherwise exclude such Section(s) of
+    the License, but only in their entirety and only with respect to the Combined
+    Software.
+
+    ==============================================================================
+    Software from third parties included in the LLVM Project:
+    ==============================================================================
+    The LLVM Project contains third party software which is under different license
+    terms. All such code will be identified clearly using at least one of two
+    mechanisms:
+    1) It will be in a separate directory tree with its own `LICENSE.txt` or
+      `LICENSE` file at the top containing the specific license and restrictions
+      which apply to that software, or
+    2) It will contain specific license and restriction terms at the top of every
+      file.
+
+    ==============================================================================
+    Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
+    ==============================================================================
+    University of Illinois/NCSA
+    Open Source License
+
+    Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign.
     All rights reserved.
 
     Developed by:
@@ -92,70 +278,32 @@ their own copyright notices and license terms:
 
         http://llvm.org
 
-    Permission is hereby granted, free of charge, to any
-    person obtaining a copy of this software and associated
-    documentation files (the "Software"), to deal with the
-    Software without restriction, including without
-    limitation the rights to use, copy, modify, merge,
-    publish, distribute, sublicense, and/or sell copies of
-    the Software, and to permit persons to whom the Software
-    is furnished to do so, subject to the following
-    conditions:
-
-        * Redistributions of source code must retain the
-          above copyright notice, this list of conditions
-          and the following disclaimers.
-
-        * Redistributions in binary form must reproduce the
-          above copyright notice, this list of conditions
-          and the following disclaimers in the documentation
-          and/or other materials provided with the
-          distribution.
-
-        * Neither the names of the LLVM Team, University of
-          Illinois at Urbana-Champaign, nor the names of its
-          contributors may be used to endorse or promote
-          products derived from this Software without
-          specific prior written permission.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-    ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-    TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-    PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
-    SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE
-    FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-    OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-    OTHER DEALINGS WITH THE SOFTWARE.
-
-    ========================================================
-
-    Copyright (c) 2009-2014 by the contributors listed in
-    CREDITS.TXT
-
-    Permission is hereby granted, free of charge, to any
-    person obtaining a copy of this software and associated
-    documentation files (the "Software"), to deal in the
-    Software without restriction, including without
-    limitation the rights to use, copy, modify, merge,
-    publish, distribute, sublicense, and/or sell copies of
-    the Software, and to permit persons to whom the Software
-    is furnished to do so, subject to the following
-    conditions:
-
-    The above copyright notice and this permission notice
-    shall be included in all copies or substantial portions
-    of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-    ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-    TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-    PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-    SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-    IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-    DEALINGS IN THE SOFTWARE.
+    Permission is hereby granted, free of charge, to any person obtaining a copy of
+    this software and associated documentation files (the "Software"), to deal with
+    the Software without restriction, including without limitation the rights to
+    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is furnished to do
+    so, subject to the following conditions:
+
+        * Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimers.
+
+        * Redistributions in binary form must reproduce the above copyright notice,
+          this list of conditions and the following disclaimers in the
+          documentation and/or other materials provided with the distribution.
+
+        * Neither the names of the LLVM Team, University of Illinois at
+          Urbana-Champaign, nor the names of its contributors may be used to
+          endorse or promote products derived from this Software without specific
+          prior written permission.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+    CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+    SOFTWARE.
 
 * Portions of the FFI code for interacting with the native ABI
   is derived from the Clay programming language, which carries
@@ -191,41 +339,3 @@ their own copyright notices and license terms:
     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
     OF SUCH DAMAGE.
-
-* libbacktrace, under src/libbacktrace:
-
-    Copyright (C) 2012-2014 Free Software Foundation, Inc.
-    Written by Ian Lance Taylor, Google.
-
-    Redistribution and use in source and binary forms, with
-    or without modification, are permitted provided that the
-    following conditions are met:
-
-        (1) Redistributions of source code must retain the
-        above copyright notice, this list of conditions and
-        the following disclaimer.
-
-        (2) Redistributions in binary form must reproduce
-        the above copyright notice, this list of conditions
-        and the following disclaimer in the documentation
-        and/or other materials provided with the
-        distribution.
-
-        (3) The name of the author may not be used to
-        endorse or promote products derived from this
-        software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-    NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-    USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-    USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-    OF SUCH DAMAGE.  */
diff --git a/Cargo.lock b/Cargo.lock
index 6b2146ad3ed..072902f333d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -297,7 +297,7 @@ dependencies = [
  "cargo-test-macro",
  "cargo-test-support",
  "cargo-util",
- "clap",
+ "clap 4.0.9",
  "crates-io",
  "curl",
  "curl-sys",
@@ -591,7 +591,7 @@ dependencies = [
  "atty",
  "bitflags",
  "clap_derive",
- "clap_lex",
+ "clap_lex 0.2.2",
  "indexmap",
  "once_cell",
  "strsim",
@@ -600,12 +600,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "clap"
+version = "4.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30607dd93c420c6f1f80b544be522a0238a7db35e6a12968d28910983fee0df0"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_lex 0.3.0",
+ "strsim",
+ "termcolor",
+]
+
+[[package]]
 name = "clap_complete"
 version = "3.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25"
 dependencies = [
- "clap",
+ "clap 3.2.20",
 ]
 
 [[package]]
@@ -631,6 +644,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "clap_lex"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
 name = "clippy"
 version = "0.1.65"
 dependencies = [
@@ -664,7 +686,7 @@ name = "clippy_dev"
 version = "0.0.1"
 dependencies = [
  "aho-corasick",
- "clap",
+ "clap 3.2.20",
  "indoc",
  "itertools",
  "opener",
@@ -1809,7 +1831,7 @@ name = "installer"
 version = "0.0.0"
 dependencies = [
  "anyhow",
- "clap",
+ "clap 3.2.20",
  "flate2",
  "lazy_static",
  "num_cpus",
@@ -2152,7 +2174,7 @@ dependencies = [
  "ammonia",
  "anyhow",
  "chrono",
- "clap",
+ "clap 3.2.20",
  "clap_complete",
  "elasticlunr-rs",
  "env_logger 0.9.0",
@@ -3024,7 +3046,7 @@ dependencies = [
 name = "rustbook"
 version = "0.1.0"
 dependencies = [
- "clap",
+ "clap 3.2.20",
  "env_logger 0.7.1",
  "mdbook",
 ]
@@ -3111,7 +3133,7 @@ name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
  "bstr",
- "clap",
+ "clap 3.2.20",
  "libz-sys",
  "regex",
  "serde_json",
@@ -3297,6 +3319,7 @@ dependencies = [
  "rustc_symbol_mangling",
  "rustc_target",
  "smallvec",
+ "tempfile",
  "tracing",
 ]
 
@@ -3781,8 +3804,6 @@ dependencies = [
  "either",
  "gsgdt",
  "polonius-engine",
- "rand 0.8.5",
- "rand_xoshiro",
  "rustc-rayon",
  "rustc-rayon-core",
  "rustc_apfloat",
@@ -4228,6 +4249,8 @@ dependencies = [
 name = "rustc_ty_utils"
 version = "0.0.0"
 dependencies = [
+ "rand 0.8.5",
+ "rand_xoshiro",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_hir",
@@ -4338,7 +4361,7 @@ dependencies = [
  "anyhow",
  "bytecount",
  "cargo_metadata 0.14.0",
- "clap",
+ "clap 3.2.20",
  "derive-new",
  "diff",
  "dirs",
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index fa6162c5184..16224d71e45 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -256,10 +256,6 @@ pub enum TokenKind {
     Eof,
 }
 
-// `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(TokenKind, 16);
-
 #[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct Token {
     pub kind: TokenKind,
@@ -349,17 +345,14 @@ impl Token {
     }
 
     pub fn is_op(&self) -> bool {
-        !matches!(
-            self.kind,
-            OpenDelim(..)
-                | CloseDelim(..)
-                | Literal(..)
-                | DocComment(..)
-                | Ident(..)
-                | Lifetime(..)
-                | Interpolated(..)
-                | Eof
-        )
+        match self.kind {
+            Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_)
+            | BinOpEq(_) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon
+            | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true,
+
+            OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)
+            | Lifetime(..) | Interpolated(..) | Eof => false,
+        }
     }
 
     pub fn is_like_plus(&self) -> bool {
@@ -728,6 +721,7 @@ impl Token {
 }
 
 impl PartialEq<TokenKind> for Token {
+    #[inline]
     fn eq(&self, rhs: &TokenKind) -> bool {
         self.kind == *rhs
     }
@@ -751,10 +745,6 @@ pub enum Nonterminal {
     NtVis(P<ast::Visibility>),
 }
 
-// `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Nonterminal, 16);
-
 #[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
 pub enum NonterminalKind {
     Item,
@@ -893,3 +883,16 @@ where
         panic!("interpolated tokens should not be present in the HIR")
     }
 }
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+    use super::*;
+    use rustc_data_structures::static_assert_size;
+    // These are in alphabetical order, which is easy to maintain.
+    static_assert_size!(Lit, 12);
+    static_assert_size!(LitKind, 2);
+    static_assert_size!(Nonterminal, 16);
+    static_assert_size!(Token, 24);
+    static_assert_size!(TokenKind, 16);
+}
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 875cd620dfc..4d2049cbc41 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -47,10 +47,6 @@ pub enum TokenTree {
     Delimited(DelimSpan, Delimiter, TokenStream),
 }
 
-// This type is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(TokenTree, 32);
-
 // Ensure all fields of `TokenTree` is `Send` and `Sync`.
 #[cfg(parallel_compiler)]
 fn _dummy()
@@ -308,13 +304,20 @@ pub struct AttributesData {
 #[derive(Clone, Debug, Default, Encodable, Decodable)]
 pub struct TokenStream(pub(crate) Lrc<Vec<TokenTree>>);
 
-// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(TokenStream, 8);
-
+/// Similar to `proc_macro::Spacing`, but for tokens.
+///
+/// Note that all `ast::TokenTree::Token` instances have a `Spacing`, but when
+/// we convert to `proc_macro::TokenTree` for proc macros only `Punct`
+/// `TokenTree`s have a `proc_macro::Spacing`.
 #[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum Spacing {
+    /// The token is not immediately followed by an operator token (as
+    /// determined by `Token::is_op`). E.g. a `+` token is `Alone` in `+ =`,
+    /// `+/*foo*/=`, `+ident`, and `+()`.
     Alone,
+
+    /// The token is immediately followed by an operator token. E.g. a `+`
+    /// token is `Joint` in `+=` and `++`.
     Joint,
 }
 
@@ -664,3 +667,16 @@ impl DelimSpan {
         self.open.with_hi(self.close.hi())
     }
 }
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+    use super::*;
+    use rustc_data_structures::static_assert_size;
+    // These are in alphabetical order, which is easy to maintain.
+    static_assert_size!(AttrTokenStream, 8);
+    static_assert_size!(AttrTokenTree, 32);
+    static_assert_size!(LazyAttrTokenStream, 8);
+    static_assert_size!(TokenStream, 8);
+    static_assert_size!(TokenTree, 32);
+}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index d9b18d68e53..9a46444d823 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1478,6 +1478,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let bounded_ty =
                     self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
                 Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+                    hir_id: self.next_id(),
                     bounded_ty: self.arena.alloc(bounded_ty),
                     bounds,
                     span,
@@ -1508,6 +1509,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ref bounds,
                 span,
             }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+                hir_id: self.next_id(),
                 bound_generic_params: self.lower_generic_params(bound_generic_params),
                 bounded_ty: self
                     .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 275ceed30d7..8281164ab12 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -61,8 +61,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::parse::feature_err;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::DesugaringKind;
@@ -1060,13 +1060,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
                     // constructing the HIR for `impl bounds...` and then lowering that.
 
-                    let parent_def_id = self.current_hir_id_owner;
                     let impl_trait_node_id = self.next_node_id();
-                    self.create_def(
-                        parent_def_id.def_id,
-                        impl_trait_node_id,
-                        DefPathData::ImplTrait,
-                    );
 
                     self.with_dyn_type_scope(false, |this| {
                         let node_id = this.next_node_id();
@@ -1357,9 +1351,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         def_node_id,
                         bounds,
                         false,
-                        &ImplTraitContext::TypeAliasesOpaqueTy,
+                        itctx,
                     ),
                     ImplTraitContext::Universal => {
+                        self.create_def(
+                            self.current_hir_id_owner.def_id,
+                            def_node_id,
+                            DefPathData::ImplTrait,
+                        );
                         let span = t.span;
                         let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
                         let (param, bounds, path) =
@@ -1453,7 +1452,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // frequently opened issues show.
         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
 
-        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
+        let opaque_ty_def_id = match origin {
+            hir::OpaqueTyOrigin::TyAlias => self.create_def(
+                self.current_hir_id_owner.def_id,
+                opaque_ty_node_id,
+                DefPathData::ImplTrait,
+            ),
+            hir::OpaqueTyOrigin::FnReturn(fn_def_id) => {
+                self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait)
+            }
+            hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"),
+        };
         debug!(?opaque_ty_def_id);
 
         // Contains the new lifetime definitions created for the TAIT (if any).
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 419e6c81791..4d251cf7ac7 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -864,15 +864,13 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         };
 
         let tcx = self.infcx.tcx;
-        let body_parent_did = tcx.opt_parent(self.mir_def_id().to_def_id())?;
-        if tcx.parent(region.def_id) != body_parent_did
-            || tcx.def_kind(body_parent_did) != DefKind::Impl
-        {
+        let region_parent = tcx.parent(region.def_id);
+        if tcx.def_kind(region_parent) != DefKind::Impl {
             return None;
         }
 
         let mut found = false;
-        tcx.fold_regions(tcx.type_of(body_parent_did), |r: ty::Region<'tcx>, _| {
+        tcx.fold_regions(tcx.type_of(region_parent), |r: ty::Region<'tcx>, _| {
             if *r == ty::ReEarlyBound(region) {
                 found = true;
             }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index d03f0369648..28ed88e8345 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -236,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
                 .unwrap();
             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_infer_types_or_consts() {
+            if hidden_type.has_non_region_infer() {
                 infcx.tcx.sess.delay_span_bug(
                     decl.hidden_type.span,
                     &format!("could not resolve {:#?}", hidden_type.ty.kind()),
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 77e0b6c55a8..7bd344467d0 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -16,6 +16,7 @@ pub fn expand_deriving_copy(
     let trait_def = TraitDef {
         span,
         path: path_std!(marker::Copy),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index c7f2d95e72f..fa8685f5f4e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -72,6 +72,7 @@ pub fn expand_deriving_clone(
     let trait_def = TraitDef {
         span,
         path: path_std!(clone::Clone),
+        skip_path_as_bound: false,
         additional_bounds: bounds,
         generics: Bounds::empty(),
         supports_unions: true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 5b556c5c9b9..eab67b0d354 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -25,6 +25,7 @@ pub fn expand_deriving_eq(
     let trait_def = TraitDef {
         span,
         path: path_std!(cmp::Eq),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 72625869558..7f117981a9a 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -19,6 +19,7 @@ pub fn expand_deriving_ord(
     let trait_def = TraitDef {
         span,
         path: path_std!(cmp::Ord),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 42ee65b570a..236cbccaf9f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -83,6 +83,7 @@ pub fn expand_deriving_partial_eq(
     let trait_def = TraitDef {
         span,
         path: path_std!(cmp::PartialEq),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 516892aeda9..4173403a1b8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -37,6 +37,7 @@ pub fn expand_deriving_partial_ord(
     let trait_def = TraitDef {
         span,
         path: path_std!(cmp::PartialOrd),
+        skip_path_as_bound: false,
         additional_bounds: vec![],
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 4af7fd81653..2cf614ed947 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -20,6 +20,7 @@ pub fn expand_deriving_debug(
     let trait_def = TraitDef {
         span,
         path: path_std!(fmt::Debug),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index 7174dbbe7ea..d669f616802 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -23,6 +23,7 @@ pub fn expand_deriving_rustc_decodable(
     let trait_def = TraitDef {
         span,
         path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index a94c8a996e6..17df9fb279a 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -24,6 +24,7 @@ pub fn expand_deriving_default(
     let trait_def = TraitDef {
         span,
         path: Path::new(vec![kw::Default, sym::Default]),
+        skip_path_as_bound: has_a_default_variant(item),
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
@@ -262,3 +263,22 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
         }
     }
 }
+
+fn has_a_default_variant(item: &Annotatable) -> bool {
+    struct HasDefaultAttrOnVariant {
+        found: bool,
+    }
+
+    impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant {
+        fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) {
+            if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
+                self.found = true;
+            }
+            // no need to subrecurse.
+        }
+    }
+
+    let mut visitor = HasDefaultAttrOnVariant { found: false };
+    item.visit_with(&mut visitor);
+    visitor.found
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index b220e54238f..f83f58b97d3 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -107,6 +107,7 @@ pub fn expand_deriving_rustc_encodable(
     let trait_def = TraitDef {
         span,
         path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 3cc160adb53..6fbd99b5c71 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -174,6 +174,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use std::cell::RefCell;
 use std::iter;
+use std::ops::Not;
 use std::vec;
 use thin_vec::thin_vec;
 use ty::{Bounds, Path, Ref, Self_, Ty};
@@ -187,6 +188,9 @@ pub struct TraitDef<'a> {
     /// Path of the trait, including any type parameters
     pub path: Path,
 
+    /// Whether to skip adding the current trait as a bound to the type parameters of the type.
+    pub skip_path_as_bound: bool,
+
     /// Additional bounds required of any type parameters of the type,
     /// other than the current trait
     pub additional_bounds: Vec<Ty>,
@@ -596,7 +600,7 @@ impl<'a> TraitDef<'a> {
                         cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
                     }).chain(
                         // require the current trait
-                        iter::once(cx.trait_bound(trait_path.clone()))
+                        self.skip_path_as_bound.not().then(|| cx.trait_bound(trait_path.clone()))
                     ).chain(
                         // also add in any bounds from the declaration
                         param.bounds.iter().cloned()
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index f1f02e7ce77..6e9d5f08b94 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -22,6 +22,7 @@ pub fn expand_deriving_hash(
     let hash_trait_def = TraitDef {
         span,
         path,
+        skip_path_as_bound: false,
         additional_bounds: Vec::new(),
         generics: Bounds::empty(),
         supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index b15e2d084ef..8b07c110663 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -159,7 +159,7 @@ pub fn make_format_args(
     append_newline: bool,
 ) -> Result<FormatArgs, ()> {
     let msg = "format argument must be a string literal";
-    let fmt_span = efmt.span;
+    let unexpanded_fmt_span = efmt.span;
     let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) {
         Ok(mut fmt) if append_newline => {
             fmt.0 = Symbol::intern(&format!("{}\n", fmt.0));
@@ -174,7 +174,7 @@ pub fn make_format_args(
                 };
                 if !suggested {
                     err.span_suggestion(
-                        fmt_span.shrink_to_lo(),
+                        unexpanded_fmt_span.shrink_to_lo(),
                         "you might be missing a string literal to format with",
                         format!("\"{}\", ", sugg_fmt),
                         Applicability::MaybeIncorrect,
@@ -192,7 +192,7 @@ pub fn make_format_args(
     };
 
     let fmt_str = fmt_str.as_str(); // for the suggestions below
-    let fmt_snippet = ecx.source_map().span_to_snippet(fmt_span).ok();
+    let fmt_snippet = ecx.source_map().span_to_snippet(unexpanded_fmt_span).ok();
     let mut parser = parse::Parser::new(
         fmt_str,
         str_style,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index f058503064b..c7ea7de8f4e 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -7,7 +7,7 @@
 #![feature(box_patterns)]
 #![feature(decl_macro)]
 #![feature(if_let_guard)]
-#![feature(is_some_with)]
+#![feature(is_some_and)]
 #![feature(is_sorted)]
 #![feature(let_chains)]
 #![feature(proc_macro_internals)]
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 7efb6cc61ee..705141614e2 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -115,7 +115,7 @@ pub fn expand_test_or_bench(
             // reworked in the future to not need it, it'd be nice.
             _ => diag.struct_span_err(attr_sp, msg).forget_guarantee(),
         };
-        err.span_label(attr_sp, "the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions")
+        err.span_label(attr_sp, "the `#[test]` macro causes a function to be run on a test and has no effect on non-functions")
             .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr()))
             .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", "#[cfg(test)]", Applicability::MaybeIncorrect)
             .emit();
diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs
index 848c34211ff..6fb1cbfad8c 100644
--- a/compiler/rustc_codegen_gcc/src/abi.rs
+++ b/compiler/rustc_codegen_gcc/src/abi.rs
@@ -11,10 +11,6 @@ use crate::intrinsic::ArgAbiExt;
 use crate::type_of::LayoutGccExt;
 
 impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
-    fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) {
-        // TODO(antoyo)
-    }
-
     fn get_param(&mut self, index: usize) -> Self::Value {
         let func = self.current_func();
         let param = func.get_param(index as i32);
diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs
index f863abdcc97..ac0342f6b80 100644
--- a/compiler/rustc_codegen_gcc/src/archive.rs
+++ b/compiler/rustc_codegen_gcc/src/archive.rs
@@ -1,6 +1,8 @@
 use std::fs::File;
 use std::path::{Path, PathBuf};
 
+use crate::errors::RanlibFailure;
+
 use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
 use rustc_session::Session;
 
@@ -181,7 +183,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             std::process::Command::new("ranlib").arg(output).status().expect("Couldn't run ranlib");
 
         if !status.success() {
-            self.config.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
+            self.config.sess.emit_fatal(RanlibFailure::new(status.code()));
         }
 
         any_members
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 52fd66af065..c346dbd63cc 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -12,6 +12,7 @@ use std::borrow::Cow;
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
+use crate::errors::UnwindingInlineAsm;
 use crate::type_of::LayoutGccExt;
 use crate::callee::get_fn;
 
@@ -109,7 +110,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
     fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) {
         if options.contains(InlineAsmOptions::MAY_UNWIND) {
             self.sess()
-                .struct_span_err(span[0], "GCC backend does not support unwinding from inline asm")
+                .create_err(UnwindingInlineAsm { span: span[0] })
                 .emit();
             return;
         }
@@ -497,7 +498,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
         if options.contains(InlineAsmOptions::NORETURN) {
             let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable");
             let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) };
-            self.call(self.type_void(), builtin_unreachable, &[], None);
+            self.call(self.type_void(), None, builtin_unreachable, &[], None);
         }
 
         // Write results to outputs.
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 6994eeb00c3..a314b7cc215 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -444,11 +444,23 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         self.block.end_with_switch(None, value, default_block, &gcc_cases);
     }
 
-    fn invoke(&mut self, typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> {
+    fn invoke(
+        &mut self,
+        typ: Type<'gcc>,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
+        func: RValue<'gcc>,
+        args: &[RValue<'gcc>],
+        then: Block<'gcc>,
+        catch: Block<'gcc>,
+        _funclet: Option<&Funclet>,
+    ) -> RValue<'gcc> {
         // TODO(bjorn3): Properly implement unwinding.
-        let call_site = self.call(typ, func, args, None);
+        let call_site = self.call(typ, None, func, args, None);
         let condition = self.context.new_rvalue_from_int(self.bool_type, 1);
         self.llbb().end_with_conditional(None, condition, then, catch);
+        if let Some(_fn_abi) = fn_abi {
+            // TODO(bjorn3): Apply function attributes
+        }
         call_site
     }
 
@@ -643,11 +655,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         self.current_func().new_local(None, aligned_type, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None)
     }
 
-    fn dynamic_alloca(&mut self, _ty: Type<'gcc>, _align: Align) -> RValue<'gcc> {
-        unimplemented!();
-    }
-
-    fn array_alloca(&mut self, _ty: Type<'gcc>, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> {
+    fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> {
         unimplemented!();
     }
 
@@ -1227,16 +1235,27 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         // TODO(antoyo)
     }
 
-    fn call(&mut self, _typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>) -> RValue<'gcc> {
+    fn call(
+        &mut self,
+        _typ: Type<'gcc>,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
+        func: RValue<'gcc>,
+        args: &[RValue<'gcc>],
+        funclet: Option<&Funclet>,
+    ) -> RValue<'gcc> {
         // FIXME(antoyo): remove when having a proper API.
         let gcc_func = unsafe { std::mem::transmute(func) };
-        if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() {
+        let call = if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() {
             self.function_call(func, args, funclet)
         }
         else {
             // If it's a not function that was defined, it's a function pointer.
             self.function_ptr_call(func, args, funclet)
+        };
+        if let Some(_fn_abi) = fn_abi {
+            // TODO(bjorn3): Apply function attributes
         }
+        call
     }
 
     fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index 356c03ee3c1..81f53328867 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -14,6 +14,7 @@ use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRan
 
 use crate::base;
 use crate::context::CodegenCx;
+use crate::errors::LinkageConstOrMutType;
 use crate::type_of::LayoutGccExt;
 
 impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
@@ -368,10 +369,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &Codeg
                 cx.layout_of(mt.ty).gcc_type(cx, true)
             }
             else {
-                cx.sess().span_fatal(
-                    span,
-                    "must have type `*const T` or `*mut T` due to `#[linkage]` attribute",
-                )
+                cx.sess().emit_fatal(LinkageConstOrMutType { span: span })
             };
         // Declare a symbol `foo` with the desired linkage.
         let global1 = cx.declare_global_with_linkage(&sym, llty2, base::global_linkage_to_gcc(linkage));
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 478f6d893dd..62a61eb8548 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -13,7 +13,7 @@ use rustc_middle::mir::mono::CodegenUnit;
 use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
 use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, TyAndLayout, LayoutOfHelpers};
 use rustc_session::Session;
-use rustc_span::Span;
+use rustc_span::{Span, source_map::respan};
 use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
 use rustc_target::spec::{HasTargetSpec, Target, TlsModel};
 
@@ -293,7 +293,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
         self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ.is_compatible_with(self.bool_type)
     }
 
-    pub fn sess(&self) -> &Session {
+    pub fn sess(&self) -> &'tcx Session {
         &self.tcx.sess
     }
 
@@ -416,10 +416,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         self.codegen_unit
     }
 
-    fn used_statics(&self) -> &RefCell<Vec<RValue<'gcc>>> {
-        unimplemented!();
-    }
-
     fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) {
         // TODO(antoyo)
     }
@@ -428,10 +424,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         // TODO(antoyo)
     }
 
-    fn create_used_variable(&self) {
-        unimplemented!();
-    }
-
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
         if self.get_declared_value("main").is_none() {
             Some(self.declare_cfn("main", fn_type))
@@ -443,14 +435,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
             None
         }
     }
-
-    fn compiler_used_statics(&self) -> &RefCell<Vec<RValue<'gcc>>> {
-        unimplemented!()
-    }
-
-    fn create_compiler_used_variable(&self) {
-        unimplemented!()
-    }
 }
 
 impl<'gcc, 'tcx> HasTyCtxt<'tcx> for CodegenCx<'gcc, 'tcx> {
@@ -477,7 +461,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         if let LayoutError::SizeOverflow(_) = err {
-            self.sess().span_fatal(span, &err.to_string())
+            self.sess().emit_fatal(respan(span, err))
         } else {
             span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
         }
@@ -495,7 +479,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
         fn_abi_request: FnAbiRequest<'tcx>,
     ) -> ! {
         if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
-            self.sess().span_fatal(span, &err.to_string())
+            self.sess().emit_fatal(respan(span, err))
         } else {
             match fn_abi_request {
                 FnAbiRequest::OfFnPtr { sig, extra_args } => {
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
new file mode 100644
index 00000000000..d7816e395c8
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -0,0 +1,242 @@
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
+use rustc_macros::Diagnostic;
+use rustc_middle::ty::Ty;
+use rustc_span::{Span, Symbol};
+use std::borrow::Cow;
+
+struct ExitCode(Option<i32>);
+
+impl IntoDiagnosticArg for ExitCode {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        let ExitCode(exit_code) = self;
+        match exit_code {
+            Some(t) => t.into_diagnostic_arg(),
+            None => DiagnosticArgValue::Str(Cow::Borrowed("<signal>")),
+        }
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::ranlib_failure)]
+pub(crate) struct RanlibFailure {
+    exit_code: ExitCode,
+}
+
+impl RanlibFailure {
+    pub fn new(exit_code: Option<i32>) -> Self {
+        RanlibFailure { exit_code: ExitCode(exit_code) }
+    }
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_basic_integer, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationBasicInteger<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_invalid_float_vector, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationInvalidFloatVector<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub elem_ty: &'a str,
+    pub vec_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_not_float, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationNotFloat<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_unrecognized, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationUnrecognized {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_expected_signed_unsigned, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationExpectedSignedUnsigned<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub elem_ty: Ty<'a>,
+    pub vec_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_unsupported_element, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationUnsupportedElement<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_ty: Ty<'a>,
+    pub elem_ty: Ty<'a>,
+    pub ret_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_invalid_bitmask, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationInvalidBitmask<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ty: Ty<'a>,
+    pub expected_int_bits: u64,
+    pub expected_bytes: u64,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_simd_shuffle, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationSimdShuffle<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_expected_simd, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationExpectedSimd<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub position: &'a str,
+    pub found_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_mask_type, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationMaskType<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_return_length, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationReturnLength<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_len: u64,
+    pub ret_ty: Ty<'a>,
+    pub out_len: u64,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_return_length_input_type, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationReturnLengthInputType<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_len: u64,
+    pub in_ty: Ty<'a>,
+    pub ret_ty: Ty<'a>,
+    pub out_len: u64,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_return_element, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationReturnElement<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_elem: Ty<'a>,
+    pub in_ty: Ty<'a>,
+    pub ret_ty: Ty<'a>,
+    pub out_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_return_type, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationReturnType<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_elem: Ty<'a>,
+    pub in_ty: Ty<'a>,
+    pub ret_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_inserted_type, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationInsertedType<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_elem: Ty<'a>,
+    pub in_ty: Ty<'a>,
+    pub out_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_return_integer_type, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationReturnIntegerType<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ret_ty: Ty<'a>,
+    pub out_ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_mismatched_lengths, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationMismatchedLengths {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub m_len: u64,
+    pub v_len: u64,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_unsupported_cast, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationUnsupportedCast<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_ty: Ty<'a>,
+    pub in_elem: Ty<'a>,
+    pub ret_ty: Ty<'a>,
+    pub out_elem: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::invalid_monomorphization_unsupported_operation, code = "E0511")]
+pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub in_ty: Ty<'a>,
+    pub in_elem: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::linkage_const_or_mut_type)]
+pub(crate) struct LinkageConstOrMutType {
+    #[primary_span]
+    pub span: Span
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::lto_not_supported)]
+pub(crate) struct LTONotSupported;
+
+#[derive(Diagnostic)]
+#[diag(codegen_gcc::unwinding_inline_asm)]
+pub(crate) struct UnwindingInlineAsm {
+    #[primary_span]
+    pub span: Span
+}
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 02cedd4646b..49be6c649e6 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -4,7 +4,7 @@ mod simd;
 use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp, FunctionType};
 use rustc_codegen_ssa::MemFlags;
 use rustc_codegen_ssa::base::wants_msvc_seh;
-use rustc_codegen_ssa::common::{IntPredicate, span_invalid_monomorphization_error};
+use rustc_codegen_ssa::common::IntPredicate;
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::{ArgAbiMethods, BaseTypeMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods};
@@ -20,6 +20,7 @@ use crate::abi::GccType;
 use crate::builder::Builder;
 use crate::common::{SignType, TypeReflection};
 use crate::context::CodegenCx;
+use crate::errors::InvalidMonomorphizationBasicInteger;
 use crate::type_of::LayoutGccExt;
 use crate::intrinsic::simd::generic_simd_intrinsic;
 
@@ -99,7 +100,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                 _ if simple.is_some() => {
                     // FIXME(antoyo): remove this cast when the API supports function.
                     let func = unsafe { std::mem::transmute(simple.expect("simple")) };
-                    self.call(self.type_void(), func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None)
+                    self.call(self.type_void(), None, func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None)
                 },
                 sym::likely => {
                     self.expect(args[0].immediate(), true)
@@ -242,15 +243,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                                 _ => bug!(),
                             },
                             None => {
-                                span_invalid_monomorphization_error(
-                                    tcx.sess,
-                                    span,
-                                    &format!(
-                                        "invalid monomorphization of `{}` intrinsic: \
-                                      expected basic integer type, found `{}`",
-                                      name, ty
-                                    ),
-                                );
+                                tcx.sess.emit_err(InvalidMonomorphizationBasicInteger { span, name, ty });
                                 return;
                             }
                         }
@@ -348,7 +341,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
     fn abort(&mut self) {
         let func = self.context.get_builtin_function("abort");
         let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
-        self.call(self.type_void(), func, &[], None);
+        self.call(self.type_void(), None, func, &[], None);
     }
 
     fn assume(&mut self, value: Self::Value) {
@@ -1131,7 +1124,7 @@ fn try_intrinsic<'gcc, 'tcx>(bx: &mut Builder<'_, 'gcc, 'tcx>, try_func: RValue<
     // NOTE: the `|| true` here is to use the panic=abort strategy with panic=unwind too
     if bx.sess().panic_strategy() == PanicStrategy::Abort || true {
         // TODO(bjorn3): Properly implement unwinding and remove the `|| true` once this is done.
-        bx.call(bx.type_void(), try_func, &[data], None);
+        bx.call(bx.type_void(), None, try_func, &[data], None);
         // Return 0 unconditionally from the intrinsic call;
         // we can never unwind.
         let ret_align = bx.tcx.data_layout.i32_align.abi;
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 2401f335018..12e416f62a4 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -2,7 +2,7 @@ use std::cmp::Ordering;
 
 use gccjit::{BinaryOp, RValue, Type, ToRValue};
 use rustc_codegen_ssa::base::compare_simd_types;
-use rustc_codegen_ssa::common::{TypeKind, span_invalid_monomorphization_error};
+use rustc_codegen_ssa::common::TypeKind;
 use rustc_codegen_ssa::mir::operand::OperandRef;
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
@@ -14,43 +14,48 @@ use rustc_span::{Span, Symbol, sym};
 use rustc_target::abi::Align;
 
 use crate::builder::Builder;
+use crate::errors::{
+    InvalidMonomorphizationInvalidFloatVector,
+    InvalidMonomorphizationNotFloat,
+    InvalidMonomorphizationUnrecognized,
+    InvalidMonomorphizationExpectedSignedUnsigned,
+    InvalidMonomorphizationUnsupportedElement,
+    InvalidMonomorphizationInvalidBitmask,
+    InvalidMonomorphizationSimdShuffle,
+    InvalidMonomorphizationExpectedSimd,
+    InvalidMonomorphizationMaskType,
+    InvalidMonomorphizationReturnLength,
+    InvalidMonomorphizationReturnLengthInputType,
+    InvalidMonomorphizationReturnElement,
+    InvalidMonomorphizationReturnType,
+    InvalidMonomorphizationInsertedType,
+    InvalidMonomorphizationReturnIntegerType,
+    InvalidMonomorphizationMismatchedLengths,
+    InvalidMonomorphizationUnsupportedCast,
+    InvalidMonomorphizationUnsupportedOperation
+};
 use crate::intrinsic;
 
 pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result<RValue<'gcc>, ()> {
     // macros for error handling:
-    #[allow(unused_macro_rules)]
-    macro_rules! emit_error {
-        ($msg: tt) => {
-            emit_error!($msg, )
-        };
-        ($msg: tt, $($fmt: tt)*) => {
-            span_invalid_monomorphization_error(
-                bx.sess(), span,
-                &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
-                         name, $($fmt)*));
-        }
-    }
-
     macro_rules! return_error {
-        ($($fmt: tt)*) => {
+        ($err:expr) => {
             {
-                emit_error!($($fmt)*);
+                bx.sess().emit_err($err);
                 return Err(());
             }
         }
     }
-
     macro_rules! require {
-        ($cond: expr, $($fmt: tt)*) => {
+        ($cond:expr, $err:expr) => {
             if !$cond {
-                return_error!($($fmt)*);
+                return_error!($err);
             }
-        };
+        }
     }
-
     macro_rules! require_simd {
         ($ty: expr, $position: expr) => {
-            require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty)
+            require!($ty.is_simd(), InvalidMonomorphizationExpectedSimd { span, name, position: $position, found_ty: $ty })
         };
     }
 
@@ -82,10 +87,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                 bx.load(int_ty, ptr, Align::ONE)
             }
             _ => return_error!(
-                "invalid bitmask `{}`, expected `u{}` or `[u8; {}]`",
-                mask_ty,
-                expected_int_bits,
-                expected_bytes
+                InvalidMonomorphizationInvalidBitmask { span, name, ty: mask_ty, expected_int_bits, expected_bytes }
             ),
         };
 
@@ -127,18 +129,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
         require!(
             in_len == out_len,
-            "expected return type with length {} (same as input type `{}`), \
-             found `{}` with length {}",
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
+            InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len }
         );
         require!(
             bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
-            "expected return type with integer elements, found `{}` with non-integer `{}`",
-            ret_ty,
-            out_ty
+            InvalidMonomorphizationReturnIntegerType {span, name, ret_ty, out_ty}
         );
 
         return Ok(compare_simd_types(
@@ -163,8 +158,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                         })
                     }
                     _ => return_error!(
-                        "simd_shuffle index must be an array of `u32`, got `{}`",
-                        args[2].layout.ty
+                        InvalidMonomorphizationSimdShuffle { span, name, ty: args[2].layout.ty }
                     ),
                 }
             }
@@ -179,19 +173,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
         require!(
             out_len == n,
-            "expected return type of length {}, found `{}` with length {}",
-            n,
-            ret_ty,
-            out_len
+            InvalidMonomorphizationReturnLength { span, name, in_len: n, ret_ty, out_len }
         );
         require!(
             in_elem == out_ty,
-            "expected return element type `{}` (element of input `{}`), \
-             found `{}` with element type `{}`",
-            in_elem,
-            in_ty,
-            ret_ty,
-            out_ty
+            InvalidMonomorphizationReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
         );
 
         let vector = args[2].immediate();
@@ -207,10 +193,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
     if name == sym::simd_insert {
         require!(
             in_elem == arg_tys[2],
-            "expected inserted type `{}` (element of input `{}`), found `{}`",
-            in_elem,
-            in_ty,
-            arg_tys[2]
+            InvalidMonomorphizationInsertedType { span, name, in_elem, in_ty, out_ty: arg_tys[2] }
         );
         let vector = args[0].immediate();
         let index = args[1].immediate();
@@ -263,10 +246,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
     if name == sym::simd_extract {
         require!(
             ret_ty == in_elem,
-            "expected return type `{}` (element of input `{}`), found `{}`",
-            in_elem,
-            in_ty,
-            ret_ty
+            InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
         );
         let vector = args[0].immediate();
         return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
@@ -279,13 +259,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
         let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
         require!(
             m_len == v_len,
-            "mismatched lengths: mask length `{}` != other vector length `{}`",
-            m_len,
-            v_len
+            InvalidMonomorphizationMismatchedLengths { span, name, m_len, v_len }
         );
         match m_elem_ty.kind() {
             ty::Int(_) => {}
-            _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty),
+            _ => return_error!(InvalidMonomorphizationMaskType { span, name, ty: m_elem_ty }),
         }
         return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate()));
     }
@@ -295,12 +273,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
         let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
         require!(
             in_len == out_len,
-            "expected return type with length {} (same as input type `{}`), \
-                  found `{}` with length {}",
-            in_len,
-            in_ty,
-            ret_ty,
-            out_len
+            InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len }
         );
         // casting cares about nominal type, not just structural type
         if in_elem == out_elem {
@@ -412,13 +385,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
             }
             _ => { /* Unsupported. Fallthrough. */ }
         }
-        require!(
-            false,
-            "unsupported cast from `{}` with element `{}` to `{}` with element `{}`",
-            in_ty,
-            in_elem,
-            ret_ty,
-            out_elem
+        return_error!(
+            InvalidMonomorphizationUnsupportedCast { span, name, in_ty, in_elem, ret_ty, out_elem }
         );
     }
 
@@ -431,10 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                     })*
                     _ => {},
                 }
-                require!(false,
-                         "unsupported operation on `{}` with element `{}`",
-                         in_ty,
-                         in_elem)
+                return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem })
             })*
         }
     }
@@ -448,23 +413,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
         span: Span,
         args: &[OperandRef<'tcx, RValue<'gcc>>],
     ) -> Result<RValue<'gcc>, ()> {
-        macro_rules! emit_error {
-            ($msg: tt, $($fmt: tt)*) => {
-                span_invalid_monomorphization_error(
-                    bx.sess(), span,
-                    &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
-                             name, $($fmt)*));
-            }
-        }
         macro_rules! return_error {
-            ($($fmt: tt)*) => {
+            ($err:expr) => {
                 {
-                    emit_error!($($fmt)*);
+                    bx.sess().emit_err($err);
                     return Err(());
                 }
             }
         }
-
         let (elem_ty_str, elem_ty) =
             if let ty::Float(f) = in_elem.kind() {
                 let elem_ty = bx.cx.type_float_from_ty(*f);
@@ -472,16 +428,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                     32 => ("f32", elem_ty),
                     64 => ("f64", elem_ty),
                     _ => {
-                        return_error!(
-                            "unsupported element type `{}` of floating-point vector `{}`",
-                            f.name_str(),
-                            in_ty
-                        );
+                        return_error!(InvalidMonomorphizationInvalidFloatVector { span, name, elem_ty: f.name_str(), vec_ty: in_ty });
                     }
                 }
             }
             else {
-                return_error!("`{}` is not a floating-point type", in_ty);
+                return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty });
             };
 
         let vec_ty = bx.cx.type_vector(elem_ty, in_len);
@@ -504,12 +456,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                 sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
                 sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
                 sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
-                _ => return_error!("unrecognized intrinsic `{}`", name),
+                _ => return_error!(InvalidMonomorphizationUnrecognized { span, name })
             };
         let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
         let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx);
         let function: RValue<'gcc> = unsafe { std::mem::transmute(function) };
-        let c = bx.call(fn_ty, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
+        let c = bx.call(fn_ty, None, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
         Ok(c)
     }
 
@@ -557,10 +509,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                     })*
                     _ => {},
                 }
-                require!(false,
-                         "unsupported operation on `{}` with element `{}`",
-                         in_ty,
-                         in_elem)
+                return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem })
             })*
         }
     }
@@ -579,12 +528,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
             ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)),
             ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)),
             _ => {
-                return_error!(
-                    "expected element type `{}` of vector type `{}` \
-                     to be a signed or unsigned integer type",
-                    arg_tys[0].simd_size_and_type(bx.tcx()).1,
-                    arg_tys[0]
-                );
+                return_error!(InvalidMonomorphizationExpectedSignedUnsigned {
+                    span,
+                    name,
+                    elem_ty: arg_tys[0].simd_size_and_type(bx.tcx()).1,
+                    vec_ty: arg_tys[0],
+                });
             }
         };
         let builtin_name =
@@ -617,10 +566,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
             if name == sym::$name {
                 require!(
                     ret_ty == in_elem,
-                    "expected return type `{}` (element of input `{}`), found `{}`",
-                    in_elem,
-                    in_ty,
-                    ret_ty
+                    InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
                 );
                 return match in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) => {
@@ -644,13 +590,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                             Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op))
                         }
                     }
-                    _ => return_error!(
-                        "unsupported {} from `{}` with element `{}` to `{}`",
-                        sym::$name,
-                        in_ty,
-                        in_elem,
-                        ret_ty
-                    ),
+                    _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
                 };
             }
         };
@@ -676,20 +616,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
             if name == sym::$name {
                 require!(
                     ret_ty == in_elem,
-                    "expected return type `{}` (element of input `{}`), found `{}`",
-                    in_elem,
-                    in_ty,
-                    ret_ty
+                    InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
                 );
                 return match in_elem.kind() {
                     ty::Int(_) | ty::Uint(_) | ty::Float(_) => Ok(bx.$reduction(args[0].immediate())),
-                    _ => return_error!(
-                        "unsupported {} from `{}` with element `{}` to `{}`",
-                        sym::$name,
-                        in_ty,
-                        in_elem,
-                        ret_ty
-                    ),
+                    _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
                 };
             }
         };
@@ -704,22 +635,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                 let input = if !$boolean {
                     require!(
                         ret_ty == in_elem,
-                        "expected return type `{}` (element of input `{}`), found `{}`",
-                        in_elem,
-                        in_ty,
-                        ret_ty
+                        InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
                     );
                     args[0].immediate()
                 } else {
                     match in_elem.kind() {
                         ty::Int(_) | ty::Uint(_) => {}
-                        _ => return_error!(
-                            "unsupported {} from `{}` with element `{}` to `{}`",
-                            sym::$name,
-                            in_ty,
-                            in_elem,
-                            ret_ty
-                        ),
+                        _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
                     }
 
                     // boolean reductions operate on vectors of i1s:
@@ -733,11 +655,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
                         Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) })
                     }
                     _ => return_error!(
-                        "unsupported {} from `{}` with element `{}` to `{}`",
-                        sym::$name,
-                        in_ty,
-                        in_elem,
-                        ret_ty
+                        InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }
                     ),
                 };
             }
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 223466fb9b5..accd02ab002 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -18,6 +18,8 @@
 #![recursion_limit="256"]
 #![warn(rust_2018_idioms)]
 #![warn(unused_lifetimes)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 
 extern crate rustc_apfloat;
 extern crate rustc_ast;
@@ -25,6 +27,7 @@ extern crate rustc_codegen_ssa;
 extern crate rustc_data_structures;
 extern crate rustc_errors;
 extern crate rustc_hir;
+extern crate rustc_macros;
 extern crate rustc_metadata;
 extern crate rustc_middle;
 extern crate rustc_session;
@@ -50,6 +53,7 @@ mod context;
 mod coverageinfo;
 mod debuginfo;
 mod declare;
+mod errors;
 mod int;
 mod intrinsic;
 mod mono_item;
@@ -59,6 +63,7 @@ mod type_of;
 use std::any::Any;
 use std::sync::{Arc, Mutex};
 
+use crate::errors::LTONotSupported;
 use gccjit::{Context, OptimizationLevel, CType};
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
@@ -97,7 +102,7 @@ pub struct GccCodegenBackend {
 impl CodegenBackend for GccCodegenBackend {
     fn init(&self, sess: &Session) {
         if sess.lto() != Lto::No {
-            sess.warn("LTO is not supported. You may get a linker error.");
+            sess.emit_warning(LTONotSupported {});
         }
 
         let temp_dir = TempDir::new().expect("cannot create temporary directory");
@@ -166,15 +171,6 @@ impl ExtraBackendMethods for GccCodegenBackend {
             Ok(())
         })
     }
-
-    fn target_cpu<'b>(&self, _sess: &'b Session) -> &'b str {
-        unimplemented!();
-    }
-
-    fn tune_cpu<'b>(&self, _sess: &'b Session) -> Option<&'b str> {
-        None
-        // TODO(antoyo)
-    }
 }
 
 pub struct ModuleBuffer;
@@ -205,7 +201,6 @@ impl WriteBackendMethods for GccCodegenBackend {
     type Module = GccContext;
     type TargetMachine = ();
     type ModuleBuffer = ModuleBuffer;
-    type Context = ();
     type ThinData = ();
     type ThinBuffer = ThinBuffer;
 
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index a068aa2ec62..df4a9fea19d 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -34,3 +34,4 @@ rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
+tempfile = "3.2.0"
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 26f5225f6b4..d478efc863a 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -592,10 +592,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
 }
 
 impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
-    fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value) {
-        fn_abi.apply_attrs_callsite(self, callsite)
-    }
-
     fn get_param(&mut self, index: usize) -> Self::Value {
         llvm::get_param(self.llfn(), index as c_uint)
     }
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 5202ac697e9..e723187ff1f 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -430,9 +430,9 @@ pub(crate) fn inline_asm_call<'ll>(
             );
 
             let call = if let Some((dest, catch, funclet)) = dest_catch_funclet {
-                bx.invoke(fty, v, inputs, dest, catch, funclet)
+                bx.invoke(fty, None, v, inputs, dest, catch, funclet)
             } else {
-                bx.call(fty, v, inputs, None)
+                bx.call(fty, None, v, inputs, None)
             };
 
             // Store mark in a metadata node so we can map LLVM errors
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 38a366095b4..20a063f80fd 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -2,16 +2,20 @@
 
 use std::env;
 use std::ffi::{CStr, CString, OsString};
-use std::io;
+use std::fs;
+use std::io::{self, Write};
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::ptr;
 use std::str;
 
+use object::read::macho::FatArch;
+
 use crate::common;
 use crate::llvm::archive_ro::{ArchiveRO, Child};
 use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
 use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
+use rustc_data_structures::memmap::Mmap;
 use rustc_session::cstore::DllImport;
 use rustc_session::Session;
 
@@ -53,13 +57,70 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
     }
 }
 
+fn try_filter_fat_archs(
+    archs: object::read::Result<&[impl FatArch]>,
+    target_arch: object::Architecture,
+    archive_path: &Path,
+    archive_map_data: &[u8],
+) -> io::Result<Option<PathBuf>> {
+    let archs = archs.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+
+    let desired = match archs.iter().filter(|a| a.architecture() == target_arch).next() {
+        Some(a) => a,
+        None => return Ok(None),
+    };
+
+    let (mut new_f, extracted_path) = tempfile::Builder::new()
+        .suffix(archive_path.file_name().unwrap())
+        .tempfile()?
+        .keep()
+        .unwrap();
+
+    new_f.write_all(
+        desired.data(archive_map_data).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
+    )?;
+
+    Ok(Some(extracted_path))
+}
+
+fn try_extract_macho_fat_archive(
+    sess: &Session,
+    archive_path: &Path,
+) -> io::Result<Option<PathBuf>> {
+    let archive_map = unsafe { Mmap::map(fs::File::open(&archive_path)?)? };
+    let target_arch = match sess.target.arch.as_ref() {
+        "aarch64" => object::Architecture::Aarch64,
+        "x86_64" => object::Architecture::X86_64,
+        _ => return Ok(None),
+    };
+
+    match object::macho::FatHeader::parse(&*archive_map) {
+        Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC => {
+            let archs = object::macho::FatHeader::parse_arch32(&*archive_map);
+            try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map)
+        }
+        Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC_64 => {
+            let archs = object::macho::FatHeader::parse_arch64(&*archive_map);
+            try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map)
+        }
+        // Not a FatHeader at all, just return None.
+        _ => Ok(None),
+    }
+}
+
 impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
     fn add_archive(
         &mut self,
         archive: &Path,
         skip: Box<dyn FnMut(&str) -> bool + 'static>,
     ) -> io::Result<()> {
-        let archive_ro = match ArchiveRO::open(archive) {
+        let mut archive = archive.to_path_buf();
+        if self.sess.target.llvm_target.contains("-apple-macosx") {
+            if let Some(new_archive) = try_extract_macho_fat_archive(&self.sess, &archive)? {
+                archive = new_archive
+            }
+        }
+        let archive_ro = match ArchiveRO::open(&archive) {
             Ok(ar) => ar,
             Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
         };
@@ -67,7 +128,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
             return Ok(());
         }
         self.additions.push(Addition::Archive {
-            path: archive.to_path_buf(),
+            path: archive,
             archive: archive_ro,
             skip: Box::new(skip),
         });
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 86f92dc0239..5b2bbdb4bde 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -19,6 +19,8 @@ use crate::context::CodegenCx;
 use crate::llvm;
 use crate::value::Value;
 
+use cstr::cstr;
+
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_codegen_ssa::traits::*;
@@ -107,11 +109,14 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
             }
 
             // Create the llvm.used and llvm.compiler.used variables.
-            if !cx.used_statics().borrow().is_empty() {
-                cx.create_used_variable()
+            if !cx.used_statics.borrow().is_empty() {
+                cx.create_used_variable_impl(cstr!("llvm.used"), &*cx.used_statics.borrow());
             }
-            if !cx.compiler_used_statics().borrow().is_empty() {
-                cx.create_compiler_used_variable()
+            if !cx.compiler_used_statics.borrow().is_empty() {
+                cx.create_used_variable_impl(
+                    cstr!("llvm.compiler.used"),
+                    &*cx.compiler_used_statics.borrow(),
+                );
             }
 
             // Run replace-all-uses-with for statics that need it. This must
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 59b1c7fb5db..fca43a0d86d 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1,3 +1,4 @@
+use crate::abi::FnAbiLlvmExt;
 use crate::attributes;
 use crate::common::Funclet;
 use crate::context::CodegenCx;
@@ -214,6 +215,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     fn invoke(
         &mut self,
         llty: &'ll Type,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
         args: &[&'ll Value],
         then: &'ll BasicBlock,
@@ -226,7 +228,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         let bundle = funclet.map(|funclet| funclet.bundle());
         let bundle = bundle.as_ref().map(|b| &*b.raw);
 
-        unsafe {
+        let invoke = unsafe {
             llvm::LLVMRustBuildInvoke(
                 self.llbuilder,
                 llty,
@@ -238,7 +240,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 bundle,
                 UNNAMED,
             )
+        };
+        if let Some(fn_abi) = fn_abi {
+            fn_abi.apply_attrs_callsite(self, invoke);
         }
+        invoke
     }
 
     fn unreachable(&mut self) {
@@ -405,20 +411,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
         let mut bx = Builder::with_cx(self.cx);
         bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) });
-        bx.dynamic_alloca(ty, align)
-    }
-
-    fn dynamic_alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
         unsafe {
-            let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED);
+            let alloca = llvm::LLVMBuildAlloca(bx.llbuilder, ty, UNNAMED);
             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
             alloca
         }
     }
 
-    fn array_alloca(&mut self, ty: &'ll Type, len: &'ll Value, align: Align) -> &'ll Value {
+    fn byte_array_alloca(&mut self, len: &'ll Value, align: Align) -> &'ll Value {
         unsafe {
-            let alloca = llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED);
+            let alloca =
+                llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), len, UNNAMED);
             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
             alloca
         }
@@ -1145,6 +1148,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     fn call(
         &mut self,
         llty: &'ll Type,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
         args: &[&'ll Value],
         funclet: Option<&Funclet<'ll>>,
@@ -1155,7 +1159,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         let bundle = funclet.map(|funclet| funclet.bundle());
         let bundle = bundle.as_ref().map(|b| &*b.raw);
 
-        unsafe {
+        let call = unsafe {
             llvm::LLVMRustBuildCall(
                 self.llbuilder,
                 llty,
@@ -1164,7 +1168,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 args.len() as c_uint,
                 bundle,
             )
+        };
+        if let Some(fn_abi) = fn_abi {
+            fn_abi.apply_attrs_callsite(self, call);
         }
+        call
     }
 
     fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
@@ -1397,7 +1405,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
 
     pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
         let (ty, f) = self.cx.get_intrinsic(intrinsic);
-        self.call(ty, f, args, None)
+        self.call(ty, None, f, args, None)
     }
 
     fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
@@ -1459,7 +1467,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
         };
         let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
-        self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None)
+        self.call(self.type_func(&[src_ty], dest_ty), None, f, &[val], None)
     }
 
     pub(crate) fn landing_pad(
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 67ffc7cb951..79ddfd884df 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -154,6 +154,11 @@ pub unsafe fn create_module<'ll>(
             target_data_layout = target_data_layout.replace("-p10:8:8-p20:8:8", "");
         }
     }
+    if llvm_version < (16, 0, 0) {
+        if sess.target.arch == "s390x" {
+            target_data_layout = target_data_layout.replace("-v128:64", "");
+        }
+    }
 
     // Ensure the data-layout values hardcoded remain the defaults.
     if sess.target.is_builtin {
@@ -453,7 +458,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
         self.coverage_cx.as_ref()
     }
 
-    fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
+    pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
         let section = cstr!("llvm.metadata");
         let array = self.const_array(self.type_ptr_to(self.type_i8()), values);
 
@@ -551,14 +556,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         self.codegen_unit
     }
 
-    fn used_statics(&self) -> &RefCell<Vec<&'ll Value>> {
-        &self.used_statics
-    }
-
-    fn compiler_used_statics(&self) -> &RefCell<Vec<&'ll Value>> {
-        &self.compiler_used_statics
-    }
-
     fn set_frame_pointer_type(&self, llfn: &'ll Value) {
         if let Some(attr) = attributes::frame_pointer_type_attr(self) {
             attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[attr]);
@@ -572,17 +569,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &attrs);
     }
 
-    fn create_used_variable(&self) {
-        self.create_used_variable_impl(cstr!("llvm.used"), &*self.used_statics.borrow());
-    }
-
-    fn create_compiler_used_variable(&self) {
-        self.create_used_variable_impl(
-            cstr!("llvm.compiler.used"),
-            &*self.compiler_used_statics.borrow(),
-        );
-    }
-
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
         if self.get_declared_value("main").is_none() {
             Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 0f663a26732..f79ef11720d 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -32,6 +32,7 @@ fn declare_raw_fn<'ll>(
     name: &str,
     callconv: llvm::CallConv,
     unnamed: llvm::UnnamedAddr,
+    visibility: llvm::Visibility,
     ty: &'ll Type,
 ) -> &'ll Value {
     debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
@@ -41,6 +42,7 @@ fn declare_raw_fn<'ll>(
 
     llvm::SetFunctionCallConv(llfn, callconv);
     llvm::SetUnnamedAddress(llfn, unnamed);
+    llvm::set_visibility(llfn, visibility);
 
     let mut attrs = SmallVec::<[_; 4]>::new();
 
@@ -78,7 +80,14 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
         unnamed: llvm::UnnamedAddr,
         fn_type: &'ll Type,
     ) -> &'ll Value {
-        declare_raw_fn(self, name, llvm::CCallConv, unnamed, fn_type)
+        // Declare C ABI functions with the visibility used by C by default.
+        let visibility = if self.tcx.sess.target.default_hidden_visibility {
+            llvm::Visibility::Hidden
+        } else {
+            llvm::Visibility::Default
+        };
+
+        declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
     }
 
     /// Declare a Rust function.
@@ -95,6 +104,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
             name,
             fn_abi.llvm_cconv(),
             llvm::UnnamedAddr::Global,
+            llvm::Visibility::Default,
             fn_abi.llvm_type(self),
         );
         fn_abi.apply_attrs_llfn(self, llfn);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index a640de42a6a..825011941a2 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -108,6 +108,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 let (simple_ty, simple_fn) = simple.unwrap();
                 self.call(
                     simple_ty,
+                    None,
                     simple_fn,
                     &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                     None,
@@ -435,7 +436,7 @@ fn try_intrinsic<'ll>(
 ) {
     if bx.sess().panic_strategy() == PanicStrategy::Abort {
         let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
-        bx.call(try_func_ty, try_func, &[data], None);
+        bx.call(try_func_ty, None, try_func, &[data], None);
         // Return 0 unconditionally from the intrinsic call;
         // we can never unwind.
         let ret_align = bx.tcx().data_layout.i32_align.abi;
@@ -534,7 +535,7 @@ fn codegen_msvc_try<'ll>(
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
         let slot = bx.alloca(bx.type_i8p(), ptr_align);
         let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
-        bx.invoke(try_func_ty, try_func, &[data], normal, catchswitch, None);
+        bx.invoke(try_func_ty, None, try_func, &[data], normal, catchswitch, None);
 
         bx.switch_to_block(normal);
         bx.ret(bx.const_i32(0));
@@ -578,7 +579,7 @@ fn codegen_msvc_try<'ll>(
         let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]);
         let ptr = bx.load(bx.type_i8p(), slot, ptr_align);
         let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
-        bx.call(catch_ty, catch_func, &[data, ptr], Some(&funclet));
+        bx.call(catch_ty, None, catch_func, &[data, ptr], Some(&funclet));
         bx.catch_ret(&funclet, caught);
 
         // The flag value of 64 indicates a "catch-all".
@@ -586,7 +587,7 @@ fn codegen_msvc_try<'ll>(
         let flags = bx.const_i32(64);
         let null = bx.const_null(bx.type_i8p());
         let funclet = bx.catch_pad(cs, &[null, flags, null]);
-        bx.call(catch_ty, catch_func, &[data, null], Some(&funclet));
+        bx.call(catch_ty, None, catch_func, &[data, null], Some(&funclet));
         bx.catch_ret(&funclet, caught);
 
         bx.switch_to_block(caught);
@@ -595,7 +596,7 @@ fn codegen_msvc_try<'ll>(
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -638,7 +639,7 @@ fn codegen_gnu_try<'ll>(
         let data = llvm::get_param(bx.llfn(), 1);
         let catch_func = llvm::get_param(bx.llfn(), 2);
         let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
-        bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
+        bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None);
 
         bx.switch_to_block(then);
         bx.ret(bx.const_i32(0));
@@ -656,13 +657,13 @@ fn codegen_gnu_try<'ll>(
         bx.add_clause(vals, tydesc);
         let ptr = bx.extract_value(vals, 0);
         let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
-        bx.call(catch_ty, catch_func, &[data, ptr], None);
+        bx.call(catch_ty, None, catch_func, &[data, ptr], None);
         bx.ret(bx.const_i32(1));
     });
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -702,7 +703,7 @@ fn codegen_emcc_try<'ll>(
         let data = llvm::get_param(bx.llfn(), 1);
         let catch_func = llvm::get_param(bx.llfn(), 2);
         let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
-        bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
+        bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None);
 
         bx.switch_to_block(then);
         bx.ret(bx.const_i32(0));
@@ -741,13 +742,13 @@ fn codegen_emcc_try<'ll>(
         let catch_data = bx.bitcast(catch_data, bx.type_i8p());
 
         let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
-        bx.call(catch_ty, catch_func, &[data, catch_data], None);
+        bx.call(catch_ty, None, catch_func, &[data, catch_data], None);
         bx.ret(bx.const_i32(1));
     });
 
     // Note that no invoke is used here because by definition this function
     // can't panic (that's what it's catching).
-    let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
+    let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None);
     let i32_align = bx.tcx().data_layout.i32_align.abi;
     bx.store(ret, dest, i32_align);
 }
@@ -1217,8 +1218,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         };
         let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
         let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty);
-        let c =
-            bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
+        let c = bx.call(
+            fn_ty,
+            None,
+            f,
+            &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
+            None,
+        );
         Ok(c)
     }
 
@@ -1417,8 +1423,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             llvm_elem_vec_ty,
         );
         let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-        let v =
-            bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None);
+        let v = bx.call(
+            fn_ty,
+            None,
+            f,
+            &[args[1].immediate(), alignment, mask, args[0].immediate()],
+            None,
+        );
         return Ok(v);
     }
 
@@ -1543,8 +1554,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         let fn_ty =
             bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t);
         let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-        let v =
-            bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None);
+        let v = bx.call(
+            fn_ty,
+            None,
+            f,
+            &[args[0].immediate(), args[1].immediate(), alignment, mask],
+            None,
+        );
         return Ok(v);
     }
 
@@ -1992,7 +2008,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
 
         let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty);
         let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
-        let v = bx.call(fn_ty, f, &[lhs, rhs], None);
+        let v = bx.call(fn_ty, None, f, &[lhs, rhs], None);
         return Ok(v);
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 15bfa843046..89c7e51d09e 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -131,12 +131,6 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
     ) -> TargetMachineFactoryFn<Self> {
         back::write::target_machine_factory(sess, optlvl, target_features)
     }
-    fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
-        llvm_util::target_cpu(sess)
-    }
-    fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str> {
-        llvm_util::tune_cpu(sess)
-    }
 
     fn spawn_thread<F, T>(time_trace: bool, f: F) -> std::thread::JoinHandle<T>
     where
@@ -170,7 +164,6 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
 impl WriteBackendMethods for LlvmCodegenBackend {
     type Module = ModuleLlvm;
     type ModuleBuffer = back::lto::ModuleBuffer;
-    type Context = llvm::Context;
     type TargetMachine = &'static mut llvm::TargetMachine;
     type ThinData = back::lto::ThinData;
     type ThinBuffer = back::lto::ThinBuffer;
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index e0bd7a33f73..2cd746ccb6a 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1180,22 +1180,19 @@ impl<'a> WasmLd<'a> {
         //   sharing memory and instantiating the module multiple times. As a
         //   result if it were exported then we'd just have no sharing.
         //
-        // * `--export=__wasm_init_memory` - when using `--passive-segments` the
-        //   linker will synthesize this function, and so we need to make sure
-        //   that our usage of `--export` below won't accidentally cause this
-        //   function to get deleted.
-        //
-        // * `--export=*tls*` - when `#[thread_local]` symbols are used these
-        //   symbols are how the TLS segments are initialized and configured.
+        // On wasm32-unknown-unknown, we also export symbols for glue code to use:
+        //    * `--export=*tls*` - when `#[thread_local]` symbols are used these
+        //      symbols are how the TLS segments are initialized and configured.
         if sess.target_features.contains(&sym::atomics) {
             cmd.arg("--shared-memory");
             cmd.arg("--max-memory=1073741824");
             cmd.arg("--import-memory");
-            cmd.arg("--export=__wasm_init_memory");
-            cmd.arg("--export=__wasm_init_tls");
-            cmd.arg("--export=__tls_size");
-            cmd.arg("--export=__tls_align");
-            cmd.arg("--export=__tls_base");
+            if sess.target.os == "unknown" {
+                cmd.arg("--export=__wasm_init_tls");
+                cmd.arg("--export=__tls_size");
+                cmd.arg("--export=__tls_align");
+                cmd.arg("--export=__tls_base");
+            }
         }
         WasmLd { cmd, sess }
     }
@@ -1320,10 +1317,12 @@ impl<'a> Linker for WasmLd<'a> {
 
         // LLD will hide these otherwise-internal symbols since it only exports
         // symbols explicitly passed via the `--export` flags above and hides all
-        // others. Various bits and pieces of tooling use this, so be sure these
-        // symbols make their way out of the linker as well.
-        self.cmd.arg("--export=__heap_base");
-        self.cmd.arg("--export=__data_end");
+        // others. Various bits and pieces of wasm32-unknown-unknown tooling use
+        // this, so be sure these symbols make their way out of the linker as well.
+        if self.sess.target.os == "unknown" {
+            self.cmd.arg("--export=__heap_base");
+            self.cmd.arg("--export=__data_end");
+        }
     }
 
     fn subsystem(&mut self, _subsystem: &str) {}
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 35fd86c1735..cb5436fd61a 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -474,7 +474,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             (rust_main, start_ty, vec![arg_argc, arg_argv])
         };
 
-        let result = bx.call(start_ty, start_fn, &args, None);
+        let result = bx.call(start_ty, None, start_fn, &args, None);
         let cast = bx.intcast(result, cx.type_int(), true);
         bx.ret(cast);
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index a6b226ef720..bd4f0cac7eb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -162,9 +162,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
             } else {
                 fx.unreachable_block()
             };
-            let invokeret =
-                bx.invoke(fn_ty, fn_ptr, &llargs, ret_llbb, unwind_block, self.funclet(fx));
-            bx.apply_attrs_callsite(&fn_abi, invokeret);
+            let invokeret = bx.invoke(
+                fn_ty,
+                Some(&fn_abi),
+                fn_ptr,
+                &llargs,
+                ret_llbb,
+                unwind_block,
+                self.funclet(fx),
+            );
             if fx.mir[self.bb].is_cleanup {
                 bx.do_not_inline(invokeret);
             }
@@ -178,8 +184,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
                 fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret);
             }
         } else {
-            let llret = bx.call(fn_ty, fn_ptr, &llargs, self.funclet(fx));
-            bx.apply_attrs_callsite(&fn_abi, llret);
+            let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
             if fx.mir[self.bb].is_cleanup {
                 // Cleanup is always the cold path. Don't inline
                 // drop glue. Also, when there is a deeply-nested
@@ -1533,8 +1538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
             let fn_ty = bx.fn_decl_backend_type(&fn_abi);
 
-            let llret = bx.call(fn_ty, fn_ptr, &[], None);
-            bx.apply_attrs_callsite(&fn_abi, llret);
+            let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], None);
             bx.do_not_inline(llret);
 
             bx.unreachable();
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 37b1e036247..e6ba642a7ed 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -352,7 +352,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
 
         // Allocate an appropriate region on the stack, and copy the value into it
         let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
-        let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, max_align);
+        let lldst = bx.byte_array_alloca(llsize, max_align);
         bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
 
         // Store the allocated region and the extra to the indirect place.
diff --git a/compiler/rustc_codegen_ssa/src/traits/abi.rs b/compiler/rustc_codegen_ssa/src/traits/abi.rs
index a00d78daf4d..60d8f2a9ece 100644
--- a/compiler/rustc_codegen_ssa/src/traits/abi.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/abi.rs
@@ -1,8 +1,5 @@
 use super::BackendTypes;
-use rustc_middle::ty::Ty;
-use rustc_target::abi::call::FnAbi;
 
 pub trait AbiBuilderMethods<'tcx>: BackendTypes {
-    fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value);
     fn get_param(&mut self, index: usize) -> Self::Value;
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 779bd3ea278..87e347c61e2 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -134,8 +134,6 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
         opt_level: config::OptLevel,
         target_features: &[String],
     ) -> TargetMachineFactoryFn<Self>;
-    fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
-    fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>;
 
     fn spawn_thread<F, T>(_time_trace: bool, f: F) -> std::thread::JoinHandle<T>
     where
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 10cf8948b5a..01408f39fb3 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -17,6 +17,7 @@ use crate::MemFlags;
 use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
 use rustc_middle::ty::Ty;
 use rustc_span::Span;
+use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange};
 use rustc_target::spec::HasTargetSpec;
 
@@ -71,6 +72,7 @@ pub trait BuilderMethods<'a, 'tcx>:
     fn invoke(
         &mut self,
         llty: Self::Type,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: Self::Value,
         args: &[Self::Value],
         then: Self::BasicBlock,
@@ -133,8 +135,7 @@ pub trait BuilderMethods<'a, 'tcx>:
     fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value;
 
     fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
-    fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
-    fn array_alloca(&mut self, ty: Self::Type, len: Self::Value, align: Align) -> Self::Value;
+    fn byte_array_alloca(&mut self, len: Self::Value, align: Align) -> Self::Value;
 
     fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value;
     fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value;
@@ -320,6 +321,7 @@ pub trait BuilderMethods<'a, 'tcx>:
     fn call(
         &mut self,
         llty: Self::Type,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: Self::Value,
         args: &[Self::Value],
         funclet: Option<&Self::Funclet>,
diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs
index 4266e42ec2b..04e2b8796c4 100644
--- a/compiler/rustc_codegen_ssa/src/traits/misc.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs
@@ -15,12 +15,8 @@ pub trait MiscMethods<'tcx>: BackendTypes {
     fn eh_personality(&self) -> Self::Value;
     fn sess(&self) -> &Session;
     fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>;
-    fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
-    fn compiler_used_statics(&self) -> &RefCell<Vec<Self::Value>>;
     fn set_frame_pointer_type(&self, llfn: Self::Function);
     fn apply_target_cpu_attr(&self, llfn: Self::Function);
-    fn create_used_variable(&self);
-    fn create_compiler_used_variable(&self);
     /// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs
index e54ec34f1ce..e0e8ffa89ed 100644
--- a/compiler/rustc_codegen_ssa/src/traits/write.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/write.rs
@@ -9,7 +9,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
     type Module: Send + Sync;
     type TargetMachine;
     type ModuleBuffer: ModuleBufferMethods;
-    type Context: ?Sized;
     type ThinData: Send + Sync;
     type ThinBuffer: ThinBufferMethods;
 
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 09d53331b5b..09c92ae0361 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -233,10 +233,10 @@ impl<'tcx> ConstEvalErr<'tcx> {
                 rustc_session::lint::builtin::CONST_ERR,
                 hir_id,
                 tcx.span,
+                message,
                 |lint| {
-                    let mut lint = lint.build(message);
-                    finish(&mut lint, Some(err_msg));
-                    lint.emit();
+                    finish(lint, Some(err_msg));
+                    lint
                 },
             );
             ErrorHandled::Linted
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 7a01b85381a..eeeb7d6d3e5 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -640,11 +640,17 @@ where
         // avoid force_allocation.
         let src = match self.read_immediate_raw(src)? {
             Ok(src_val) => {
-                assert!(!src.layout.is_unsized(), "cannot copy unsized immediates");
-                assert!(
-                    !dest.layout.is_unsized(),
-                    "the src is sized, so the dest must also be sized"
-                );
+                // FIXME(const_prop): Const-prop can possibly evaluate an
+                // unsized copy operation when it thinks that the type is
+                // actually sized, due to a trivially false where-clause
+                // predicate like `where Self: Sized` with `Self = dyn Trait`.
+                // See #102553 for an example of such a predicate.
+                if src.layout.is_unsized() {
+                    throw_inval!(SizeOfUnsizedType(src.layout.ty));
+                }
+                if dest.layout.is_unsized() {
+                    throw_inval!(SizeOfUnsizedType(dest.layout.ty));
+                }
                 assert_eq!(src.layout.size, dest.layout.size);
                 // Yay, we got a value that we can write directly.
                 return if layout_compat {
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 7c4c7db1035..230f841cf4d 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -20,7 +20,7 @@ Rust MIR: a lowered representation of Rust.
 #![feature(trusted_step)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
-#![feature(is_some_with)]
+#![feature(is_some_and)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 
@@ -32,7 +32,6 @@ extern crate rustc_middle;
 pub mod const_eval;
 mod errors;
 pub mod interpret;
-mod might_permit_raw_init;
 pub mod transform;
 pub mod util;
 
@@ -61,7 +60,6 @@ pub fn provide(providers: &mut Providers) {
         const_eval::deref_mir_constant(tcx, param_env, value)
     };
     providers.permits_uninit_init =
-        |tcx, ty| might_permit_raw_init::might_permit_raw_init(tcx, ty, InitKind::Uninit);
-    providers.permits_zero_init =
-        |tcx, ty| might_permit_raw_init::might_permit_raw_init(tcx, ty, InitKind::Zero);
+        |tcx, ty| util::might_permit_raw_init(tcx, ty, InitKind::UninitMitigated0x01Fill);
+    providers.permits_zero_init = |tcx, ty| util::might_permit_raw_init(tcx, ty, InitKind::Zero);
 }
diff --git a/compiler/rustc_const_eval/src/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/might_permit_raw_init.rs
deleted file mode 100644
index 37ffa19ccd6..00000000000
--- a/compiler/rustc_const_eval/src/might_permit_raw_init.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use crate::const_eval::CompileTimeInterpreter;
-use crate::interpret::{InterpCx, MemoryKind, OpTy};
-use rustc_middle::ty::layout::LayoutCx;
-use rustc_middle::ty::{layout::TyAndLayout, ParamEnv, TyCtxt};
-use rustc_session::Limit;
-use rustc_target::abi::InitKind;
-
-pub fn might_permit_raw_init<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    ty: TyAndLayout<'tcx>,
-    kind: InitKind,
-) -> bool {
-    let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
-
-    if strict {
-        let machine = CompileTimeInterpreter::new(
-            Limit::new(0),
-            /*can_access_statics:*/ false,
-            /*check_alignment:*/ true,
-        );
-
-        let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
-
-        let allocated = cx
-            .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
-            .expect("OOM: failed to allocate for uninit check");
-
-        if kind == InitKind::Zero {
-            cx.write_bytes_ptr(
-                allocated.ptr,
-                std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()),
-            )
-            .expect("failed to write bytes for zero valid check");
-        }
-
-        let ot: OpTy<'_, _> = allocated.into();
-
-        // Assume that if it failed, it's a validation failure.
-        cx.validate_operand(&ot).is_ok()
-    } else {
-        let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() };
-        ty.might_permit_raw_init(&layout_cx, kind)
-    }
-}
diff --git a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs
new file mode 100644
index 00000000000..6ca71223391
--- /dev/null
+++ b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs
@@ -0,0 +1,151 @@
+use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout};
+use rustc_middle::ty::{ParamEnv, TyCtxt};
+use rustc_session::Limit;
+use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants};
+
+use crate::const_eval::CompileTimeInterpreter;
+use crate::interpret::{InterpCx, MemoryKind, OpTy};
+
+/// Determines if this type permits "raw" initialization by just transmuting some memory into an
+/// instance of `T`.
+///
+/// `init_kind` indicates if the memory is zero-initialized or left uninitialized. We assume
+/// uninitialized memory is mitigated by filling it with 0x01, which reduces the chance of causing
+/// LLVM UB.
+///
+/// By default we check whether that operation would cause *LLVM UB*, i.e., whether the LLVM IR we
+/// generate has UB or not. This is a mitigation strategy, which is why we are okay with accepting
+/// Rust UB as long as there is no risk of miscompilations. The `strict_init_checks` can be set to
+/// do a full check against Rust UB instead (in which case we will also ignore the 0x01-filling and
+/// to the full uninit check).
+pub fn might_permit_raw_init<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: TyAndLayout<'tcx>,
+    kind: InitKind,
+) -> bool {
+    if tcx.sess.opts.unstable_opts.strict_init_checks {
+        might_permit_raw_init_strict(ty, tcx, kind)
+    } else {
+        let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() };
+        might_permit_raw_init_lax(ty, &layout_cx, kind)
+    }
+}
+
+/// Implements the 'strict' version of the `might_permit_raw_init` checks; see that function for
+/// details.
+fn might_permit_raw_init_strict<'tcx>(
+    ty: TyAndLayout<'tcx>,
+    tcx: TyCtxt<'tcx>,
+    kind: InitKind,
+) -> bool {
+    let machine = CompileTimeInterpreter::new(
+        Limit::new(0),
+        /*can_access_statics:*/ false,
+        /*check_alignment:*/ true,
+    );
+
+    let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
+
+    let allocated = cx
+        .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
+        .expect("OOM: failed to allocate for uninit check");
+
+    if kind == InitKind::Zero {
+        cx.write_bytes_ptr(
+            allocated.ptr,
+            std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()),
+        )
+        .expect("failed to write bytes for zero valid check");
+    }
+
+    let ot: OpTy<'_, _> = allocated.into();
+
+    // Assume that if it failed, it's a validation failure.
+    // This does *not* actually check that references are dereferenceable, but since all types that
+    // require dereferenceability also require non-null, we don't actually get any false negatives
+    // due to this.
+    cx.validate_operand(&ot).is_ok()
+}
+
+/// Implements the 'lax' (default) version of the `might_permit_raw_init` checks; see that function for
+/// details.
+fn might_permit_raw_init_lax<'tcx>(
+    this: TyAndLayout<'tcx>,
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    init_kind: InitKind,
+) -> bool {
+    let scalar_allows_raw_init = move |s: Scalar| -> bool {
+        match init_kind {
+            InitKind::Zero => {
+                // The range must contain 0.
+                s.valid_range(cx).contains(0)
+            }
+            InitKind::UninitMitigated0x01Fill => {
+                // The range must include an 0x01-filled buffer.
+                let mut val: u128 = 0x01;
+                for _ in 1..s.size(cx).bytes() {
+                    // For sizes >1, repeat the 0x01.
+                    val = (val << 8) | 0x01;
+                }
+                s.valid_range(cx).contains(val)
+            }
+        }
+    };
+
+    // Check the ABI.
+    let valid = match this.abi {
+        Abi::Uninhabited => false, // definitely UB
+        Abi::Scalar(s) => scalar_allows_raw_init(s),
+        Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
+        Abi::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
+        Abi::Aggregate { .. } => true, // Fields are checked below.
+    };
+    if !valid {
+        // This is definitely not okay.
+        return false;
+    }
+
+    // Special magic check for references and boxes (i.e., special pointer types).
+    if let Some(pointee) = this.ty.builtin_deref(false) {
+        let pointee = cx.layout_of(pointee.ty).expect("need to be able to compute layouts");
+        // We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied.
+        if pointee.align.abi.bytes() > 1 {
+            // 0x01-filling is not aligned.
+            return false;
+        }
+        if pointee.size.bytes() > 0 {
+            // A 'fake' integer pointer is not sufficiently dereferenceable.
+            return false;
+        }
+    }
+
+    // If we have not found an error yet, we need to recursively descend into fields.
+    match &this.fields {
+        FieldsShape::Primitive | FieldsShape::Union { .. } => {}
+        FieldsShape::Array { .. } => {
+            // Arrays never have scalar layout in LLVM, so if the array is not actually
+            // accessed, there is no LLVM UB -- therefore we can skip this.
+        }
+        FieldsShape::Arbitrary { offsets, .. } => {
+            for idx in 0..offsets.len() {
+                if !might_permit_raw_init_lax(this.field(cx, idx), cx, init_kind) {
+                    // We found a field that is unhappy with this kind of initialization.
+                    return false;
+                }
+            }
+        }
+    }
+
+    match &this.variants {
+        Variants::Single { .. } => {
+            // All fields of this single variant have already been checked above, there is nothing
+            // else to do.
+        }
+        Variants::Multiple { .. } => {
+            // We cannot tell LLVM anything about the details of this multi-variant layout, so
+            // invalid values "hidden" inside the variant cannot cause LLVM trouble.
+        }
+    }
+
+    true
+}
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index a1876bed83e..7a05cfd235f 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -3,8 +3,10 @@ mod alignment;
 mod call_kind;
 pub mod collect_writes;
 mod find_self_call;
+mod might_permit_raw_init;
 
 pub use self::aggregate::expand_aggregate;
 pub use self::alignment::is_disaligned;
 pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind};
 pub use self::find_self_call::find_self_call;
+pub use self::might_permit_raw_init::might_permit_raw_init;
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 937cb671573..fe257e10205 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -96,6 +96,23 @@ impl<K: Ord, V> SortedMap<K, V> {
         }
     }
 
+    /// Gets a mutable reference to the value in the entry, or insert a new one.
+    #[inline]
+    pub fn get_mut_or_insert_default(&mut self, key: K) -> &mut V
+    where
+        K: Eq,
+        V: Default,
+    {
+        let index = match self.lookup_index_for(&key) {
+            Ok(index) => index,
+            Err(index) => {
+                self.data.insert(index, (key, V::default()));
+                index
+            }
+        };
+        unsafe { &mut self.data.get_unchecked_mut(index).1 }
+    }
+
     #[inline]
     pub fn clear(&mut self) {
         self.data.clear();
diff --git a/compiler/rustc_error_codes/src/error_codes/E0045.md b/compiler/rustc_error_codes/src/error_codes/E0045.md
index 143c693bf7c..1cb214531e8 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0045.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0045.md
@@ -3,9 +3,7 @@ Variadic parameters have been used on a non-C ABI function.
 Erroneous code example:
 
 ```compile_fail,E0045
-#![feature(unboxed_closures)]
-
-extern "rust-call" {
+extern "Rust" {
     fn foo(x: u8, ...); // error!
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md
index 496174b28ef..5cbe2a188b0 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0092.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0092.md
@@ -19,6 +19,6 @@ functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
-    fn atomic_fence(); // ok!
+    fn atomic_fence_seqcst(); // ok!
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index ec86ec44ece..cc546bdbb3b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
@@ -6,6 +6,7 @@ Erroneous code example:
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
                                  //        of type parameters
 }
@@ -19,6 +20,7 @@ Example:
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T>() -> usize; // ok!
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0161.md b/compiler/rustc_error_codes/src/error_codes/E0161.md
index ebd2c97698b..643990ef1c7 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0161.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0161.md
@@ -3,7 +3,6 @@ A value was moved whose size was not known at compile time.
 Erroneous code example:
 
 ```compile_fail,E0161
-#![feature(box_syntax)]
 trait Bar {
     fn f(self);
 }
@@ -13,7 +12,7 @@ impl Bar for i32 {
 }
 
 fn main() {
-    let b: Box<dyn Bar> = box (0 as i32);
+    let b: Box<dyn Bar> = Box::new(0i32);
     b.f();
     // error: cannot move a value of type dyn Bar: the size of dyn Bar cannot
     //        be statically determined
@@ -27,8 +26,6 @@ either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
 it around as usual. Example:
 
 ```
-#![feature(box_syntax)]
-
 trait Bar {
     fn f(&self);
 }
@@ -38,7 +35,7 @@ impl Bar for i32 {
 }
 
 fn main() {
-    let b: Box<dyn Bar> = box (0 as i32);
+    let b: Box<dyn Bar> = Box::new(0i32);
     b.f();
     // ok!
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 77289f01900..8c2462ebd9b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
@@ -7,6 +7,7 @@ used. Erroneous code examples:
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T>(); // error: intrinsic has wrong type
 }
 
@@ -42,6 +43,7 @@ For the first code example, please check the function definition. Example:
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T>() -> usize; // ok!
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0579.md b/compiler/rustc_error_codes/src/error_codes/E0579.md
index f554242a3d4..e7e6fb68256 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0579.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0579.md
@@ -8,9 +8,9 @@ Erroneous code example:
 fn main() {
     match 5u32 {
         // This range is ok, albeit pointless.
-        1 .. 2 => {}
+        1..2 => {}
         // This range is empty, and the compiler can tell.
-        5 .. 5 => {} // error!
+        5..5 => {} // error!
     }
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md
index 990a2549412..3ba3ed10e5c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0622.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0622.md
@@ -5,7 +5,7 @@ Erroneous code example:
 ```compile_fail,E0622
 #![feature(intrinsics)]
 extern "rust-intrinsic" {
-    pub static breakpoint : fn(); // error: intrinsic must be a function
+    pub static breakpoint: fn(); // error: intrinsic must be a function
 }
 
 fn main() { unsafe { breakpoint(); } }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0743.md b/compiler/rustc_error_codes/src/error_codes/E0743.md
index ddd3136df0c..a19d3ef96e9 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0743.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0743.md
@@ -3,8 +3,6 @@ The C-variadic type `...` has been nested inside another type.
 Erroneous code example:
 
 ```compile_fail,E0743
-#![feature(c_variadic)]
-
 fn foo2(x: u8, y: &...) {} // error!
 ```
 
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
new file mode 100644
index 00000000000..178e1a67cce
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
@@ -0,0 +1,68 @@
+codegen_gcc_ranlib_failure =
+    Ranlib exited with code {$exit_code}
+
+codegen_gcc_linkage_const_or_mut_type =
+    must have type `*const T` or `*mut T` due to `#[linkage]` attribute
+
+codegen_gcc_unwinding_inline_asm =
+    GCC backend does not support unwinding from inline asm
+
+codegen_gcc_lto_not_supported =
+    LTO is not supported. You may get a linker error.
+
+codegen_gcc_invalid_monomorphization_basic_integer =
+    invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`
+
+codegen_gcc_invalid_monomorphization_invalid_float_vector =
+    invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$elem_ty}` of floating-point vector `{$vec_ty}`
+
+codegen_gcc_invalid_monomorphization_not_float =
+    invalid monomorphization of `{$name}` intrinsic: `{$ty}` is not a floating-point type
+
+codegen_gcc_invalid_monomorphization_unrecognized =
+    invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
+
+codegen_gcc_invalid_monomorphization_expected_signed_unsigned =
+    invalid monomorphization of `{$name}` intrinsic: expected element type `{$elem_ty}` of vector type `{$vec_ty}` to be a signed or unsigned integer type
+
+codegen_gcc_invalid_monomorphization_unsupported_element =
+    invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}`
+
+codegen_gcc_invalid_monomorphization_invalid_bitmask =
+    invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
+
+codegen_gcc_invalid_monomorphization_simd_shuffle =
+    invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
+
+codegen_gcc_invalid_monomorphization_expected_simd =
+    invalid monomorphization of `{$name}` intrinsic: expected SIMD {$expected_ty} type, found non-SIMD `{$found_ty}`
+
+codegen_gcc_invalid_monomorphization_mask_type =
+    invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_`
+
+codegen_gcc_invalid_monomorphization_return_length =
+    invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
+
+codegen_gcc_invalid_monomorphization_return_length_input_type =
+    invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
+
+codegen_gcc_invalid_monomorphization_return_element =
+    invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
+
+codegen_gcc_invalid_monomorphization_return_type =
+    invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
+
+codegen_gcc_invalid_monomorphization_inserted_type =
+    invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
+
+codegen_gcc_invalid_monomorphization_return_integer_type =
+    invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
+
+codegen_gcc_invalid_monomorphization_mismatched_lengths =
+    invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
+
+codegen_gcc_invalid_monomorphization_unsupported_cast =
+    invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
+
+codegen_gcc_invalid_monomorphization_unsupported_operation =
+    invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
diff --git a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl b/compiler/rustc_error_messages/locales/en-US/compiletest.ftl
new file mode 100644
index 00000000000..55061fbce7e
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/compiletest.ftl
@@ -0,0 +1,5 @@
+compiletest_example = this is an example message used in testing
+    .note = with a note
+    .help = with a help
+    .suggestion = with a suggestion
+    .label = with a label
diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
index 272731d9914..c6a4ff6f0e0 100644
--- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
@@ -1,101 +1,101 @@
-typeck_field_multiply_specified_in_initializer =
+hir_analysis_field_multiply_specified_in_initializer =
     field `{$ident}` specified more than once
     .label = used more than once
     .previous_use_label = first use of `{$ident}`
 
-typeck_unrecognized_atomic_operation =
+hir_analysis_unrecognized_atomic_operation =
     unrecognized atomic operation function: `{$op}`
     .label = unrecognized atomic operation
 
-typeck_wrong_number_of_generic_arguments_to_intrinsic =
+hir_analysis_wrong_number_of_generic_arguments_to_intrinsic =
     intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
     .label = expected {$expected} {$descr} {$expected ->
         [one] parameter
         *[other] parameters
     }
 
-typeck_unrecognized_intrinsic_function =
+hir_analysis_unrecognized_intrinsic_function =
     unrecognized intrinsic function: `{$name}`
     .label = unrecognized intrinsic
 
-typeck_lifetimes_or_bounds_mismatch_on_trait =
+hir_analysis_lifetimes_or_bounds_mismatch_on_trait =
     lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
     .label = lifetimes do not match {$item_kind} in trait
     .generics_label = lifetimes in impl do not match this {$item_kind} in trait
 
-typeck_drop_impl_on_wrong_item =
+hir_analysis_drop_impl_on_wrong_item =
     the `Drop` trait may only be implemented for local structs, enums, and unions
     .label = must be a struct, enum, or union in the current crate
 
-typeck_field_already_declared =
+hir_analysis_field_already_declared =
     field `{$field_name}` is already declared
     .label = field already declared
     .previous_decl_label = `{$field_name}` first declared here
 
-typeck_copy_impl_on_type_with_dtor =
+hir_analysis_copy_impl_on_type_with_dtor =
     the trait `Copy` may not be implemented for this type; the type has a destructor
     .label = `Copy` not allowed on types with destructors
 
-typeck_multiple_relaxed_default_bounds =
+hir_analysis_multiple_relaxed_default_bounds =
     type parameter has more than one relaxed default bound, only one is supported
 
-typeck_copy_impl_on_non_adt =
+hir_analysis_copy_impl_on_non_adt =
     the trait `Copy` may not be implemented for this type
     .label = type is not a structure or enumeration
 
-typeck_trait_object_declared_with_no_traits =
+hir_analysis_trait_object_declared_with_no_traits =
     at least one trait is required for an object type
     .alias_span = this alias does not contain a trait
 
-typeck_ambiguous_lifetime_bound =
+hir_analysis_ambiguous_lifetime_bound =
     ambiguous lifetime bound, explicit lifetime bound required
 
-typeck_assoc_type_binding_not_allowed =
+hir_analysis_assoc_type_binding_not_allowed =
     associated type bindings are not allowed here
     .label = associated type not allowed here
 
-typeck_functional_record_update_on_non_struct =
+hir_analysis_functional_record_update_on_non_struct =
     functional record update syntax requires a struct
 
-typeck_typeof_reserved_keyword_used =
+hir_analysis_typeof_reserved_keyword_used =
     `typeof` is a reserved keyword but unimplemented
     .suggestion = consider replacing `typeof(...)` with an actual type
     .label = reserved keyword
 
-typeck_return_stmt_outside_of_fn_body =
+hir_analysis_return_stmt_outside_of_fn_body =
     return statement outside of function body
     .encl_body_label = the return is part of this body...
     .encl_fn_label = ...not the enclosing function body
 
-typeck_yield_expr_outside_of_generator =
+hir_analysis_yield_expr_outside_of_generator =
     yield expression outside of generator literal
 
-typeck_struct_expr_non_exhaustive =
+hir_analysis_struct_expr_non_exhaustive =
     cannot create non-exhaustive {$what} using struct expression
 
-typeck_method_call_on_unknown_type =
+hir_analysis_method_call_on_unknown_type =
     the type of this value must be known to call a method on a raw pointer on it
 
-typeck_value_of_associated_struct_already_specified =
+hir_analysis_value_of_associated_struct_already_specified =
     the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
     .label = re-bound here
     .previous_bound_label = `{$item_name}` bound here first
 
-typeck_address_of_temporary_taken = cannot take address of a temporary
+hir_analysis_address_of_temporary_taken = cannot take address of a temporary
     .label = temporary value
 
-typeck_add_return_type_add = try adding a return type
+hir_analysis_add_return_type_add = try adding a return type
 
-typeck_add_return_type_missing_here = a return type might be missing here
+hir_analysis_add_return_type_missing_here = a return type might be missing here
 
-typeck_expected_default_return_type = expected `()` because of default return type
+hir_analysis_expected_default_return_type = expected `()` because of default return type
 
-typeck_expected_return_type = expected `{$expected}` because of return type
+hir_analysis_expected_return_type = expected `{$expected}` because of return type
 
-typeck_unconstrained_opaque_type = unconstrained opaque type
+hir_analysis_unconstrained_opaque_type = unconstrained opaque type
     .note = `{$name}` must be used in combination with a concrete type within the same module
 
-typeck_missing_type_params =
+hir_analysis_missing_type_params =
     the type {$parameterCount ->
         [one] parameter
         *[other] parameters
@@ -117,19 +117,19 @@ typeck_missing_type_params =
     } to {$parameters}
     .note = because of the default `Self` reference, type parameters must be specified on object types
 
-typeck_manual_implementation =
+hir_analysis_manual_implementation =
     manual implementations of `{$trait_name}` are experimental
     .label = manual implementations of `{$trait_name}` are experimental
     .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
+hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
 
-typeck_unused_extern_crate =
+hir_analysis_unused_extern_crate =
     unused extern crate
     .suggestion = remove it
 
-typeck_extern_crate_not_idiomatic =
+hir_analysis_extern_crate_not_idiomatic =
     `extern crate` is not idiomatic in the new edition
     .suggestion = convert it to a `{$msg_code}`
 
-typeck_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
+hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl
index 80b0b1a8904..0fd9b0ead16 100644
--- a/compiler/rustc_error_messages/locales/en-US/lint.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl
@@ -433,3 +433,7 @@ lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}`
 lint_check_name_warning = {$msg}
 
 lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name}
+
+lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its associated type bounds
+    .specifically = this associated type bound is unsatisfied for `{$proj_ty}`
+    .suggestion = add this bound
diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl
index ed834886453..ca3c91ce24a 100644
--- a/compiler/rustc_error_messages/locales/en-US/middle.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl
@@ -15,3 +15,6 @@ middle_previous_use_here =
 middle_limit_invalid =
     `limit` must be a non-negative integer
     .label = {$error_str}
+
+middle_const_eval_non_int =
+    constant evaluation of enum discriminant resulted in non-integer
diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl
index 6d34cdce340..13c368d1c58 100644
--- a/compiler/rustc_error_messages/locales/en-US/parser.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl
@@ -245,7 +245,7 @@ parser_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is no
 parser_expected_statement_after_outer_attr = expected statement after outer attribute
 
 parser_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything
-    .help = doc comments must come before what they document, maybe a comment was intended with `//`?
+    .help = doc comments must come before what they document, if a comment was intended use `//`
     .suggestion = missing comma here
 
 parser_const_let_mutually_exclusive = `const` and `let` are mutually exclusive
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index ff33ae7e8f2..18be60975e4 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -40,27 +40,29 @@ fluent_messages! {
     attr => "../locales/en-US/attr.ftl",
     borrowck => "../locales/en-US/borrowck.ftl",
     builtin_macros => "../locales/en-US/builtin_macros.ftl",
+    compiletest => "../locales/en-US/compiletest.ftl",
     const_eval => "../locales/en-US/const_eval.ftl",
+    codegen_gcc => "../locales/en-US/codegen_gcc.ftl",
     driver => "../locales/en-US/driver.ftl",
     expand => "../locales/en-US/expand.ftl",
-    session => "../locales/en-US/session.ftl",
-    interface => "../locales/en-US/interface.ftl",
+    hir_analysis => "../locales/en-US/hir_analysis.ftl",
     infer => "../locales/en-US/infer.ftl",
+    interface => "../locales/en-US/interface.ftl",
     lint => "../locales/en-US/lint.ftl",
+    metadata => "../locales/en-US/metadata.ftl",
     middle => "../locales/en-US/middle.ftl",
+    mir_dataflow => "../locales/en-US/mir_dataflow.ftl",
     monomorphize => "../locales/en-US/monomorphize.ftl",
-    metadata => "../locales/en-US/metadata.ftl",
     parser => "../locales/en-US/parser.ftl",
     passes => "../locales/en-US/passes.ftl",
     plugin_impl => "../locales/en-US/plugin_impl.ftl",
     privacy => "../locales/en-US/privacy.ftl",
     query_system => "../locales/en-US/query_system.ftl",
-    trait_selection => "../locales/en-US/trait_selection.ftl",
     save_analysis => "../locales/en-US/save_analysis.ftl",
-    ty_utils => "../locales/en-US/ty_utils.ftl",
-    typeck => "../locales/en-US/typeck.ftl",
-    mir_dataflow => "../locales/en-US/mir_dataflow.ftl",
+    session => "../locales/en-US/session.ftl",
     symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
+    trait_selection => "../locales/en-US/trait_selection.ftl",
+    ty_utils => "../locales/en-US/ty_utils.ftl",
 }
 
 pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
@@ -357,6 +359,17 @@ impl<S: Into<String>> From<S> for DiagnosticMessage {
     }
 }
 
+/// A workaround for "good path" ICEs when formatting types in disables lints.
+///
+/// Delays formatting until `.into(): DiagnosticMessage` is used.
+pub struct DelayDm<F>(pub F);
+
+impl<F: FnOnce() -> String> From<DelayDm<F>> for DiagnosticMessage {
+    fn from(DelayDm(f): DelayDm<F>) -> Self {
+        DiagnosticMessage::from(f())
+    }
+}
+
 /// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but
 /// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagnosticMessage` and the
 /// subdiagnostic derive refers to typed identifiers that are `DiagnosticMessage`s, so need to be
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 5520e22e476..31e410aaaf0 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -1,6 +1,6 @@
 use crate::snippet::Style;
 use crate::{
-    CodeSuggestion, DiagnosticMessage, EmissionGuarantee, Level, LintDiagnosticBuilder, MultiSpan,
+    CodeSuggestion, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level, MultiSpan,
     SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
 };
 use rustc_ast as ast;
@@ -209,7 +209,12 @@ pub trait AddToDiagnostic {
 #[rustc_diagnostic_item = "DecorateLint"]
 pub trait DecorateLint<'a, G: EmissionGuarantee> {
     /// Decorate and emit a lint.
-    fn decorate_lint(self, diag: LintDiagnosticBuilder<'a, G>);
+    fn decorate_lint<'b>(
+        self,
+        diag: &'b mut DiagnosticBuilder<'a, G>,
+    ) -> &'b mut DiagnosticBuilder<'a, G>;
+
+    fn msg(&self) -> DiagnosticMessage;
 }
 
 #[must_use]
@@ -359,9 +364,10 @@ impl Diagnostic {
             // The lint index inside the attribute is manually transferred here.
             let lint_index = expectation_id.get_lint_index();
             expectation_id.set_lint_index(None);
-            let mut stable_id = *unstable_to_stable
+            let mut stable_id = unstable_to_stable
                 .get(&expectation_id)
-                .expect("each unstable `LintExpectationId` must have a matching stable id");
+                .expect("each unstable `LintExpectationId` must have a matching stable id")
+                .normalize();
 
             stable_id.set_lint_index(lint_index);
             *expectation_id = stable_id;
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index b4ba65ca96d..bbe6435be59 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -5,6 +5,7 @@ use crate::{
 };
 use crate::{Handler, Level, MultiSpan, StashKey};
 use rustc_lint_defs::Applicability;
+use rustc_span::source_map::Spanned;
 
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -23,6 +24,18 @@ pub trait IntoDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>;
 }
 
+impl<'a, T, E> IntoDiagnostic<'a, E> for Spanned<T>
+where
+    T: IntoDiagnostic<'a, E>,
+    E: EmissionGuarantee,
+{
+    fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, E> {
+        let mut diag = self.node.into_diagnostic(handler);
+        diag.set_span(self.span);
+        diag
+    }
+}
+
 /// Used for emitting structured error messages and other diagnostic information.
 ///
 /// If there is some state in a downstream crate you would like to
@@ -629,27 +642,3 @@ macro_rules! struct_span_err {
 macro_rules! error_code {
     ($code:ident) => {{ $crate::DiagnosticId::Error(stringify!($code).to_owned()) }};
 }
-
-/// Wrapper around a `DiagnosticBuilder` for creating lints.
-pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, G>);
-
-impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> {
-    #[rustc_lint_diagnostics]
-    /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`.
-    pub fn build(mut self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'a, G> {
-        self.0.set_primary_message(msg);
-        self.0.set_is_lint();
-        self.0
-    }
-
-    /// Create a `LintDiagnosticBuilder` from some existing `DiagnosticBuilder`.
-    pub fn new(err: DiagnosticBuilder<'a, G>) -> LintDiagnosticBuilder<'a, G> {
-        LintDiagnosticBuilder(err)
-    }
-}
-
-impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> {
-    pub fn forget_guarantee(self) -> LintDiagnosticBuilder<'a, ()> {
-        LintDiagnosticBuilder(self.0.forget_guarantee())
-    }
-}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index d3effb7c1c0..7c312da6279 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -30,7 +30,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::sync::{self, Lock, Lrc};
 use rustc_data_structures::AtomicRef;
 pub use rustc_error_messages::{
-    fallback_fluent_bundle, fluent, fluent_bundle, DiagnosticMessage, FluentBundle,
+    fallback_fluent_bundle, fluent, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
     LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
     DEFAULT_LOCALE_RESOURCES,
 };
@@ -66,7 +66,7 @@ pub type PErr<'a> = DiagnosticBuilder<'a, ErrorGuaranteed>;
 pub type PResult<'a, T> = Result<T, PErr<'a>>;
 
 // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
-// (See also the comment on `DiagnosticBuilder`'s `diagnostic` field.)
+// (See also the comment on `DiagnosticBuilderInner`'s `diagnostic` field.)
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16);
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -374,7 +374,7 @@ pub use diagnostic::{
     AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay,
     DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
 };
-pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder};
+pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
 use std::backtrace::Backtrace;
 
 /// A handler deals with errors and other compiler output.
@@ -1134,6 +1134,12 @@ impl Handler {
         );
         std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations)
     }
+
+    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");
+    }
 }
 
 impl HandlerInner {
@@ -1205,7 +1211,7 @@ impl HandlerInner {
 
         if let Some(expectation_id) = diagnostic.level.get_expectation_id() {
             self.suppressed_expected_diag = true;
-            self.fulfilled_expectations.insert(expectation_id);
+            self.fulfilled_expectations.insert(expectation_id.normalize());
         }
 
         if matches!(diagnostic.level, Warning(_))
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 59a7b668a83..17a348ec6ba 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -110,10 +110,26 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
                 tokenstream::TokenTree::Token(token, spacing) => (token, spacing == Joint),
             };
 
+            // Split the operator into one or more `Punct`s, one per character.
+            // The final one inherits the jointness of the original token. Any
+            // before that get `joint = true`.
             let mut op = |s: &str| {
                 assert!(s.is_ascii());
-                trees.extend(s.as_bytes().iter().enumerate().map(|(idx, &ch)| {
-                    TokenTree::Punct(Punct { ch, joint: joint || idx != s.len() - 1, span })
+                trees.extend(s.bytes().enumerate().map(|(i, ch)| {
+                    let is_final = i == s.len() - 1;
+                    // Split the token span into single chars. Unless the span
+                    // is an unusual one, e.g. due to proc macro expansion. We
+                    // determine this by assuming any span with a length that
+                    // matches the operator length is a normal one, and any
+                    // span with a different length is an unusual one.
+                    let span = if (span.hi() - span.lo()).to_usize() == s.len() {
+                        let lo = span.lo() + BytePos::from_usize(i);
+                        let hi = lo + BytePos::from_usize(1);
+                        span.with_lo(lo).with_hi(hi)
+                    } else {
+                        span
+                    };
+                    TokenTree::Punct(Punct { ch, joint: if is_final { joint } else { true }, span })
                 }));
             };
 
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 700d9dab64b..5ee6c9f2387 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -499,6 +499,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
     ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
+    ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
     ungated!(
         rustc_default_body_unstable, Normal,
         template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index e7c26bd726f..f1f0c224bbd 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -314,74 +314,75 @@ pub enum Res<Id = hir::HirId> {
     /// **Belongs to the type namespace.**
     PrimTy(hir::PrimTy),
 
-    /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
-    /// optionally with the [`DefId`] of the item introducing the `Self` type alias.
+    /// The `Self` type, as used within a trait.
+    ///
+    /// **Belongs to the type namespace.**
+    ///
+    /// See the examples on [`Res::SelfTyAlias`] for details.
+    SelfTyParam {
+        /// The trait this `Self` is a generic parameter for.
+        trait_: DefId,
+    },
+
+    /// The `Self` type, as used somewhere other than within a trait.
     ///
     /// **Belongs to the type namespace.**
     ///
     /// Examples:
     /// ```
-    /// struct Bar(Box<Self>);
-    /// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
+    /// struct Bar(Box<Self>); // SelfTyAlias
     ///
     /// trait Foo {
-    ///     fn foo() -> Box<Self>;
-    ///     // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
+    ///     fn foo() -> Box<Self>; // SelfTyParam
     /// }
     ///
     /// impl Bar {
     ///     fn blah() {
-    ///         let _: Self;
-    ///         // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
+    ///         let _: Self; // SelfTyAlias
     ///     }
     /// }
     ///
     /// impl Foo for Bar {
-    ///     fn foo() -> Box<Self> {
-    ///     // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
-    ///         let _: Self;
-    ///         // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
+    ///     fn foo() -> Box<Self> { // SelfTyAlias
+    ///         let _: Self;        // SelfTyAlias
     ///
     ///         todo!()
     ///     }
     /// }
     /// ```
-    ///
     /// *See also [`Res::SelfCtor`].*
     ///
-    /// -----
-    ///
-    /// HACK(min_const_generics): self types also have an optional requirement to **not** mention
-    /// any generic parameters to allow the following with `min_const_generics`:
-    /// ```
-    /// # struct Foo;
-    /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
-    ///
-    /// struct Bar([u8; baz::<Self>()]);
-    /// const fn baz<T>() -> usize { 10 }
-    /// ```
-    /// We do however allow `Self` in repeat expression even if it is generic to not break code
-    /// which already works on stable while causing the `const_evaluatable_unchecked` future compat
-    /// lint:
-    /// ```
-    /// fn foo<T>() {
-    ///     let _bar = [1_u8; std::mem::size_of::<*mut T>()];
-    /// }
-    /// ```
-    // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
-    SelfTy {
-        /// The trait this `Self` is a generic arg for.
-        trait_: Option<DefId>,
+    SelfTyAlias {
         /// The item introducing the `Self` type alias. Can be used in the `type_of` query
-        /// to get the underlying type. Additionally whether the `Self` type is disallowed
-        /// from mentioning generics (i.e. when used in an anonymous constant).
-        alias_to: Option<(DefId, bool)>,
-    },
+        /// to get the underlying type.
+        alias_to: DefId,
 
-    /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
-    ///
-    /// **Belongs to the type namespace.**
-    ToolMod,
+        /// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an
+        /// anonymous constant).
+        ///
+        /// HACK(min_const_generics): self types also have an optional requirement to **not**
+        /// mention any generic parameters to allow the following with `min_const_generics`:
+        /// ```
+        /// # struct Foo;
+        /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
+        ///
+        /// struct Bar([u8; baz::<Self>()]);
+        /// const fn baz<T>() -> usize { 10 }
+        /// ```
+        /// We do however allow `Self` in repeat expression even if it is generic to not break code
+        /// which already works on stable while causing the `const_evaluatable_unchecked` future
+        /// compat lint:
+        /// ```
+        /// fn foo<T>() {
+        ///     let _bar = [1_u8; std::mem::size_of::<*mut T>()];
+        /// }
+        /// ```
+        // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
+        forbid_generic: bool,
+
+        /// Is this within an `impl Foo for bar`?
+        is_trait_impl: bool,
+    },
 
     // Value namespace
     /// The `Self` constructor, along with the [`DefId`]
@@ -389,7 +390,7 @@ pub enum Res<Id = hir::HirId> {
     ///
     /// **Belongs to the value namespace.**
     ///
-    /// *See also [`Res::SelfTy`].*
+    /// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].*
     SelfCtor(DefId),
 
     /// A local variable or function parameter.
@@ -397,6 +398,11 @@ pub enum Res<Id = hir::HirId> {
     /// **Belongs to the value namespace.**
     Local(Id),
 
+    /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
+    ///
+    /// **Belongs to the type namespace.**
+    ToolMod,
+
     // Macro namespace
     /// An attribute that is *not* implemented via macro.
     /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
@@ -606,7 +612,8 @@ impl<Id> Res<Id> {
 
             Res::Local(..)
             | Res::PrimTy(..)
-            | Res::SelfTy { .. }
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
             | Res::SelfCtor(..)
             | Res::ToolMod
             | Res::NonMacroAttr(..)
@@ -629,7 +636,7 @@ impl<Id> Res<Id> {
             Res::SelfCtor(..) => "self constructor",
             Res::PrimTy(..) => "builtin type",
             Res::Local(..) => "local variable",
-            Res::SelfTy { .. } => "self type",
+            Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
             Res::ToolMod => "tool module",
             Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
             Res::Err => "unresolved item",
@@ -652,7 +659,10 @@ impl<Id> Res<Id> {
             Res::SelfCtor(id) => Res::SelfCtor(id),
             Res::PrimTy(id) => Res::PrimTy(id),
             Res::Local(id) => Res::Local(map(id)),
-            Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
+            Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
+            Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
+                Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
+            }
             Res::ToolMod => Res::ToolMod,
             Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
             Res::Err => Res::Err,
@@ -665,7 +675,10 @@ impl<Id> Res<Id> {
             Res::SelfCtor(id) => Res::SelfCtor(id),
             Res::PrimTy(id) => Res::PrimTy(id),
             Res::Local(id) => Res::Local(map(id)?),
-            Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
+            Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
+            Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
+                Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
+            }
             Res::ToolMod => Res::ToolMod,
             Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
             Res::Err => Res::Err,
@@ -692,7 +705,9 @@ impl<Id> Res<Id> {
     pub fn ns(&self) -> Option<Namespace> {
         match self {
             Res::Def(kind, ..) => kind.ns(),
-            Res::PrimTy(..) | Res::SelfTy { .. } | Res::ToolMod => Some(Namespace::TypeNS),
+            Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
+                Some(Namespace::TypeNS)
+            }
             Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
             Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
             Res::Err => None,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index c1948052e3c..922ce738dbb 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -731,6 +731,7 @@ pub enum PredicateOrigin {
 /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
 #[derive(Debug, HashStable_Generic)]
 pub struct WhereBoundPredicate<'hir> {
+    pub hir_id: HirId,
     pub span: Span,
     /// Origin of the predicate.
     pub origin: PredicateOrigin,
@@ -2403,8 +2404,9 @@ impl<'hir> Ty<'hir> {
             return None;
         };
         match path.res {
-            Res::Def(DefKind::TyParam, def_id)
-            | Res::SelfTy { trait_: Some(def_id), alias_to: None } => Some((def_id, segment.ident)),
+            Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
+                Some((def_id, segment.ident))
+            }
             _ => None,
         }
     }
@@ -3532,9 +3534,10 @@ mod size_asserts {
     static_assert_size!(Param<'_>, 32);
     static_assert_size!(Pat<'_>, 72);
     static_assert_size!(PatKind<'_>, 48);
-    static_assert_size!(Path<'_>, 48);
-    static_assert_size!(PathSegment<'_>, 56);
+    static_assert_size!(Path<'_>, 40);
+    static_assert_size!(PathSegment<'_>, 48);
     static_assert_size!(QPath<'_>, 24);
+    static_assert_size!(Res, 12);
     static_assert_size!(Stmt<'_>, 32);
     static_assert_size!(StmtKind<'_>, 16);
     static_assert_size!(TraitItem<'_>, 88);
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 8f5f314ecae..8777a54ba09 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -847,20 +847,28 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
 ) {
     match *predicate {
         WherePredicate::BoundPredicate(WhereBoundPredicate {
+            hir_id,
             ref bounded_ty,
             bounds,
             bound_generic_params,
-            ..
+            origin: _,
+            span: _,
         }) => {
+            visitor.visit_id(hir_id);
             visitor.visit_ty(bounded_ty);
             walk_list!(visitor, visit_param_bound, bounds);
             walk_list!(visitor, visit_generic_param, bound_generic_params);
         }
-        WherePredicate::RegionPredicate(WhereRegionPredicate { ref lifetime, bounds, .. }) => {
+        WherePredicate::RegionPredicate(WhereRegionPredicate {
+            ref lifetime,
+            bounds,
+            span: _,
+            in_where_clause: _,
+        }) => {
             visitor.visit_lifetime(lifetime);
             walk_list!(visitor, visit_param_bound, bounds);
         }
-        WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
+        WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span: _ }) => {
             visitor.visit_ty(lhs_ty);
             visitor.visit_ty(rhs_ty);
         }
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index afac75de2d9..b66e59d8ac6 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -448,8 +448,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let infer_lifetimes =
             (gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();
 
-        if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() {
-            Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span);
+        if gen_pos != GenericArgPosition::Type && let Some(b) = gen_args.bindings.first() {
+            Self::prohibit_assoc_ty_binding(tcx, b.span);
         }
 
         let explicit_late_bound =
@@ -649,9 +649,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     LATE_BOUND_LIFETIME_ARGUMENTS,
                     args.args[0].hir_id(),
                     multispan,
-                    |lint| {
-                        lint.build(msg).emit();
-                    },
+                    msg,
+                    |lint| lint,
                 );
             }
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 244018ebbeb..6e373e41b4c 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -276,9 +276,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             item_segment.infer_args,
             None,
         );
-        let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args());
-
-        if let Some(b) = assoc_bindings.first() {
+        if let Some(b) = item_segment.args().bindings.first() {
             Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
         }
 
@@ -605,8 +603,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             None,
         );
 
-        let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args());
-        if let Some(b) = assoc_bindings.first() {
+        if let Some(b) = item_segment.args().bindings.first() {
             Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
         }
 
@@ -794,8 +791,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             trait_segment,
             is_impl,
         );
-        let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args());
-        if let Some(b) = assoc_bindings.first() {
+        if let Some(b) = trait_segment.args().bindings.first() {
             Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
         }
         ty::TraitRef::new(trait_def_id, substs)
@@ -1902,7 +1898,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         // Find the type of the associated item, and the trait where the associated
         // item is declared.
         let bound = match (&qself_ty.kind(), qself_res) {
-            (_, Res::SelfTy { trait_: Some(_), alias_to: Some((impl_def_id, _)) }) => {
+            (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
                 // `Self` in an impl of a trait -- we have a concrete self type and a
                 // trait reference.
                 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
@@ -1921,8 +1917,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             (
                 &ty::Param(_),
-                Res::SelfTy { trait_: Some(param_did), alias_to: None }
-                | Res::Def(DefKind::TyParam, param_did),
+                Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
             ) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?,
             _ => {
                 let reported = if variant_resolution.is_some() {
@@ -2015,30 +2010,35 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         tcx.check_stability(item.def_id, Some(hir_ref_id), span, None);
 
         if let Some(variant_def_id) = variant_resolution {
-            tcx.struct_span_lint_hir(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
-                let mut err = lint.build("ambiguous associated item");
-                let mut could_refer_to = |kind: DefKind, def_id, also| {
-                    let note_msg = format!(
-                        "`{}` could{} refer to the {} defined here",
-                        assoc_ident,
-                        also,
-                        kind.descr(def_id)
-                    );
-                    err.span_note(tcx.def_span(def_id), &note_msg);
-                };
+            tcx.struct_span_lint_hir(
+                AMBIGUOUS_ASSOCIATED_ITEMS,
+                hir_ref_id,
+                span,
+                "ambiguous associated item",
+                |lint| {
+                    let mut could_refer_to = |kind: DefKind, def_id, also| {
+                        let note_msg = format!(
+                            "`{}` could{} refer to the {} defined here",
+                            assoc_ident,
+                            also,
+                            kind.descr(def_id)
+                        );
+                        lint.span_note(tcx.def_span(def_id), &note_msg);
+                    };
 
-                could_refer_to(DefKind::Variant, variant_def_id, "");
-                could_refer_to(kind, item.def_id, " also");
+                    could_refer_to(DefKind::Variant, variant_def_id, "");
+                    could_refer_to(kind, item.def_id, " also");
 
-                err.span_suggestion(
-                    span,
-                    "use fully-qualified syntax",
-                    format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
-                    Applicability::MachineApplicable,
-                );
+                    lint.span_suggestion(
+                        span,
+                        "use fully-qualified syntax",
+                        format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
+                        Applicability::MachineApplicable,
+                    );
 
-                err.emit();
-            });
+                    lint
+                },
+            );
         }
         Ok((ty, kind, item.def_id))
     }
@@ -2208,8 +2208,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         for segment in segments {
             // Only emit the first error to avoid overloading the user with error messages.
-            if let [binding, ..] = segment.args().bindings {
-                Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
+            if let Some(b) = segment.args().bindings.first() {
+                Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
                 return true;
             }
         }
@@ -2417,7 +2417,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
                 tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
             }
-            Res::SelfTy { trait_: Some(_), alias_to: None } => {
+            Res::SelfTyParam { .. } => {
                 // `Self` in trait or type alias.
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(path.segments.iter(), |err| {
@@ -2432,7 +2432,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 });
                 tcx.types.self_param
             }
-            Res::SelfTy { trait_: _, alias_to: Some((def_id, forbid_generic)) } => {
+            Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
                 // `Self` in impl (we know the concrete type).
                 assert_eq!(opt_self_ty, None);
                 // Try to evaluate any array length constants.
@@ -3084,15 +3084,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     BARE_TRAIT_OBJECTS,
                     self_ty.hir_id,
                     self_ty.span,
+                    msg,
                     |lint| {
-                        let mut diag = lint.build(msg);
-                        diag.multipart_suggestion_verbose(
+                        lint.multipart_suggestion_verbose(
                             "use `dyn`",
                             sugg,
                             Applicability::MachineApplicable,
                         );
-                        self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
-                        diag.emit();
+                        self.maybe_lint_blanket_trait_impl(&self_ty, lint);
+                        lint
                     },
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/check/callee.rs b/compiler/rustc_hir_analysis/src/check/callee.rs
index c82a31e65cf..080771844a4 100644
--- a/compiler/rustc_hir_analysis/src/check/callee.rs
+++ b/compiler/rustc_hir_analysis/src/check/callee.rs
@@ -394,140 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ty::FnPtr(sig) => (sig, None),
             _ => {
-                let mut unit_variant = None;
-                if let hir::ExprKind::Path(qpath) = &callee_expr.kind
-                    && let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _)
-                        = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
-                    // Only suggest removing parens if there are no arguments
-                    && arg_exprs.is_empty()
-                {
-                    let descr = match kind {
-                        def::CtorOf::Struct => "struct",
-                        def::CtorOf::Variant => "enum variant",
-                    };
-                    let removal_span =
-                        callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
-                    unit_variant =
-                        Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath)));
-                }
-
-                let callee_ty = self.resolve_vars_if_possible(callee_ty);
-                let mut err = type_error_struct!(
-                    self.tcx.sess,
-                    callee_expr.span,
-                    callee_ty,
-                    E0618,
-                    "expected function, found {}",
-                    match &unit_variant {
-                        Some((_, kind, path)) => format!("{kind} `{path}`"),
-                        None => format!("`{callee_ty}`"),
-                    }
-                );
-
-                self.identify_bad_closure_def_and_call(
-                    &mut err,
-                    call_expr.hir_id,
-                    &callee_expr.kind,
-                    callee_expr.span,
-                );
-
-                if let Some((removal_span, kind, path)) = &unit_variant {
-                    err.span_suggestion_verbose(
-                        *removal_span,
-                        &format!(
-                            "`{path}` is a unit {kind}, and does not take parentheses to be constructed",
-                        ),
-                        "",
-                        Applicability::MachineApplicable,
-                    );
-                }
-
-                let mut inner_callee_path = None;
-                let def = match callee_expr.kind {
-                    hir::ExprKind::Path(ref qpath) => {
-                        self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
-                    }
-                    hir::ExprKind::Call(ref inner_callee, _) => {
-                        // If the call spans more than one line and the callee kind is
-                        // itself another `ExprCall`, that's a clue that we might just be
-                        // missing a semicolon (Issue #51055)
-                        let call_is_multiline =
-                            self.tcx.sess.source_map().is_multiline(call_expr.span);
-                        if call_is_multiline {
-                            err.span_suggestion(
-                                callee_expr.span.shrink_to_hi(),
-                                "consider using a semicolon here",
-                                ";",
-                                Applicability::MaybeIncorrect,
-                            );
-                        }
-                        if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind {
-                            inner_callee_path = Some(inner_qpath);
-                            self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id)
-                        } else {
-                            Res::Err
-                        }
-                    }
-                    _ => Res::Err,
-                };
-
-                if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
-                    if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_expr, callee_ty)
-                        && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
-                    {
-                        let descr = match maybe_def {
-                            DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id),
-                            DefIdOrName::Name(name) => name,
-                        };
-                        err.span_label(
-                            callee_expr.span,
-                            format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called")
-                        );
-                        if let DefIdOrName::DefId(def_id) = maybe_def
-                            && let Some(def_span) = self.tcx.hir().span_if_local(def_id)
-                        {
-                            err.span_label(def_span, "the callable type is defined here");
-                        }
-                    } else {
-                        err.span_label(call_expr.span, "call expression requires function");
-                    }
-                }
-
-                if let Some(span) = self.tcx.hir().res_span(def) {
-                    let callee_ty = callee_ty.to_string();
-                    let label = match (unit_variant, inner_callee_path) {
-                        (Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")),
-                        (_, Some(hir::QPath::Resolved(_, path))) => self
-                            .tcx
-                            .sess
-                            .source_map()
-                            .span_to_snippet(path.span)
-                            .ok()
-                            .map(|p| format!("`{p}` defined here returns `{callee_ty}`")),
-                        _ => {
-                            match def {
-                                // Emit a different diagnostic for local variables, as they are not
-                                // type definitions themselves, but rather variables *of* that type.
-                                Res::Local(hir_id) => Some(format!(
-                                    "`{}` has type `{}`",
-                                    self.tcx.hir().name(hir_id),
-                                    callee_ty
-                                )),
-                                Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
-                                    Some(format!(
-                                        "`{}` defined here",
-                                        self.tcx.def_path_str(def_id),
-                                    ))
-                                }
-                                _ => Some(format!("`{callee_ty}` defined here")),
-                            }
-                        }
-                    };
-                    if let Some(label) = label {
-                        err.span_label(span, label);
-                    }
-                }
-                err.emit();
+                self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
 
                 // This is the "default" function signature, used in case of error.
                 // In that case, we check each argument against "error" in order to
@@ -574,6 +441,145 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fn_sig.output()
     }
 
+    fn report_invalid_callee(
+        &self,
+        call_expr: &'tcx hir::Expr<'tcx>,
+        callee_expr: &'tcx hir::Expr<'tcx>,
+        callee_ty: Ty<'tcx>,
+        arg_exprs: &'tcx [hir::Expr<'tcx>],
+    ) {
+        let mut unit_variant = None;
+        if let hir::ExprKind::Path(qpath) = &callee_expr.kind
+            && let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _)
+                = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
+            // Only suggest removing parens if there are no arguments
+            && arg_exprs.is_empty()
+        {
+            let descr = match kind {
+                def::CtorOf::Struct => "struct",
+                def::CtorOf::Variant => "enum variant",
+            };
+            let removal_span =
+                callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
+            unit_variant =
+                Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath)));
+        }
+
+        let callee_ty = self.resolve_vars_if_possible(callee_ty);
+        let mut err = type_error_struct!(
+            self.tcx.sess,
+            callee_expr.span,
+            callee_ty,
+            E0618,
+            "expected function, found {}",
+            match &unit_variant {
+                Some((_, kind, path)) => format!("{kind} `{path}`"),
+                None => format!("`{callee_ty}`"),
+            }
+        );
+
+        self.identify_bad_closure_def_and_call(
+            &mut err,
+            call_expr.hir_id,
+            &callee_expr.kind,
+            callee_expr.span,
+        );
+
+        if let Some((removal_span, kind, path)) = &unit_variant {
+            err.span_suggestion_verbose(
+                *removal_span,
+                &format!(
+                    "`{path}` is a unit {kind}, and does not take parentheses to be constructed",
+                ),
+                "",
+                Applicability::MachineApplicable,
+            );
+        }
+
+        let mut inner_callee_path = None;
+        let def = match callee_expr.kind {
+            hir::ExprKind::Path(ref qpath) => {
+                self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
+            }
+            hir::ExprKind::Call(ref inner_callee, _) => {
+                // If the call spans more than one line and the callee kind is
+                // itself another `ExprCall`, that's a clue that we might just be
+                // missing a semicolon (Issue #51055)
+                let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span);
+                if call_is_multiline {
+                    err.span_suggestion(
+                        callee_expr.span.shrink_to_hi(),
+                        "consider using a semicolon here",
+                        ";",
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind {
+                    inner_callee_path = Some(inner_qpath);
+                    self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id)
+                } else {
+                    Res::Err
+                }
+            }
+            _ => Res::Err,
+        };
+
+        if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
+            if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_expr, callee_ty)
+                && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span)
+            {
+                let descr = match maybe_def {
+                    DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id),
+                    DefIdOrName::Name(name) => name,
+                };
+                err.span_label(
+                    callee_expr.span,
+                    format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called")
+                );
+                if let DefIdOrName::DefId(def_id) = maybe_def
+                    && let Some(def_span) = self.tcx.hir().span_if_local(def_id)
+                {
+                    err.span_label(def_span, "the callable type is defined here");
+                }
+            } else {
+                err.span_label(call_expr.span, "call expression requires function");
+            }
+        }
+
+        if let Some(span) = self.tcx.hir().res_span(def) {
+            let callee_ty = callee_ty.to_string();
+            let label = match (unit_variant, inner_callee_path) {
+                (Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")),
+                (_, Some(hir::QPath::Resolved(_, path))) => self
+                    .tcx
+                    .sess
+                    .source_map()
+                    .span_to_snippet(path.span)
+                    .ok()
+                    .map(|p| format!("`{p}` defined here returns `{callee_ty}`")),
+                _ => {
+                    match def {
+                        // Emit a different diagnostic for local variables, as they are not
+                        // type definitions themselves, but rather variables *of* that type.
+                        Res::Local(hir_id) => Some(format!(
+                            "`{}` has type `{}`",
+                            self.tcx.hir().name(hir_id),
+                            callee_ty
+                        )),
+                        Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
+                            Some(format!("`{}` defined here", self.tcx.def_path_str(def_id),))
+                        }
+                        _ => Some(format!("`{callee_ty}` defined here")),
+                    }
+                }
+            };
+            if let Some(label) = label {
+                err.span_label(span, label);
+            }
+        }
+        err.emit();
+    }
+
     fn confirm_deferred_closure_call(
         &self,
         call_expr: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_analysis/src/check/cast.rs b/compiler/rustc_hir_analysis/src/check/cast.rs
index 81a979865ac..01badc133c9 100644
--- a/compiler/rustc_hir_analysis/src/check/cast.rs
+++ b/compiler/rustc_hir_analysis/src/check/cast.rs
@@ -33,7 +33,7 @@ use super::FnCtxt;
 use crate::hir::def_id::DefId;
 use crate::type_error_struct;
 use hir::def_id::LOCAL_CRATE;
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode};
 use rustc_middle::mir::Mutability;
@@ -754,19 +754,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         } else {
             ("", lint::builtin::TRIVIAL_CASTS)
         };
-        fcx.tcx.struct_span_lint_hir(lint, self.expr.hir_id, self.span, |err| {
-            err.build(&format!(
-                "trivial {}cast: `{}` as `{}`",
-                adjective,
-                fcx.ty_to_string(t_expr),
-                fcx.ty_to_string(t_cast)
-            ))
-            .help(&format!(
-                "cast can be replaced by coercion; this might \
-                                   require {type_asc_or}a temporary variable"
-            ))
-            .emit();
-        });
+        fcx.tcx.struct_span_lint_hir(
+            lint,
+            self.expr.hir_id,
+            self.span,
+            DelayDm(|| {
+                format!(
+                    "trivial {}cast: `{}` as `{}`",
+                    adjective,
+                    fcx.ty_to_string(t_expr),
+                    fcx.ty_to_string(t_cast)
+                )
+            }),
+            |lint| {
+                lint.help(format!(
+                    "cast can be replaced by coercion; this might \
+                     require {type_asc_or}a temporary variable"
+                ))
+            },
+        );
     }
 
     #[instrument(skip(fcx), level = "debug")]
@@ -1074,12 +1080,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 lint::builtin::CENUM_IMPL_DROP_CAST,
                 self.expr.hir_id,
                 self.span,
-                |err| {
-                    err.build(&format!(
-                        "cannot cast enum `{}` into integer `{}` because it implements `Drop`",
-                        self.expr_ty, self.cast_ty
-                    ))
-                    .emit();
+                DelayDm(|| format!(
+                    "cannot cast enum `{}` into integer `{}` because it implements `Drop`",
+                    self.expr_ty, self.cast_ty
+                )),
+                |lint| {
+                    lint
                 },
             );
         }
@@ -1090,12 +1096,11 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             lint::builtin::LOSSY_PROVENANCE_CASTS,
             self.expr.hir_id,
             self.span,
-            |err| {
-                let mut err = err.build(&format!(
+            DelayDm(|| format!(
                     "under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`",
                     self.expr_ty, self.cast_ty
-                ));
-
+                )),
+            |lint| {
                 let msg = "use `.addr()` to obtain the address of a pointer";
 
                 let expr_prec = self.expr.precedence().order();
@@ -1114,9 +1119,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         (cast_span, format!(").addr(){scalar_cast}")),
                     ];
 
-                    err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
+                    lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
                 } else {
-                    err.span_suggestion(
+                    lint.span_suggestion(
                         cast_span,
                         msg,
                         format!(".addr(){scalar_cast}"),
@@ -1124,12 +1129,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     );
                 }
 
-                err.help(
+                lint.help(
                     "if you can't comply with strict provenance and need to expose the pointer \
                     provenance you can use `.expose_addr()` instead"
                 );
 
-                err.emit();
+                lint
             },
         );
     }
@@ -1139,24 +1144,24 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             lint::builtin::FUZZY_PROVENANCE_CASTS,
             self.expr.hir_id,
             self.span,
-            |err| {
-                let mut err = err.build(&format!(
-                    "strict provenance disallows casting integer `{}` to pointer `{}`",
-                    self.expr_ty, self.cast_ty
-                ));
+            DelayDm(|| format!(
+                "strict provenance disallows casting integer `{}` to pointer `{}`",
+                self.expr_ty, self.cast_ty
+            )),
+            |lint| {
                 let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address";
                 let suggestions = vec![
                     (self.expr_span.shrink_to_lo(), String::from("(...).with_addr(")),
                     (self.expr_span.shrink_to_hi().to(self.cast_span), String::from(")")),
                 ];
 
-                err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
-                err.help(
+                lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
+                lint.help(
                     "if you can't comply with strict provenance and don't have a pointer with \
                     the correct provenance you can use `std::ptr::from_exposed_addr()` instead"
                  );
 
-                err.emit();
+                lint
             },
         );
     }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index d82ee8f48c5..824144aeac0 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -48,9 +48,13 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
             .emit();
         }
         None => {
-            tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
-                lint.build("use of calling convention not supported on this target").emit();
-            });
+            tcx.struct_span_lint_hir(
+                UNSUPPORTED_CALLING_CONVENTIONS,
+                hir_id,
+                span,
+                "use of calling convention not supported on this target",
+                |lint| lint,
+            );
         }
     }
 
@@ -510,10 +514,10 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
             UNINHABITED_STATIC,
             tcx.hir().local_def_id_to_hir_id(def_id),
             span,
+            "static of uninhabited type",
             |lint| {
-                lint.build("static of uninhabited type")
+                lint
                 .note("uninhabited statics cannot be initialized, and any access would be an immediate error")
-                .emit();
             },
         );
     }
@@ -609,9 +613,12 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
         fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
             match arg.kind {
                 hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
-                    [PathSegment { res: Res::SelfTy { trait_: _, alias_to: impl_ref }, .. }] => {
-                        let impl_ty_name =
-                            impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id));
+                    [PathSegment { res: Res::SelfTyParam { .. }, .. }] => {
+                        let impl_ty_name = None;
+                        self.selftys.push((path.span, impl_ty_name));
+                    }
+                    [PathSegment { res: Res::SelfTyAlias { alias_to: def_id, .. }, .. }] => {
+                        let impl_ty_name = Some(self.tcx.def_path_str(*def_id));
                         self.selftys.push((path.span, impl_ty_name));
                     }
                     _ => {}
@@ -1434,6 +1441,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
                 REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
                 tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()),
                 span,
+                "zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types",
                 |lint| {
                     let note = if non_exhaustive {
                         "is marked with `#[non_exhaustive]`"
@@ -1441,10 +1449,9 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD
                         "contains private fields"
                     };
                     let field_ty = tcx.def_path_str_with_substs(def_id, substs);
-                    lint.build("zero-sized fields in repr(transparent) cannot contain external non-exhaustive types")
+                    lint
                         .note(format!("this {descr} contains `{field_ty}`, which {note}, \
                             and makes it not a breaking change to become non-zero-sized in the future."))
-                        .emit();
                 },
             )
         }
diff --git a/compiler/rustc_hir_analysis/src/check/demand.rs b/compiler/rustc_hir_analysis/src/check/demand.rs
index 264df8b914b..d396c801c09 100644
--- a/compiler/rustc_hir_analysis/src/check/demand.rs
+++ b/compiler/rustc_hir_analysis/src/check/demand.rs
@@ -32,17 +32,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error: Option<TypeError<'tcx>>,
     ) {
         self.annotate_expected_due_to_let_ty(err, expr, error);
-        self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr);
-        self.suggest_compatible_variants(err, expr, expected, expr_ty);
-        self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty);
-        if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
-            return;
-        }
-        self.suggest_no_capture_closure(err, expected, expr_ty);
-        self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
-        self.suggest_missing_parentheses(err, expr);
-        self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected);
-        self.suggest_copied_or_cloned(err, expr, expr_ty, expected);
+
+        // Use `||` to give these suggestions a precedence
+        let _ = self.suggest_missing_parentheses(err, expr)
+            || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
+            || self.suggest_compatible_variants(err, expr, expected, expr_ty)
+            || self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty)
+            || self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty)
+            || self.suggest_no_capture_closure(err, expected, expr_ty)
+            || self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty)
+            || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
+            || self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
+            || self.suggest_into(err, expr, expr_ty, expected);
+
         self.note_type_is_not_clone(err, expected, expr_ty, expr);
         self.note_need_for_fn_pointer(err, expected, expr_ty);
         self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
@@ -286,7 +288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         expr_ty: Ty<'tcx>,
-    ) {
+    ) -> bool {
         if let ty::Adt(expected_adt, substs) = expected.kind() {
             if let hir::ExprKind::Field(base, ident) = expr.kind {
                 let base_ty = self.typeck_results.borrow().expr_ty(base);
@@ -299,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "",
                         Applicability::MaybeIncorrect,
                     );
-                    return
+                    return true;
                 }
             }
 
@@ -338,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did()) {
                                 vec!["None", "Some(())"]
                             } else {
-                                return;
+                                return false;
                             };
                             if let Some(indent) =
                                 self.tcx.sess.source_map().indentation_before(span.shrink_to_lo())
@@ -358,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     Applicability::MaybeIncorrect,
                                 );
                             }
-                            return;
+                            return true;
                         }
                     }
                 }
@@ -445,6 +447,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         suggestions_for(&**variant, *ctor_kind, *field_name),
                         Applicability::MaybeIncorrect,
                     );
+                    return true;
                 }
                 _ => {
                     // More than one matching variant.
@@ -460,9 +463,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ),
                         Applicability::MaybeIncorrect,
                     );
+                    return true;
                 }
             }
         }
+
+        false
     }
 
     fn suggest_non_zero_new_unwrap(
@@ -471,19 +477,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         expr_ty: Ty<'tcx>,
-    ) {
+    ) -> bool {
         let tcx = self.tcx;
         let (adt, unwrap) = match expected.kind() {
             // In case Option<NonZero*> is wanted, but * is provided, suggest calling new
             ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
                 // Unwrap option
-                let ty::Adt(adt, _) = substs.type_at(0).kind() else { return };
+                let ty::Adt(adt, _) = substs.type_at(0).kind() else { return false; };
 
                 (adt, "")
             }
             // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
             ty::Adt(adt, _) => (adt, ".unwrap()"),
-            _ => return,
+            _ => return false,
         };
 
         let map = [
@@ -502,7 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let Some((s, _)) = map
             .iter()
             .find(|&&(s, t)| self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t))
-            else { return };
+            else { return false; };
 
         let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);
 
@@ -514,6 +520,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ],
             Applicability::MaybeIncorrect,
         );
+
+        true
     }
 
     pub fn get_conversion_methods(
diff --git a/compiler/rustc_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs
index 48a4f40780b..b9459887c46 100644
--- a/compiler/rustc_hir_analysis/src/check/expr.rs
+++ b/compiler/rustc_hir_analysis/src/check/expr.rs
@@ -41,6 +41,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
 use rustc_middle::ty::error::TypeError::FieldMisMatch;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitable};
+use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_session::parse::feature_err;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
@@ -394,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Some(sp) =
                             tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
                         {
-                            tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
+                            err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
                         }
                         err.emit();
                         oprnd_t = tcx.ty_error();
@@ -541,7 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // been resolved or we errored. This is important as we can only check transmute
                 // on concrete types, but the output type may not be known yet (it would only
                 // be known if explicitly specified via turbofish).
-                self.deferred_transmute_checks.borrow_mut().push((from, to, expr.span));
+                self.deferred_transmute_checks.borrow_mut().push((from, to, expr.hir_id));
             }
             if !tcx.features().unsized_fn_params {
                 // We want to remove some Sized bounds from std functions,
diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs
index 4522678802b..e51e5280620 100644
--- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs
@@ -58,17 +58,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
 
-                self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
-                    let msg = format!("unreachable {}", kind);
-                    lint.build(&msg)
-                        .span_label(span, &msg)
-                        .span_label(
+                let msg = format!("unreachable {}", kind);
+                self.tcx().struct_span_lint_hir(
+                    lint::builtin::UNREACHABLE_CODE,
+                    id,
+                    span,
+                    &msg,
+                    |lint| {
+                        lint.span_label(span, &msg).span_label(
                             orig_span,
                             custom_note
                                 .unwrap_or("any code following this expression is unreachable"),
                         )
-                        .emit();
-                })
+                    },
+                )
             }
         }
     }
@@ -88,14 +91,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
     ) -> Ty<'tcx> {
         // No Infer()? Nothing needs doing.
-        if !ty.has_infer_types_or_consts() {
+        if !ty.has_non_region_infer() {
             debug!("no inference var, nothing needs doing");
             return ty;
         }
 
         // If `ty` is a type variable, see whether we already know what it is.
         ty = self.resolve_vars_if_possible(ty);
-        if !ty.has_infer_types_or_consts() {
+        if !ty.has_non_region_infer() {
             debug!(?ty);
             return ty;
         }
diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
index 64e7fa1a42b..13e74021b9e 100644
--- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
@@ -50,8 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(in super::super) fn check_transmutes(&self) {
         let mut deferred_transmute_checks = self.deferred_transmute_checks.borrow_mut();
         debug!("FnCtxt::check_transmutes: {} deferred checks", deferred_transmute_checks.len());
-        for (from, to, span) in deferred_transmute_checks.drain(..) {
-            self.check_transmute(span, from, to);
+        for (from, to, hir_id) in deferred_transmute_checks.drain(..) {
+            self.check_transmute(from, to, hir_id);
         }
     }
 
@@ -63,7 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let get_operand_ty = |expr| {
                 let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
                 let ty = self.resolve_vars_if_possible(ty);
-                if ty.has_infer_types_or_consts() {
+                if ty.has_non_region_infer() {
                     assert!(self.is_tainted_by_errors());
                     self.tcx.ty_error()
                 } else {
@@ -1199,7 +1199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 _ => bug!("unexpected type: {:?}", ty),
             },
             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
-            | Res::SelfTy { .. } => match ty.kind() {
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. } => match ty.kind() {
                 ty::Adt(adt, substs) if !adt.is_enum() => {
                     Some((adt.non_enum_variant(), adt.did(), substs))
                 }
diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
index c32d1309031..09890c55cd3 100644
--- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
@@ -3,7 +3,7 @@ use crate::astconv::AstConv;
 use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
 
 use hir::def_id::DefId;
-use rustc_ast::util::parser::ExprPrecedence;
+use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
 use rustc_errors::{Applicability, Diagnostic, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind};
@@ -15,6 +15,7 @@ use rustc_infer::infer::{self, TyCtxtInferExt};
 use rustc_infer::traits::{self, StatementAsExpression};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Binder, IsSuggestable, ToPredicate, Ty};
+use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::infer::InferCtxtExt;
@@ -64,7 +65,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// When encountering an fn-like type, try accessing the output of the type
-    /// // and suggesting calling it if it satisfies a predicate (i.e. if the
+    /// and suggesting calling it if it satisfies a predicate (i.e. if the
     /// output has a method or a field):
     /// ```compile_fail,E0308
     /// fn foo(x: usize) -> usize { x }
@@ -138,7 +139,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 sugg,
                 applicability,
             );
-
             return true;
         }
         false
@@ -327,7 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
-    ) {
+    ) -> bool {
         let expr = expr.peel_blocks();
         if let Some((sp, msg, suggestion, applicability, verbose)) =
             self.check_ref(expr, found, expected)
@@ -337,12 +337,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 err.span_suggestion(sp, &msg, suggestion, applicability);
             }
+            return true;
+        } else if self.suggest_else_fn_with_closure(err, expr, found, expected)
+        {
+            return true;
         } else if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected))
             && let ty::FnDef(def_id, ..) = &found.kind()
             && let Some(sp) = self.tcx.hir().span_if_local(*def_id)
         {
             err.span_label(sp, format!("{found} defined here"));
-        } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
+            return true;
+        } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
+            return true;
+        } else {
             let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
             if !methods.is_empty() {
                 let mut suggestions = methods.iter()
@@ -393,6 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         suggestions,
                         Applicability::MaybeIncorrect,
                     );
+                    return true;
                 }
             } else if let ty::Adt(found_adt, found_substs) = found.kind()
                 && self.tcx.is_diagnostic_item(sym::Option, found_adt.did())
@@ -417,9 +425,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         format!(".map(|x| &*{}x)", "*".repeat(ref_cnt)),
                         Applicability::MaybeIncorrect,
                     );
+                    return true;
                 }
             }
         }
+
+        false
     }
 
     /// When encountering the expected boxed value allocated in the stack, suggest allocating it
@@ -430,13 +441,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
-    ) {
+    ) -> bool {
         if self.tcx.hir().is_inside_const_context(expr.hir_id) {
             // Do not suggest `Box::new` in const context.
-            return;
+            return false;
         }
         if !expected.is_box() || found.is_box() {
-            return;
+            return false;
         }
         let boxed_found = self.tcx.mk_box(found);
         if self.can_coerce(boxed_found, expected) {
@@ -454,6 +465,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                  https://doc.rust-lang.org/rust-by-example/std/box.html, and \
                  https://doc.rust-lang.org/std/boxed/index.html",
             );
+            true
+        } else {
+            false
         }
     }
 
@@ -464,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err: &mut Diagnostic,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
-    ) {
+    ) -> bool {
         if let (ty::FnPtr(_), ty::Closure(def_id, _)) = (expected.kind(), found.kind()) {
             if let Some(upvars) = self.tcx.upvars_mentioned(*def_id) {
                 // Report upto four upvars being captured to reduce the amount error messages
@@ -488,8 +502,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     multi_span,
                     "closures can only be coerced to `fn` types if they do not capture any variables"
                 );
+                return true;
             }
         }
+        false
     }
 
     /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
@@ -891,11 +907,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
-    ) {
+    ) -> bool {
         let sp = self.tcx.sess.source_map().start_point(expr.span);
         if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
             // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
-            self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp);
+            err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
+            true
+        } else {
+            false
         }
     }
 
@@ -908,7 +927,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         mut expr: &hir::Expr<'_>,
         mut expr_ty: Ty<'tcx>,
         mut expected_ty: Ty<'tcx>,
-    ) {
+    ) -> bool {
         loop {
             match (&expr.kind, expr_ty.kind(), expected_ty.kind()) {
                 (
@@ -922,9 +941,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
                 (hir::ExprKind::Block(blk, _), _, _) => {
                     self.suggest_block_to_brackets(diag, *blk, expr_ty, expected_ty);
-                    break;
+                    break true;
                 }
-                _ => break,
+                _ => break false,
             }
         }
     }
@@ -935,11 +954,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
-    ) {
-        let ty::Adt(adt_def, substs) = expr_ty.kind() else { return; };
-        let ty::Adt(expected_adt_def, expected_substs) = expected_ty.kind() else { return; };
+    ) -> bool {
+        let ty::Adt(adt_def, substs) = expr_ty.kind() else { return false; };
+        let ty::Adt(expected_adt_def, expected_substs) = expected_ty.kind() else { return false; };
         if adt_def != expected_adt_def {
-            return;
+            return false;
         }
 
         let mut suggest_copied_or_cloned = || {
@@ -958,6 +977,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ".copied()",
                         Applicability::MachineApplicable,
                     );
+                    return true;
                 } else if let Some(clone_did) = self.tcx.lang_items().clone_trait()
                     && rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
                         self,
@@ -975,8 +995,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ".cloned()",
                         Applicability::MachineApplicable,
                     );
+                    return true;
                 }
             }
+            false
         };
 
         if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result)
@@ -984,12 +1006,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Check that the error types are equal
             && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)).is_ok()
         {
-            suggest_copied_or_cloned();
+            return suggest_copied_or_cloned();
         } else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option)
             && adt_def.did() == option_did
         {
-            suggest_copied_or_cloned();
+            return suggest_copied_or_cloned();
+        }
+
+        false
+    }
+
+    pub(crate) fn suggest_into(
+        &self,
+        diag: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        expr_ty: Ty<'tcx>,
+        expected_ty: Ty<'tcx>,
+    ) -> bool {
+        let expr = expr.peel_blocks();
+
+        // We have better suggestions for scalar interconversions...
+        if expr_ty.is_scalar() && expected_ty.is_scalar() {
+            return false;
+        }
+
+        // Don't suggest turning a block into another type (e.g. `{}.into()`)
+        if matches!(expr.kind, hir::ExprKind::Block(..)) {
+            return false;
+        }
+
+        // We'll later suggest `.as_ref` when noting the type error,
+        // so skip if we will suggest that instead.
+        if self.should_suggest_as_ref(expected_ty, expr_ty).is_some() {
+            return false;
+        }
+
+        if let Some(into_def_id) = self.tcx.get_diagnostic_item(sym::Into)
+            && self.predicate_must_hold_modulo_regions(&traits::Obligation::new(
+                self.misc(expr.span),
+                self.param_env,
+                ty::Binder::dummy(ty::TraitRef {
+                    def_id: into_def_id,
+                    substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]),
+                })
+                .to_poly_trait_predicate()
+                .to_predicate(self.tcx),
+            ))
+        {
+            let sugg = if expr.precedence().order() >= PREC_POSTFIX {
+                vec![(expr.span.shrink_to_hi(), ".into()".to_owned())]
+            } else {
+                vec![(expr.span.shrink_to_lo(), "(".to_owned()), (expr.span.shrink_to_hi(), ").into()".to_owned())]
+            };
+            diag.multipart_suggestion(
+                format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
+                sugg,
+                Applicability::MaybeIncorrect
+            );
+            return true;
         }
+
+        false
     }
 
     /// Suggest wrapping the block in square brackets instead of curly braces
@@ -1121,7 +1198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 err.span_suggestion_short(
                     span_semi,
-                    "remove this semicolon",
+                    "remove this semicolon to return this value",
                     "",
                     Applicability::MachineApplicable,
                 );
diff --git a/compiler/rustc_hir_analysis/src/check/generator_interior.rs b/compiler/rustc_hir_analysis/src/check/generator_interior.rs
index 254a19368bf..898419b5b23 100644
--- a/compiler/rustc_hir_analysis/src/check/generator_interior.rs
+++ b/compiler/rustc_hir_analysis/src/check/generator_interior.rs
@@ -6,7 +6,7 @@
 use self::drop_ranges::DropRanges;
 use super::FnCtxt;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
-use rustc_errors::pluralize;
+use rustc_errors::{pluralize, DelayDm};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -610,33 +610,33 @@ fn check_must_not_suspend_def(
             rustc_session::lint::builtin::MUST_NOT_SUSPEND,
             hir_id,
             data.source_span,
-            |lint| {
-                let msg = format!(
+            DelayDm(|| {
+                format!(
                     "{}`{}`{} held across a suspend point, but should not be",
                     data.descr_pre,
                     tcx.def_path_str(def_id),
                     data.descr_post,
-                );
-                let mut err = lint.build(&msg);
-
+                )
+            }),
+            |lint| {
                 // add span pointing to the offending yield/await
-                err.span_label(data.yield_span, "the value is held across this suspend point");
+                lint.span_label(data.yield_span, "the value is held across this suspend point");
 
                 // Add optional reason note
                 if let Some(note) = attr.value_str() {
                     // FIXME(guswynn): consider formatting this better
-                    err.span_note(data.source_span, note.as_str());
+                    lint.span_note(data.source_span, note.as_str());
                 }
 
                 // Add some quick suggestions on what to do
                 // FIXME: can `drop` work as a suggestion here as well?
-                err.span_help(
+                lint.span_help(
                     data.source_span,
                     "consider using a block (`{ ... }`) \
                     to shrink the value's scope, ending before the suspend point",
                 );
 
-                err.emit();
+                lint
             },
         );
 
diff --git a/compiler/rustc_hir_analysis/src/check/inherited.rs b/compiler/rustc_hir_analysis/src/check/inherited.rs
index 37c830d4e38..2546227e138 100644
--- a/compiler/rustc_hir_analysis/src/check/inherited.rs
+++ b/compiler/rustc_hir_analysis/src/check/inherited.rs
@@ -55,7 +55,7 @@ pub struct Inherited<'a, 'tcx> {
 
     pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>,
 
-    pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, Span)>>,
+    pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, hir::HirId)>>,
 
     pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>,
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index ae484b4feda..8be1cf04f8b 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -7,7 +7,8 @@ use crate::errors::{
 };
 use crate::require_same_types;
 
-use rustc_errors::struct_span_err;
+use hir::def_id::DefId;
+use rustc_errors::{struct_span_err, DiagnosticMessage};
 use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, TyCtxt};
@@ -61,8 +62,12 @@ fn equate_intrinsic_type<'tcx>(
 }
 
 /// Returns the unsafety of the given intrinsic.
-pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
-    match intrinsic {
+pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety {
+    let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
+        true => hir::Unsafety::Normal,
+        false => hir::Unsafety::Unsafe,
+    };
+    let is_in_list = match tcx.item_name(intrinsic_id) {
         // When adding a new intrinsic to this list,
         // it's usually worth updating that intrinsic's documentation
         // to note that it's safe to call, since
@@ -106,14 +111,26 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
         | sym::variant_count
         | sym::ptr_mask => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
+    };
+
+    if has_safe_attr != is_in_list {
+        tcx.sess.struct_span_err(
+            tcx.def_span(intrinsic_id),
+            DiagnosticMessage::Str(format!(
+                    "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`",
+                    tcx.item_name(intrinsic_id)
+        ))).emit();
     }
+
+    is_in_list
 }
 
 /// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
 /// and in `library/core/src/intrinsics.rs`.
 pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
-    let intrinsic_name = tcx.item_name(it.def_id.to_def_id());
+    let intrinsic_id = it.def_id.to_def_id();
+    let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
     let bound_vars = tcx.mk_bound_variable_kinds(
@@ -160,7 +177,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         };
         (n_tps, 0, inputs, output, hir::Unsafety::Unsafe)
     } else {
-        let unsafety = intrinsic_operation_unsafety(intrinsic_name);
+        let unsafety = intrinsic_operation_unsafety(tcx, intrinsic_id);
         let (n_tps, inputs, output) = match intrinsic_name {
             sym::abort => (0, Vec::new(), tcx.types.never),
             sym::unreachable => (0, Vec::new(), tcx.types.never),
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index d8fe63dbf08..4abc00cefb6 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -1,3 +1,4 @@
+use hir::HirId;
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
@@ -6,7 +7,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
 use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
 use rustc_session::lint;
-use rustc_span::{Span, Symbol, DUMMY_SP};
+use rustc_span::{Symbol, DUMMY_SP};
 use rustc_target::abi::{Pointer, VariantIdx};
 use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
 
@@ -40,11 +41,13 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
+    pub fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
+        let tcx = self.tcx;
+        let span = tcx.hir().span(hir_id);
         let convert = |ty: Ty<'tcx>| {
             let ty = self.resolve_vars_if_possible(ty);
-            let ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
-            (SizeSkeleton::compute(ty, self.tcx, self.param_env), ty)
+            let ty = tcx.normalize_erasing_regions(self.param_env, ty);
+            (SizeSkeleton::compute(ty, tcx, self.param_env), ty)
         };
         let (sk_from, from) = convert(from);
         let (sk_to, to) = convert(to);
@@ -57,9 +60,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // Special-case transmuting from `typeof(function)` and
             // `Option<typeof(function)>` to present a clearer error.
-            let from = unpack_option_like(self.tcx, from);
-            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&self.tcx) {
-                struct_span_err!(self.tcx.sess, span, E0591, "can't transmute zero-sized type")
+            let from = unpack_option_like(tcx, from);
+            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&tcx) {
+                struct_span_err!(tcx.sess, span, E0591, "can't transmute zero-sized type")
                     .note(&format!("source type: {from}"))
                     .note(&format!("target type: {to}"))
                     .help("cast with `as` to a pointer instead")
@@ -83,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let mut err = struct_span_err!(
-            self.tcx.sess,
+            tcx.sess,
             span,
             E0512,
             "cannot transmute between types of different sizes, \
@@ -146,7 +149,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         target_features: &FxHashSet<Symbol>,
     ) -> Option<InlineAsmType> {
         let ty = (self.get_operand_ty)(expr);
-        if ty.has_infer_types_or_consts() {
+        if ty.has_non_region_infer() {
             bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty);
         }
         let asm_ty_isize = match self.tcx.sess.target.pointer_width {
@@ -328,17 +331,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     lint::builtin::ASM_SUB_REGISTER,
                     expr.hir_id,
                     spans,
+                    "formatting may not be suitable for sub-register argument",
                     |lint| {
-                        let msg = "formatting may not be suitable for sub-register argument";
-                        let mut err = lint.build(msg);
-                        err.span_label(expr.span, "for this argument");
-                        err.help(&format!(
+                        lint.span_label(expr.span, "for this argument");
+                        lint.help(&format!(
                             "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`",
                         ));
-                        err.help(&format!(
+                        lint.help(&format!(
                             "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
                         ));
-                        err.emit();
+                        lint
                     },
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs b/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs
index 392695cca68..ca4cdf5a0d0 100644
--- a/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs
+++ b/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs
@@ -82,14 +82,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 prelude_or_array_lint,
                 self_expr.hir_id,
                 self_expr.span,
+                format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
                 |lint| {
                     let sp = self_expr.span;
 
-                    let mut lint = lint.build(&format!(
-                        "trait method `{}` will become ambiguous in Rust 2021",
-                        segment.ident.name
-                    ));
-
                     let derefs = "*".repeat(pick.autoderefs);
 
                     let autoref = match pick.autoref_or_ptr_adjustment {
@@ -133,7 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         );
                     }
 
-                    lint.emit();
+                    lint
                 },
             );
         } else {
@@ -143,6 +139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 prelude_or_array_lint,
                 call_expr.hir_id,
                 call_expr.span,
+                format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
                 |lint| {
                     let sp = call_expr.span;
                     let trait_name = self.trait_path_or_bare_name(
@@ -151,11 +148,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         pick.item.container_id(self.tcx),
                     );
 
-                    let mut lint = lint.build(&format!(
-                        "trait method `{}` will become ambiguous in Rust 2021",
-                        segment.ident.name
-                    ));
-
                     let (self_adjusted, precise) = self.adjust_expr(pick, self_expr, sp);
                     if precise {
                         let args = args
@@ -202,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         );
                     }
 
-                    lint.emit();
+                    lint
                 },
             );
         }
@@ -257,15 +249,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         }
 
-        self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
-            // "type" refers to either a type or, more likely, a trait from which
-            // the associated function or method is from.
-            let container_id = pick.item.container_id(self.tcx);
-            let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
-            let trait_generics = self.tcx.generics_of(container_id);
-
-            let trait_name =
-                if trait_generics.params.len() <= trait_generics.has_self as usize {
+        self.tcx.struct_span_lint_hir(
+            RUST_2021_PRELUDE_COLLISIONS,
+            expr_id,
+            span,
+            format!(
+                "trait-associated function `{}` will become ambiguous in Rust 2021",
+                method_name.name
+            ),
+            |lint| {
+                // "type" refers to either a type or, more likely, a trait from which
+                // the associated function or method is from.
+                let container_id = pick.item.container_id(self.tcx);
+                let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
+                let trait_generics = self.tcx.generics_of(container_id);
+
+                let trait_name = if trait_generics.params.len() <= trait_generics.has_self as usize
+                {
                     trait_path
                 } else {
                     let counts = trait_generics.own_counts();
@@ -282,44 +282,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     )
                 };
 
-            let mut lint = lint.build(&format!(
-                "trait-associated function `{}` will become ambiguous in Rust 2021",
-                method_name.name
-            ));
-
-            let mut self_ty_name = self_ty_span
-                .find_ancestor_inside(span)
-                .and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
-                .unwrap_or_else(|| self_ty.to_string());
-
-            // Get the number of generics the self type has (if an Adt) unless we can determine that
-            // the user has written the self type with generics already which we (naively) do by looking
-            // for a "<" in `self_ty_name`.
-            if !self_ty_name.contains('<') {
-                if let Adt(def, _) = self_ty.kind() {
-                    let generics = self.tcx.generics_of(def.did());
-                    if !generics.params.is_empty() {
-                        let counts = generics.own_counts();
-                        self_ty_name += &format!(
-                            "<{}>",
-                            std::iter::repeat("'_")
-                                .take(counts.lifetimes)
-                                .chain(std::iter::repeat("_").take(counts.types + counts.consts))
-                                .collect::<Vec<_>>()
-                                .join(", ")
-                        );
+                let mut self_ty_name = self_ty_span
+                    .find_ancestor_inside(span)
+                    .and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
+                    .unwrap_or_else(|| self_ty.to_string());
+
+                // Get the number of generics the self type has (if an Adt) unless we can determine that
+                // the user has written the self type with generics already which we (naively) do by looking
+                // for a "<" in `self_ty_name`.
+                if !self_ty_name.contains('<') {
+                    if let Adt(def, _) = self_ty.kind() {
+                        let generics = self.tcx.generics_of(def.did());
+                        if !generics.params.is_empty() {
+                            let counts = generics.own_counts();
+                            self_ty_name += &format!(
+                                "<{}>",
+                                std::iter::repeat("'_")
+                                    .take(counts.lifetimes)
+                                    .chain(
+                                        std::iter::repeat("_").take(counts.types + counts.consts)
+                                    )
+                                    .collect::<Vec<_>>()
+                                    .join(", ")
+                            );
+                        }
                     }
                 }
-            }
-            lint.span_suggestion(
-                span,
-                "disambiguate the associated function",
-                format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
-                Applicability::MachineApplicable,
-            );
-
-            lint.emit();
-        });
+                lint.span_suggestion(
+                    span,
+                    "disambiguate the associated function",
+                    format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
+                    Applicability::MachineApplicable,
+                );
+
+                lint
+            },
+        );
     }
 
     fn trait_path_or_bare_name(
diff --git a/compiler/rustc_hir_analysis/src/check/method/probe.rs b/compiler/rustc_hir_analysis/src/check/method/probe.rs
index 6cd7ced01a3..a761a93dea4 100644
--- a/compiler/rustc_hir_analysis/src/check/method/probe.rs
+++ b/compiler/rustc_hir_analysis/src/check/method/probe.rs
@@ -409,9 +409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         lint::builtin::TYVAR_BEHIND_RAW_POINTER,
                         scope_expr_id,
                         span,
-                        |lint| {
-                            lint.build("type annotations needed").emit();
-                        },
+                        "type annotations needed",
+                        |lint| lint,
                     );
                 }
             } else {
@@ -1358,24 +1357,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         stable_pick: &Pick<'_>,
         unstable_candidates: &[(Candidate<'tcx>, Symbol)],
     ) {
+        let def_kind = stable_pick.item.kind.as_def_kind();
         self.tcx.struct_span_lint_hir(
             lint::builtin::UNSTABLE_NAME_COLLISIONS,
             self.scope_expr_id,
             self.span,
+            format!(
+                "{} {} with this name may be added to the standard library in the future",
+                def_kind.article(),
+                def_kind.descr(stable_pick.item.def_id),
+            ),
             |lint| {
-                let def_kind = stable_pick.item.kind.as_def_kind();
-                let mut diag = lint.build(&format!(
-                    "{} {} with this name may be added to the standard library in the future",
-                    def_kind.article(),
-                    def_kind.descr(stable_pick.item.def_id),
-                ));
                 match (stable_pick.item.kind, stable_pick.item.container) {
                     (ty::AssocKind::Fn, _) => {
                         // FIXME: This should be a `span_suggestion` instead of `help`
                         // However `self.span` only
                         // highlights the method name, so we can't use it. Also consider reusing
                         // the code from `report_method_error()`.
-                        diag.help(&format!(
+                        lint.help(&format!(
                             "call with fully qualified syntax `{}(...)` to keep using the current \
                              method",
                             self.tcx.def_path_str(stable_pick.item.def_id),
@@ -1383,7 +1382,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     }
                     (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
                         let def_id = stable_pick.item.container_id(self.tcx);
-                        diag.span_suggestion(
+                        lint.span_suggestion(
                             self.span,
                             "use the fully qualified path to the associated const",
                             format!(
@@ -1399,7 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 }
                 if self.tcx.sess.is_nightly_build() {
                     for (candidate, feature) in unstable_candidates {
-                        diag.help(&format!(
+                        lint.help(&format!(
                             "add `#![feature({})]` to the crate attributes to enable `{}`",
                             feature,
                             self.tcx.def_path_str(candidate.item.def_id),
@@ -1407,7 +1406,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     }
                 }
 
-                diag.emit();
+                lint
             },
         );
     }
diff --git a/compiler/rustc_hir_analysis/src/check/method/suggest.rs b/compiler/rustc_hir_analysis/src/check/method/suggest.rs
index 0e82e4956c7..ad1084bd1b1 100644
--- a/compiler/rustc_hir_analysis/src/check/method/suggest.rs
+++ b/compiler/rustc_hir_analysis/src/check/method/suggest.rs
@@ -2324,6 +2324,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else`
+    /// FIXME: currently not working for suggesting `map_or_else`, see #102408
+    pub(crate) fn suggest_else_fn_with_closure(
+        &self,
+        err: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        found: Ty<'tcx>,
+        expected: Ty<'tcx>,
+    ) -> bool {
+        let Some((_def_id_or_name, output, _inputs)) = self.extract_callable_info(expr, found)
+        else { return false; };
+
+        if !self.can_coerce(output, expected) {
+            return false;
+        }
+
+        let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+        if  let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
+            let hir::ExprKind::MethodCall(
+                hir::PathSegment { ident: method_name, .. },
+                self_expr,
+                args,
+                ..,
+             ) = call_expr.kind &&
+            let Some(self_ty) = self.typeck_results.borrow().expr_ty_opt(self_expr) {
+            let new_name = Ident {
+                name: Symbol::intern(&format!("{}_else", method_name.as_str())),
+                span: method_name.span,
+            };
+            let probe = self.lookup_probe(
+                expr.span,
+                new_name,
+                self_ty,
+                self_expr,
+                ProbeScope::TraitsInScope,
+            );
+
+            // check the method arguments number
+            if let Ok(pick) = probe &&
+                let fn_sig = self.tcx.fn_sig(pick.item.def_id) &&
+                let fn_args = fn_sig.skip_binder().inputs() &&
+                fn_args.len() == args.len() + 1 {
+                err.span_suggestion_verbose(
+                    method_name.span.shrink_to_hi(),
+                    &format!("try calling `{}` instead", new_name.name.as_str()),
+                    "_else",
+                    Applicability::MaybeIncorrect,
+                );
+                return true;
+            }
+        }
+        false
+    }
+
     /// Checks whether there is a local type somewhere in the chain of
     /// autoderefs of `rcvr_ty`.
     fn type_derefs_to_local(
diff --git a/compiler/rustc_hir_analysis/src/check/op.rs b/compiler/rustc_hir_analysis/src/check/op.rs
index 4754717c29a..d876b1d20fe 100644
--- a/compiler/rustc_hir_analysis/src/check/op.rs
+++ b/compiler/rustc_hir_analysis/src/check/op.rs
@@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
+use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
@@ -470,7 +471,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // This has nothing here because it means we did string
                         // concatenation (e.g., "Hello " + "World!"). This means
                         // we don't want the note in the else clause to be emitted
-                    } else if lhs_ty.has_param_types_or_consts() {
+                    } else if lhs_ty.has_non_region_param() {
                         // Look for a TraitPredicate in the Fulfillment errors,
                         // and use it to generate a suggestion.
                         //
@@ -656,7 +657,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         format!("cannot apply unary operator `{}`", op.as_str()),
                     );
 
-                    if operand_ty.has_param_types_or_consts() {
+                    if operand_ty.has_non_region_param() {
                         let predicates = errors.iter().filter_map(|error| {
                             error.obligation.predicate.to_opt_poly_trait_pred()
                         });
@@ -677,7 +678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // If the previous expression was a block expression, suggest parentheses
                         // (turning this into a binary subtraction operation instead.)
                         // for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs)
-                        self.tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
+                        err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
                     } else {
                         match actual.kind() {
                             Uint(_) if op == hir::UnOp::Neg => {
diff --git a/compiler/rustc_hir_analysis/src/check/pat.rs b/compiler/rustc_hir_analysis/src/check/pat.rs
index 8906b622b68..178326cfdc4 100644
--- a/compiler/rustc_hir_analysis/src/check/pat.rs
+++ b/compiler/rustc_hir_analysis/src/check/pat.rs
@@ -1790,10 +1790,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             &unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(),
         );
 
-        self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |build| {
-        let mut lint = build.build("some fields are not explicitly listed");
+        self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| {
         lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
-
         lint.help(
             "ensure that all fields are mentioned explicitly by adding the suggested fields",
         );
@@ -1801,7 +1799,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             "the pattern is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found",
             ty,
         ));
-        lint.emit();
+
+        lint
     });
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/upvar.rs b/compiler/rustc_hir_analysis/src/check/upvar.rs
index 0b207a6c0be..4f495641691 100644
--- a/compiler/rustc_hir_analysis/src/check/upvar.rs
+++ b/compiler/rustc_hir_analysis/src/check/upvar.rs
@@ -749,10 +749,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
                 closure_hir_id,
                 closure_head_span,
+                reasons.migration_message(),
                 |lint| {
-                    let mut diagnostics_builder = lint.build(
-                        &reasons.migration_message(),
-                    );
                     for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations {
                         // Labels all the usage of the captured variable and why they are responsible
                         // for migration being needed
@@ -760,13 +758,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             match &lint_note.captures_info {
                                 UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => {
                                     let cause_span = self.tcx.hir().span(*capture_expr_id);
-                                    diagnostics_builder.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
+                                    lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
                                         self.tcx.hir().name(*var_hir_id),
                                         captured_name,
                                     ));
                                 }
                                 UpvarMigrationInfo::CapturingNothing { use_span } => {
-                                    diagnostics_builder.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect",
+                                    lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect",
                                         self.tcx.hir().name(*var_hir_id),
                                     ));
                                 }
@@ -781,13 +779,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                                 match &lint_note.captures_info {
                                     UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
-                                        diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure",
+                                        lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure",
                                             self.tcx.hir().name(*var_hir_id),
                                             captured_name,
                                         ));
                                     }
                                     UpvarMigrationInfo::CapturingNothing { use_span: _ } => {
-                                        diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure",
+                                        lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure",
                                             v = self.tcx.hir().name(*var_hir_id),
                                         ));
                                     }
@@ -800,7 +798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 match &lint_note.captures_info {
                                     UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
                                         let var_name = self.tcx.hir().name(*var_hir_id);
-                                        diagnostics_builder.span_label(closure_head_span, format!("\
+                                        lint.span_label(closure_head_span, format!("\
                                         in Rust 2018, this closure implements {missing_trait} \
                                         as `{var_name}` implements {missing_trait}, but in Rust 2021, \
                                         this closure will no longer implement {missing_trait} \
@@ -814,7 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                         }
                     }
-                    diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
+                    lint.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
 
                     let diagnostic_msg = format!(
                         "add a dummy let to cause {} to be fully captured",
@@ -857,7 +855,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             // We take the indentation from the next non-empty line.
                             let line2 = lines.find(|line| !line.is_empty()).unwrap_or_default();
                             let indent = line2.split_once(|c: char| !c.is_whitespace()).unwrap_or_default().0;
-                            diagnostics_builder.span_suggestion(
+                            lint.span_suggestion(
                                 closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(),
                                 &diagnostic_msg,
                                 format!("\n{indent}{migration_string};"),
@@ -868,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             // braces, but with more than just the opening
                             // brace on the first line. We put the `let`
                             // directly after the `{`.
-                            diagnostics_builder.span_suggestion(
+                            lint.span_suggestion(
                                 closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(),
                                 &diagnostic_msg,
                                 format!(" {migration_string};"),
@@ -877,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         } else {
                             // This is a closure without braces around the body.
                             // We add braces to add the `let` before the body.
-                            diagnostics_builder.multipart_suggestion(
+                            lint.multipart_suggestion(
                                 &diagnostic_msg,
                                 vec![
                                     (closure_body_span.shrink_to_lo(), format!("{{ {migration_string}; ")),
@@ -887,7 +885,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             );
                         }
                     } else {
-                        diagnostics_builder.span_suggestion(
+                        lint.span_suggestion(
                             closure_span,
                             &diagnostic_msg,
                             migration_string,
@@ -895,7 +893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         );
                     }
 
-                    diagnostics_builder.emit();
+                    lint
                 },
             );
         }
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 7965ec1b43f..d607f901420 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1428,9 +1428,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
             let substituted_pred = predicates.rebind(pred).subst(tcx, substs);
             // Don't check non-defaulted params, dependent defaults (including lifetimes)
             // or preds with multiple params.
-            if substituted_pred.has_param_types_or_consts()
-                || param_count.params.len() > 1
-                || has_region
+            if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
             {
                 None
             } else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) {
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index 1d23ed92921..922833f8580 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -29,14 +29,18 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
             continue;
         }
         let hir::ItemKind::Use(path, _) = item.kind else { unreachable!() };
-        tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
-            let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
-                format!("unused import: `{}`", snippet)
-            } else {
-                "unused import".to_owned()
-            };
-            lint.build(&msg).emit();
-        });
+        let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
+            format!("unused import: `{}`", snippet)
+        } else {
+            "unused import".to_owned()
+        };
+        tcx.struct_span_lint_hir(
+            lint::builtin::UNUSED_IMPORTS,
+            item.hir_id(),
+            path.span,
+            msg,
+            |lint| lint,
+        );
     }
 
     unused_crates_lint(tcx);
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 7d15e5a7f3c..1307f74f210 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -2,7 +2,7 @@
 //! crate or pertains to a type defined in this crate.
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::struct_span_err;
+use rustc_errors::{struct_span_err, DelayDm};
 use rustc_errors::{Diagnostic, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_middle::ty::subst::GenericArgKind;
@@ -412,30 +412,31 @@ fn lint_auto_trait_impl<'tcx>(
         lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
         tcx.hir().local_def_id_to_hir_id(impl_def_id),
         tcx.def_span(impl_def_id),
-        |err| {
-            let item_span = tcx.def_span(self_type_did);
-            let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
-            let mut err = err.build(&format!(
+        DelayDm(|| {
+            format!(
                 "cross-crate traits with a default impl, like `{}`, \
                          should not be specialized",
                 tcx.def_path_str(trait_ref.def_id),
-            ));
+            )
+        }),
+        |lint| {
+            let item_span = tcx.def_span(self_type_did);
+            let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
             match arg {
                 ty::util::NotUniqueParam::DuplicateParam(arg) => {
-                    err.note(&format!("`{}` is mentioned multiple times", arg));
+                    lint.note(&format!("`{}` is mentioned multiple times", arg));
                 }
                 ty::util::NotUniqueParam::NotParam(arg) => {
-                    err.note(&format!("`{}` is not a generic parameter", arg));
+                    lint.note(&format!("`{}` is not a generic parameter", arg));
                 }
             }
-            err.span_note(
+            lint.span_note(
                 item_span,
                 &format!(
                     "try using the same sequence of generic parameters as the {} definition",
                     self_descr,
                 ),
-            );
-            err.emit();
+            )
         },
     );
 }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e7deae2b557..ab4b861b6cb 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -15,46 +15,40 @@
 //! crate as a kind of pass. This should eventually be factored away.
 
 use crate::astconv::AstConv;
-use crate::bounds::Bounds;
 use crate::check::intrinsic::intrinsic_operation_unsafety;
-use crate::constrained_generic_params as cgp;
 use crate::errors;
-use crate::middle::resolve_lifetime as rl;
 use rustc_ast as ast;
 use rustc_ast::{MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_data_structures::captures::Captures;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, DefKind};
+use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::weak_lang_items;
-use rustc_hir::{GenericParamKind, HirId, Node};
+use rustc_hir::{GenericParamKind, Node};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::mono::Linkage;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::util::Discr;
-use rustc_middle::ty::util::IntTypeExt;
+use rustc_middle::ty::util::{Discr, IntTypeExt};
+use rustc_middle::ty::ReprOptions;
 use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, Ty, TyCtxt};
-use rustc_middle::ty::{ReprOptions, ToPredicate};
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 use rustc_target::spec::{abi, SanitizerSet};
 use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
 use std::iter;
 
+mod generics_of;
 mod item_bounds;
+mod predicates_of;
 mod type_of;
 
-#[derive(Debug)]
-struct OnlySelfBounds(bool);
-
 ///////////////////////////////////////////////////////////////////////////
 // Main entry point
 
@@ -68,14 +62,15 @@ pub fn provide(providers: &mut Providers) {
         type_of: type_of::type_of,
         item_bounds: item_bounds::item_bounds,
         explicit_item_bounds: item_bounds::explicit_item_bounds,
-        generics_of,
-        predicates_of,
+        generics_of: generics_of::generics_of,
+        predicates_of: predicates_of::predicates_of,
         predicates_defined_on,
-        explicit_predicates_of,
-        super_predicates_of,
-        super_predicates_that_define_assoc_type,
-        trait_explicit_predicates_and_bounds,
-        type_param_predicates,
+        explicit_predicates_of: predicates_of::explicit_predicates_of,
+        super_predicates_of: predicates_of::super_predicates_of,
+        super_predicates_that_define_assoc_type:
+            predicates_of::super_predicates_that_define_assoc_type,
+        trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
+        type_param_predicates: predicates_of::type_param_predicates,
         trait_def,
         adt_def,
         fn_sig,
@@ -572,160 +567,6 @@ fn get_new_lifetime_name<'tcx>(
     (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
 }
 
-/// Returns the predicates defined on `item_def_id` of the form
-/// `X: Foo` where `X` is the type parameter `def_id`.
-#[instrument(level = "trace", skip(tcx))]
-fn type_param_predicates(
-    tcx: TyCtxt<'_>,
-    (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
-) -> ty::GenericPredicates<'_> {
-    use rustc_hir::*;
-
-    // In the AST, bounds can derive from two places. Either
-    // written inline like `<T: Foo>` or in a where-clause like
-    // `where T: Foo`.
-
-    let param_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let param_owner = tcx.hir().ty_param_owner(def_id);
-    let generics = tcx.generics_of(param_owner);
-    let index = generics.param_def_id_to_index[&def_id.to_def_id()];
-    let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id));
-
-    // Don't look for bounds where the type parameter isn't in scope.
-    let parent = if item_def_id == param_owner.to_def_id() {
-        None
-    } else {
-        tcx.generics_of(item_def_id).parent
-    };
-
-    let mut result = parent
-        .map(|parent| {
-            let icx = ItemCtxt::new(tcx, parent);
-            icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name)
-        })
-        .unwrap_or_default();
-    let mut extend = None;
-
-    let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local());
-    let ast_generics = match tcx.hir().get(item_hir_id) {
-        Node::TraitItem(item) => &item.generics,
-
-        Node::ImplItem(item) => &item.generics,
-
-        Node::Item(item) => {
-            match item.kind {
-                ItemKind::Fn(.., ref generics, _)
-                | ItemKind::Impl(hir::Impl { ref generics, .. })
-                | ItemKind::TyAlias(_, ref generics)
-                | ItemKind::OpaqueTy(OpaqueTy {
-                    ref generics,
-                    origin: hir::OpaqueTyOrigin::TyAlias,
-                    ..
-                })
-                | ItemKind::Enum(_, ref generics)
-                | ItemKind::Struct(_, ref generics)
-                | ItemKind::Union(_, ref generics) => generics,
-                ItemKind::Trait(_, _, ref generics, ..) => {
-                    // Implied `Self: Trait` and supertrait bounds.
-                    if param_id == item_hir_id {
-                        let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
-                        extend =
-                            Some((identity_trait_ref.without_const().to_predicate(tcx), item.span));
-                    }
-                    generics
-                }
-                _ => return result,
-            }
-        }
-
-        Node::ForeignItem(item) => match item.kind {
-            ForeignItemKind::Fn(_, _, ref generics) => generics,
-            _ => return result,
-        },
-
-        _ => return result,
-    };
-
-    let icx = ItemCtxt::new(tcx, item_def_id);
-    let extra_predicates = extend.into_iter().chain(
-        icx.type_parameter_bounds_in_generics(
-            ast_generics,
-            param_id,
-            ty,
-            OnlySelfBounds(true),
-            Some(assoc_name),
-        )
-        .into_iter()
-        .filter(|(predicate, _)| match predicate.kind().skip_binder() {
-            ty::PredicateKind::Trait(data) => data.self_ty().is_param(index),
-            _ => false,
-        }),
-    );
-    result.predicates =
-        tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates));
-    result
-}
-
-impl<'tcx> ItemCtxt<'tcx> {
-    /// Finds bounds from `hir::Generics`. This requires scanning through the
-    /// AST. We do this to avoid having to convert *all* the bounds, which
-    /// would create artificial cycles. Instead, we can only convert the
-    /// bounds for a type parameter `X` if `X::Foo` is used.
-    #[instrument(level = "trace", skip(self, ast_generics))]
-    fn type_parameter_bounds_in_generics(
-        &self,
-        ast_generics: &'tcx hir::Generics<'tcx>,
-        param_id: hir::HirId,
-        ty: Ty<'tcx>,
-        only_self_bounds: OnlySelfBounds,
-        assoc_name: Option<Ident>,
-    ) -> Vec<(ty::Predicate<'tcx>, Span)> {
-        let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
-        trace!(?param_def_id);
-        ast_generics
-            .predicates
-            .iter()
-            .filter_map(|wp| match *wp {
-                hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
-                _ => None,
-            })
-            .flat_map(|bp| {
-                let bt = if bp.is_param_bound(param_def_id) {
-                    Some(ty)
-                } else if !only_self_bounds.0 {
-                    Some(self.to_ty(bp.bounded_ty))
-                } else {
-                    None
-                };
-                let bvars = self.tcx.late_bound_vars(bp.bounded_ty.hir_id);
-
-                bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter(
-                    |(_, b, _)| match assoc_name {
-                        Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
-                        None => true,
-                    },
-                )
-            })
-            .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars))
-            .collect()
-    }
-
-    #[instrument(level = "trace", skip(self))]
-    fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
-        match b {
-            hir::GenericBound::Trait(poly_trait_ref, _) => {
-                let trait_ref = &poly_trait_ref.trait_ref;
-                if let Some(trait_did) = trait_ref.trait_def_id() {
-                    self.tcx.trait_may_define_assoc_type(trait_did, assoc_name)
-                } else {
-                    false
-                }
-            }
-            _ => false,
-        }
-    }
-}
-
 fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     let it = tcx.hir().item(item_id);
     debug!("convert: item {} with id {}", it.ident, it.hir_id());
@@ -1097,96 +938,6 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> {
     tcx.alloc_adt_def(def_id.to_def_id(), kind, variants, repr)
 }
 
-/// Ensures that the super-predicates of the trait with a `DefId`
-/// of `trait_def_id` are converted and stored. This also ensures that
-/// the transitive super-predicates are converted.
-fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredicates<'_> {
-    debug!("super_predicates(trait_def_id={:?})", trait_def_id);
-    tcx.super_predicates_that_define_assoc_type((trait_def_id, None))
-}
-
-/// Ensures that the super-predicates of the trait with a `DefId`
-/// of `trait_def_id` are converted and stored. This also ensures that
-/// the transitive super-predicates are converted.
-fn super_predicates_that_define_assoc_type(
-    tcx: TyCtxt<'_>,
-    (trait_def_id, assoc_name): (DefId, Option<Ident>),
-) -> ty::GenericPredicates<'_> {
-    debug!(
-        "super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})",
-        trait_def_id, assoc_name
-    );
-    if trait_def_id.is_local() {
-        debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id);
-        let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
-
-        let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
-            bug!("trait_node_id {} is not an item", trait_hir_id);
-        };
-
-        let (generics, bounds) = match item.kind {
-            hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
-            hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
-            _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
-        };
-
-        let icx = ItemCtxt::new(tcx, trait_def_id);
-
-        // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
-        let self_param_ty = tcx.types.self_param;
-        let superbounds1 = if let Some(assoc_name) = assoc_name {
-            <dyn AstConv<'_>>::compute_bounds_that_match_assoc_type(
-                &icx,
-                self_param_ty,
-                bounds,
-                assoc_name,
-            )
-        } else {
-            <dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds)
-        };
-
-        let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
-
-        // Convert any explicit superbounds in the where-clause,
-        // e.g., `trait Foo where Self: Bar`.
-        // In the case of trait aliases, however, we include all bounds in the where-clause,
-        // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
-        // as one of its "superpredicates".
-        let is_trait_alias = tcx.is_trait_alias(trait_def_id);
-        let superbounds2 = icx.type_parameter_bounds_in_generics(
-            generics,
-            item.hir_id(),
-            self_param_ty,
-            OnlySelfBounds(!is_trait_alias),
-            assoc_name,
-        );
-
-        // Combine the two lists to form the complete set of superbounds:
-        let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
-        debug!(?superbounds);
-
-        // Now require that immediate supertraits are converted,
-        // which will, in turn, reach indirect supertraits.
-        if assoc_name.is_none() {
-            // Now require that immediate supertraits are converted,
-            // which will, in turn, reach indirect supertraits.
-            for &(pred, span) in superbounds {
-                debug!("superbound: {:?}", pred);
-                if let ty::PredicateKind::Trait(bound) = pred.kind().skip_binder() {
-                    tcx.at(span).super_predicates_of(bound.def_id());
-                }
-            }
-        }
-
-        ty::GenericPredicates { parent: None, predicates: superbounds }
-    } else {
-        // if `assoc_name` is None, then the query should've been redirected to an
-        // external provider
-        assert!(assoc_name.is_some());
-        tcx.super_predicates_of(trait_def_id)
-    }
-}
-
 fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
     let item = tcx.hir().expect_item(def_id.expect_local());
 
@@ -1328,475 +1079,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
     )
 }
 
-fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<Span> {
-    struct LateBoundRegionsDetector<'tcx> {
-        tcx: TyCtxt<'tcx>,
-        outer_index: ty::DebruijnIndex,
-        has_late_bound_regions: Option<Span>,
-    }
-
-    impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> {
-        fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
-            if self.has_late_bound_regions.is_some() {
-                return;
-            }
-            match ty.kind {
-                hir::TyKind::BareFn(..) => {
-                    self.outer_index.shift_in(1);
-                    intravisit::walk_ty(self, ty);
-                    self.outer_index.shift_out(1);
-                }
-                _ => intravisit::walk_ty(self, ty),
-            }
-        }
-
-        fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) {
-            if self.has_late_bound_regions.is_some() {
-                return;
-            }
-            self.outer_index.shift_in(1);
-            intravisit::walk_poly_trait_ref(self, tr);
-            self.outer_index.shift_out(1);
-        }
-
-        fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
-            if self.has_late_bound_regions.is_some() {
-                return;
-            }
-
-            match self.tcx.named_region(lt.hir_id) {
-                Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {}
-                Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {}
-                Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => {
-                    self.has_late_bound_regions = Some(lt.span);
-                }
-            }
-        }
-    }
-
-    fn has_late_bound_regions<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        generics: &'tcx hir::Generics<'tcx>,
-        decl: &'tcx hir::FnDecl<'tcx>,
-    ) -> Option<Span> {
-        let mut visitor = LateBoundRegionsDetector {
-            tcx,
-            outer_index: ty::INNERMOST,
-            has_late_bound_regions: None,
-        };
-        for param in generics.params {
-            if let GenericParamKind::Lifetime { .. } = param.kind {
-                if tcx.is_late_bound(param.hir_id) {
-                    return Some(param.span);
-                }
-            }
-        }
-        visitor.visit_fn_decl(decl);
-        visitor.has_late_bound_regions
-    }
-
-    match node {
-        Node::TraitItem(item) => match item.kind {
-            hir::TraitItemKind::Fn(ref sig, _) => {
-                has_late_bound_regions(tcx, &item.generics, sig.decl)
-            }
-            _ => None,
-        },
-        Node::ImplItem(item) => match item.kind {
-            hir::ImplItemKind::Fn(ref sig, _) => {
-                has_late_bound_regions(tcx, &item.generics, sig.decl)
-            }
-            _ => None,
-        },
-        Node::ForeignItem(item) => match item.kind {
-            hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => {
-                has_late_bound_regions(tcx, generics, fn_decl)
-            }
-            _ => None,
-        },
-        Node::Item(item) => match item.kind {
-            hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
-                has_late_bound_regions(tcx, generics, sig.decl)
-            }
-            _ => None,
-        },
-        _ => None,
-    }
-}
-
-struct AnonConstInParamTyDetector {
-    in_param_ty: bool,
-    found_anon_const_in_param_ty: bool,
-    ct: HirId,
-}
-
-impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
-    fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
-        if let GenericParamKind::Const { ty, default: _ } = p.kind {
-            let prev = self.in_param_ty;
-            self.in_param_ty = true;
-            self.visit_ty(ty);
-            self.in_param_ty = prev;
-        }
-    }
-
-    fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
-        if self.in_param_ty && self.ct == c.hir_id {
-            self.found_anon_const_in_param_ty = true;
-        } else {
-            intravisit::walk_anon_const(self, c)
-        }
-    }
-}
-
-fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
-    use rustc_hir::*;
-
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
-
-    let node = tcx.hir().get(hir_id);
-    let parent_def_id = match node {
-        Node::ImplItem(_)
-        | Node::TraitItem(_)
-        | Node::Variant(_)
-        | Node::Ctor(..)
-        | Node::Field(_) => {
-            let parent_id = tcx.hir().get_parent_item(hir_id);
-            Some(parent_id.to_def_id())
-        }
-        // FIXME(#43408) always enable this once `lazy_normalization` is
-        // stable enough and does not need a feature gate anymore.
-        Node::AnonConst(_) => {
-            let parent_def_id = tcx.hir().get_parent_item(hir_id);
-
-            let mut in_param_ty = false;
-            for (_parent, node) in tcx.hir().parent_iter(hir_id) {
-                if let Some(generics) = node.generics() {
-                    let mut visitor = AnonConstInParamTyDetector {
-                        in_param_ty: false,
-                        found_anon_const_in_param_ty: false,
-                        ct: hir_id,
-                    };
-
-                    visitor.visit_generics(generics);
-                    in_param_ty = visitor.found_anon_const_in_param_ty;
-                    break;
-                }
-            }
-
-            if in_param_ty {
-                // We do not allow generic parameters in anon consts if we are inside
-                // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
-                None
-            } else if tcx.lazy_normalization() {
-                if let Some(param_id) = tcx.hir().opt_const_param_default_param_hir_id(hir_id) {
-                    // If the def_id we are calling generics_of on is an anon ct default i.e:
-                    //
-                    // struct Foo<const N: usize = { .. }>;
-                    //        ^^^       ^          ^^^^^^ def id of this anon const
-                    //        ^         ^ param_id
-                    //        ^ parent_def_id
-                    //
-                    // then we only want to return generics for params to the left of `N`. If we don't do that we
-                    // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`.
-                    //
-                    // This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as
-                    // we substitute the defaults with the partially built substs when we build the substs. Subst'ing
-                    // the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building.
-                    //
-                    // We fix this by having this function return the parent's generics ourselves and truncating the
-                    // generics to only include non-forward declared params (with the exception of the `Self` ty)
-                    //
-                    // For the above code example that means we want `substs: []`
-                    // For the following struct def we want `substs: [N#0]` when generics_of is called on
-                    // the def id of the `{ N + 1 }` anon const
-                    // struct Foo<const N: usize, const M: usize = { N + 1 }>;
-                    //
-                    // This has some implications for how we get the predicates available to the anon const
-                    // see `explicit_predicates_of` for more information on this
-                    let generics = tcx.generics_of(parent_def_id.to_def_id());
-                    let param_def = tcx.hir().local_def_id(param_id).to_def_id();
-                    let param_def_idx = generics.param_def_id_to_index[&param_def];
-                    // In the above example this would be .params[..N#0]
-                    let params = generics.params[..param_def_idx as usize].to_owned();
-                    let param_def_id_to_index =
-                        params.iter().map(|param| (param.def_id, param.index)).collect();
-
-                    return ty::Generics {
-                        // we set the parent of these generics to be our parent's parent so that we
-                        // dont end up with substs: [N, M, N] for the const default on a struct like this:
-                        // struct Foo<const N: usize, const M: usize = { ... }>;
-                        parent: generics.parent,
-                        parent_count: generics.parent_count,
-                        params,
-                        param_def_id_to_index,
-                        has_self: generics.has_self,
-                        has_late_bound_regions: generics.has_late_bound_regions,
-                    };
-                }
-
-                // HACK(eddyb) this provides the correct generics when
-                // `feature(generic_const_expressions)` is enabled, so that const expressions
-                // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
-                //
-                // Note that we do not supply the parent generics when using
-                // `min_const_generics`.
-                Some(parent_def_id.to_def_id())
-            } else {
-                let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
-                match parent_node {
-                    // HACK(eddyb) this provides the correct generics for repeat
-                    // expressions' count (i.e. `N` in `[x; N]`), and explicit
-                    // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
-                    // as they shouldn't be able to cause query cycle errors.
-                    Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
-                        if constant.hir_id() == hir_id =>
-                    {
-                        Some(parent_def_id.to_def_id())
-                    }
-                    Node::Variant(Variant { disr_expr: Some(ref constant), .. })
-                        if constant.hir_id == hir_id =>
-                    {
-                        Some(parent_def_id.to_def_id())
-                    }
-                    Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
-                        Some(tcx.typeck_root_def_id(def_id))
-                    }
-                    // Exclude `GlobalAsm` here which cannot have generics.
-                    Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
-                        if asm.operands.iter().any(|(op, _op_sp)| match op {
-                            hir::InlineAsmOperand::Const { anon_const }
-                            | hir::InlineAsmOperand::SymFn { anon_const } => {
-                                anon_const.hir_id == hir_id
-                            }
-                            _ => false,
-                        }) =>
-                    {
-                        Some(parent_def_id.to_def_id())
-                    }
-                    _ => None,
-                }
-            }
-        }
-        Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
-            Some(tcx.typeck_root_def_id(def_id))
-        }
-        Node::Item(item) => match item.kind {
-            ItemKind::OpaqueTy(hir::OpaqueTy {
-                origin:
-                    hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
-                in_trait,
-                ..
-            }) => {
-                if in_trait {
-                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
-                } else {
-                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
-                }
-                Some(fn_def_id.to_def_id())
-            }
-            ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
-                let parent_id = tcx.hir().get_parent_item(hir_id);
-                assert_ne!(parent_id, hir::CRATE_OWNER_ID);
-                debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
-                // Opaque types are always nested within another item, and
-                // inherit the generics of the item.
-                Some(parent_id.to_def_id())
-            }
-            _ => None,
-        },
-        _ => None,
-    };
-
-    enum Defaults {
-        Allowed,
-        // See #36887
-        FutureCompatDisallowed,
-        Deny,
-    }
-
-    let no_generics = hir::Generics::empty();
-    let ast_generics = node.generics().unwrap_or(&no_generics);
-    let (opt_self, allow_defaults) = match node {
-        Node::Item(item) => {
-            match item.kind {
-                ItemKind::Trait(..) | ItemKind::TraitAlias(..) => {
-                    // Add in the self type parameter.
-                    //
-                    // Something of a hack: use the node id for the trait, also as
-                    // the node id for the Self type parameter.
-                    let opt_self = Some(ty::GenericParamDef {
-                        index: 0,
-                        name: kw::SelfUpper,
-                        def_id,
-                        pure_wrt_drop: false,
-                        kind: ty::GenericParamDefKind::Type {
-                            has_default: false,
-                            synthetic: false,
-                        },
-                    });
-
-                    (opt_self, Defaults::Allowed)
-                }
-                ItemKind::TyAlias(..)
-                | ItemKind::Enum(..)
-                | ItemKind::Struct(..)
-                | ItemKind::OpaqueTy(..)
-                | ItemKind::Union(..) => (None, Defaults::Allowed),
-                _ => (None, Defaults::FutureCompatDisallowed),
-            }
-        }
-
-        // GATs
-        Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
-            (None, Defaults::Deny)
-        }
-        Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => {
-            (None, Defaults::Deny)
-        }
-
-        _ => (None, Defaults::FutureCompatDisallowed),
-    };
-
-    let has_self = opt_self.is_some();
-    let mut parent_has_self = false;
-    let mut own_start = has_self as u32;
-    let parent_count = parent_def_id.map_or(0, |def_id| {
-        let generics = tcx.generics_of(def_id);
-        assert!(!has_self);
-        parent_has_self = generics.has_self;
-        own_start = generics.count() as u32;
-        generics.parent_count + generics.params.len()
-    });
-
-    let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize);
-
-    if let Some(opt_self) = opt_self {
-        params.push(opt_self);
-    }
-
-    let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
-    params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
-        name: param.name.ident().name,
-        index: own_start + i as u32,
-        def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
-        pure_wrt_drop: param.pure_wrt_drop,
-        kind: ty::GenericParamDefKind::Lifetime,
-    }));
-
-    // Now create the real type and const parameters.
-    let type_start = own_start - has_self as u32 + params.len() as u32;
-    let mut i = 0;
-
-    const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
-    `struct`, `enum`, `type`, or `trait` definitions";
-
-    params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
-        GenericParamKind::Lifetime { .. } => None,
-        GenericParamKind::Type { ref default, synthetic, .. } => {
-            if default.is_some() {
-                match allow_defaults {
-                    Defaults::Allowed => {}
-                    Defaults::FutureCompatDisallowed
-                        if tcx.features().default_type_parameter_fallback => {}
-                    Defaults::FutureCompatDisallowed => {
-                        tcx.struct_span_lint_hir(
-                            lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
-                            param.hir_id,
-                            param.span,
-                            |lint| {
-                                lint.build(TYPE_DEFAULT_NOT_ALLOWED).emit();
-                            },
-                        );
-                    }
-                    Defaults::Deny => {
-                        tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED);
-                    }
-                }
-            }
-
-            let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
-
-            let param_def = ty::GenericParamDef {
-                index: type_start + i as u32,
-                name: param.name.ident().name,
-                def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
-                pure_wrt_drop: param.pure_wrt_drop,
-                kind,
-            };
-            i += 1;
-            Some(param_def)
-        }
-        GenericParamKind::Const { default, .. } => {
-            if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() {
-                tcx.sess.span_err(
-                    param.span,
-                    "defaults for const parameters are only allowed in \
-                    `struct`, `enum`, `type`, or `trait` definitions",
-                );
-            }
-
-            let param_def = ty::GenericParamDef {
-                index: type_start + i as u32,
-                name: param.name.ident().name,
-                def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
-                pure_wrt_drop: param.pure_wrt_drop,
-                kind: ty::GenericParamDefKind::Const { has_default: default.is_some() },
-            };
-            i += 1;
-            Some(param_def)
-        }
-    }));
-
-    // provide junk type parameter defs - the only place that
-    // cares about anything but the length is instantiation,
-    // and we don't do that for closures.
-    if let Node::Expr(&hir::Expr {
-        kind: hir::ExprKind::Closure(hir::Closure { movability: gen, .. }),
-        ..
-    }) = node
-    {
-        let dummy_args = if gen.is_some() {
-            &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
-        } else {
-            &["<closure_kind>", "<closure_signature>", "<upvars>"][..]
-        };
-
-        params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef {
-            index: type_start + i as u32,
-            name: Symbol::intern(arg),
-            def_id,
-            pure_wrt_drop: false,
-            kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
-        }));
-    }
-
-    // provide junk type parameter defs for const blocks.
-    if let Node::AnonConst(_) = node {
-        let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
-        if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node {
-            params.push(ty::GenericParamDef {
-                index: type_start,
-                name: Symbol::intern("<const_ty>"),
-                def_id,
-                pure_wrt_drop: false,
-                kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
-            });
-        }
-    }
-
-    let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect();
-
-    ty::Generics {
-        parent: parent_def_id,
-        parent_count,
-        params,
-        param_def_id_to_index,
-        has_self: has_self || parent_has_self,
-        has_late_bound_regions: has_late_bound_regions(tcx, node),
-    }
-}
-
 fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
     generic_args.iter().any(|arg| match arg {
         hir::GenericArg::Type(ty) => is_suggestable_infer_ty(ty),
@@ -2093,450 +1375,6 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate
     result
 }
 
-/// Returns a list of all type predicates (explicit and implicit) for the definition with
-/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
-/// `Self: Trait` predicates for traits.
-fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
-    let mut result = tcx.predicates_defined_on(def_id);
-
-    if tcx.is_trait(def_id) {
-        // For traits, add `Self: Trait` predicate. This is
-        // not part of the predicates that a user writes, but it
-        // is something that one must prove in order to invoke a
-        // method or project an associated type.
-        //
-        // In the chalk setup, this predicate is not part of the
-        // "predicates" for a trait item. But it is useful in
-        // rustc because if you directly (e.g.) invoke a trait
-        // method like `Trait::method(...)`, you must naturally
-        // prove that the trait applies to the types that were
-        // used, and adding the predicate into this list ensures
-        // that this is done.
-        //
-        // We use a DUMMY_SP here as a way to signal trait bounds that come
-        // from the trait itself that *shouldn't* be shown as the source of
-        // an obligation and instead be skipped. Otherwise we'd use
-        // `tcx.def_span(def_id);`
-
-        let constness = if tcx.has_attr(def_id, sym::const_trait) {
-            ty::BoundConstness::ConstIfConst
-        } else {
-            ty::BoundConstness::NotConst
-        };
-
-        let span = rustc_span::DUMMY_SP;
-        result.predicates =
-            tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
-                ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
-                span,
-            ))));
-    }
-    debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
-    result
-}
-
-/// Returns a list of user-specified type predicates for the definition with ID `def_id`.
-/// N.B., this does not include any implied/inferred constraints.
-#[instrument(level = "trace", skip(tcx), ret)]
-fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
-    use rustc_hir::*;
-
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
-    let node = tcx.hir().get(hir_id);
-
-    let mut is_trait = None;
-    let mut is_default_impl_trait = None;
-
-    let icx = ItemCtxt::new(tcx, def_id);
-
-    const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
-
-    // We use an `IndexSet` to preserves order of insertion.
-    // Preserving the order of insertion is important here so as not to break UI tests.
-    let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default();
-
-    let ast_generics = match node {
-        Node::TraitItem(item) => item.generics,
-
-        Node::ImplItem(item) => item.generics,
-
-        Node::Item(item) => {
-            match item.kind {
-                ItemKind::Impl(ref impl_) => {
-                    if impl_.defaultness.is_default() {
-                        is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy);
-                    }
-                    &impl_.generics
-                }
-                ItemKind::Fn(.., ref generics, _)
-                | ItemKind::TyAlias(_, ref generics)
-                | ItemKind::Enum(_, ref generics)
-                | ItemKind::Struct(_, ref generics)
-                | ItemKind::Union(_, ref generics) => *generics,
-
-                ItemKind::Trait(_, _, ref generics, ..) => {
-                    is_trait = Some(ty::TraitRef::identity(tcx, def_id));
-                    *generics
-                }
-                ItemKind::TraitAlias(ref generics, _) => {
-                    is_trait = Some(ty::TraitRef::identity(tcx, def_id));
-                    *generics
-                }
-                ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
-                    ..
-                }) => {
-                    // return-position impl trait
-                    //
-                    // We don't inherit predicates from the parent here:
-                    // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
-                    // then the return type is `f::<'static, T>::{{opaque}}`.
-                    //
-                    // If we inherited the predicates of `f` then we would
-                    // require that `T: 'static` to show that the return
-                    // type is well-formed.
-                    //
-                    // The only way to have something with this opaque type
-                    // is from the return type of the containing function,
-                    // which will ensure that the function's predicates
-                    // hold.
-                    return ty::GenericPredicates { parent: None, predicates: &[] };
-                }
-                ItemKind::OpaqueTy(OpaqueTy {
-                    ref generics,
-                    origin: hir::OpaqueTyOrigin::TyAlias,
-                    ..
-                }) => {
-                    // type-alias impl trait
-                    generics
-                }
-
-                _ => NO_GENERICS,
-            }
-        }
-
-        Node::ForeignItem(item) => match item.kind {
-            ForeignItemKind::Static(..) => NO_GENERICS,
-            ForeignItemKind::Fn(_, _, ref generics) => *generics,
-            ForeignItemKind::Type => NO_GENERICS,
-        },
-
-        _ => NO_GENERICS,
-    };
-
-    let generics = tcx.generics_of(def_id);
-    let parent_count = generics.parent_count as u32;
-    let has_own_self = generics.has_self && parent_count == 0;
-
-    // Below we'll consider the bounds on the type parameters (including `Self`)
-    // and the explicit where-clauses, but to get the full set of predicates
-    // on a trait we need to add in the supertrait bounds and bounds found on
-    // associated types.
-    if let Some(_trait_ref) = is_trait {
-        predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
-    }
-
-    // In default impls, we can assume that the self type implements
-    // the trait. So in:
-    //
-    //     default impl Foo for Bar { .. }
-    //
-    // we add a default where clause `Foo: Bar`. We do a similar thing for traits
-    // (see below). Recall that a default impl is not itself an impl, but rather a
-    // set of defaults that can be incorporated into another impl.
-    if let Some(trait_ref) = is_default_impl_trait {
-        predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
-    }
-
-    // Collect the region predicates that were declared inline as
-    // well. In the case of parameters declared on a fn or method, we
-    // have to be careful to only iterate over early-bound regions.
-    let mut index = parent_count
-        + has_own_self as u32
-        + early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
-
-    trace!(?predicates);
-    trace!(?ast_generics);
-
-    // Collect the predicates that were written inline by the user on each
-    // type parameter (e.g., `<T: Foo>`).
-    for param in ast_generics.params {
-        match param.kind {
-            // We already dealt with early bound lifetimes above.
-            GenericParamKind::Lifetime { .. } => (),
-            GenericParamKind::Type { .. } => {
-                let name = param.name.ident().name;
-                let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
-                index += 1;
-
-                let mut bounds = Bounds::default();
-                // Params are implicitly sized unless a `?Sized` bound is found
-                <dyn AstConv<'_>>::add_implicitly_sized(
-                    &icx,
-                    &mut bounds,
-                    &[],
-                    Some((param.hir_id, ast_generics.predicates)),
-                    param.span,
-                );
-                trace!(?bounds);
-                predicates.extend(bounds.predicates(tcx, param_ty));
-                trace!(?predicates);
-            }
-            GenericParamKind::Const { .. } => {
-                // Bounds on const parameters are currently not possible.
-                index += 1;
-            }
-        }
-    }
-
-    trace!(?predicates);
-    // Add in the bounds that appear in the where-clause.
-    for predicate in ast_generics.predicates {
-        match predicate {
-            hir::WherePredicate::BoundPredicate(bound_pred) => {
-                let ty = icx.to_ty(bound_pred.bounded_ty);
-                let bound_vars = icx.tcx.late_bound_vars(bound_pred.bounded_ty.hir_id);
-
-                // Keep the type around in a dummy predicate, in case of no bounds.
-                // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
-                // is still checked for WF.
-                if bound_pred.bounds.is_empty() {
-                    if let ty::Param(_) = ty.kind() {
-                        // This is a `where T:`, which can be in the HIR from the
-                        // transformation that moves `?Sized` to `T`'s declaration.
-                        // We can skip the predicate because type parameters are
-                        // trivially WF, but also we *should*, to avoid exposing
-                        // users who never wrote `where Type:,` themselves, to
-                        // compiler/tooling bugs from not handling WF predicates.
-                    } else {
-                        let span = bound_pred.bounded_ty.span;
-                        let predicate = ty::Binder::bind_with_vars(
-                            ty::PredicateKind::WellFormed(ty.into()),
-                            bound_vars,
-                        );
-                        predicates.insert((predicate.to_predicate(tcx), span));
-                    }
-                }
-
-                let mut bounds = Bounds::default();
-                <dyn AstConv<'_>>::add_bounds(
-                    &icx,
-                    ty,
-                    bound_pred.bounds.iter(),
-                    &mut bounds,
-                    bound_vars,
-                );
-                predicates.extend(bounds.predicates(tcx, ty));
-            }
-
-            hir::WherePredicate::RegionPredicate(region_pred) => {
-                let r1 = <dyn AstConv<'_>>::ast_region_to_region(&icx, &region_pred.lifetime, None);
-                predicates.extend(region_pred.bounds.iter().map(|bound| {
-                    let (r2, span) = match bound {
-                        hir::GenericBound::Outlives(lt) => {
-                            (<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.span)
-                        }
-                        _ => bug!(),
-                    };
-                    let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
-                        ty::OutlivesPredicate(r1, r2),
-                    ))
-                    .to_predicate(icx.tcx);
-
-                    (pred, span)
-                }))
-            }
-
-            hir::WherePredicate::EqPredicate(..) => {
-                // FIXME(#20041)
-            }
-        }
-    }
-
-    if tcx.features().generic_const_exprs {
-        predicates.extend(const_evaluatable_predicates_of(tcx, def_id.expect_local()));
-    }
-
-    let mut predicates: Vec<_> = predicates.into_iter().collect();
-
-    // Subtle: before we store the predicates into the tcx, we
-    // sort them so that predicates like `T: Foo<Item=U>` come
-    // before uses of `U`.  This avoids false ambiguity errors
-    // in trait checking. See `setup_constraining_predicates`
-    // for details.
-    if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
-        let self_ty = tcx.type_of(def_id);
-        let trait_ref = tcx.impl_trait_ref(def_id);
-        cgp::setup_constraining_predicates(
-            tcx,
-            &mut predicates,
-            trait_ref,
-            &mut cgp::parameters_for_impl(self_ty, trait_ref),
-        );
-    }
-
-    ty::GenericPredicates {
-        parent: generics.parent,
-        predicates: tcx.arena.alloc_from_iter(predicates),
-    }
-}
-
-fn const_evaluatable_predicates_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    def_id: LocalDefId,
-) -> FxIndexSet<(ty::Predicate<'tcx>, Span)> {
-    struct ConstCollector<'tcx> {
-        tcx: TyCtxt<'tcx>,
-        preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>,
-    }
-
-    impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> {
-        fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
-            let def_id = self.tcx.hir().local_def_id(c.hir_id);
-            let ct = ty::Const::from_anon_const(self.tcx, def_id);
-            if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
-                let span = self.tcx.hir().span(c.hir_id);
-                self.preds.insert((
-                    ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
-                        .to_predicate(self.tcx),
-                    span,
-                ));
-            }
-        }
-
-        fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) {
-            // Do not look into const param defaults,
-            // these get checked when they are actually instantiated.
-            //
-            // We do not want the following to error:
-            //
-            //     struct Foo<const N: usize, const M: usize = { N + 1 }>;
-            //     struct Bar<const N: usize>(Foo<N, 3>);
-        }
-    }
-
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-    let node = tcx.hir().get(hir_id);
-
-    let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
-    if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(ref impl_) = item.kind {
-        if let Some(of_trait) = &impl_.of_trait {
-            debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
-            collector.visit_trait_ref(of_trait);
-        }
-
-        debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id);
-        collector.visit_ty(impl_.self_ty);
-    }
-
-    if let Some(generics) = node.generics() {
-        debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id);
-        collector.visit_generics(generics);
-    }
-
-    if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) {
-        debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id);
-        collector.visit_fn_decl(fn_sig.decl);
-    }
-    debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds);
-
-    collector.preds
-}
-
-fn trait_explicit_predicates_and_bounds(
-    tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
-) -> ty::GenericPredicates<'_> {
-    assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
-    gather_explicit_predicates_of(tcx, def_id.to_def_id())
-}
-
-fn explicit_predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericPredicates<'tcx> {
-    let def_kind = tcx.def_kind(def_id);
-    if let DefKind::Trait = def_kind {
-        // Remove bounds on associated types from the predicates, they will be
-        // returned by `explicit_item_bounds`.
-        let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local());
-        let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
-
-        let is_assoc_item_ty = |ty: Ty<'tcx>| {
-            // For a predicate from a where clause to become a bound on an
-            // associated type:
-            // * It must use the identity substs of the item.
-            //     * Since any generic parameters on the item are not in scope,
-            //       this means that the item is not a GAT, and its identity
-            //       substs are the same as the trait's.
-            // * It must be an associated type for this trait (*not* a
-            //   supertrait).
-            if let ty::Projection(projection) = ty.kind() {
-                projection.substs == trait_identity_substs
-                    && tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id
-            } else {
-                false
-            }
-        };
-
-        let predicates: Vec<_> = predicates_and_bounds
-            .predicates
-            .iter()
-            .copied()
-            .filter(|(pred, _)| match pred.kind().skip_binder() {
-                ty::PredicateKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
-                ty::PredicateKind::Projection(proj) => {
-                    !is_assoc_item_ty(proj.projection_ty.self_ty())
-                }
-                ty::PredicateKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
-                _ => true,
-            })
-            .collect();
-        if predicates.len() == predicates_and_bounds.predicates.len() {
-            predicates_and_bounds
-        } else {
-            ty::GenericPredicates {
-                parent: predicates_and_bounds.parent,
-                predicates: tcx.arena.alloc_slice(&predicates),
-            }
-        }
-    } else {
-        if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
-            let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
-            if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() {
-                // In `generics_of` we set the generics' parent to be our parent's parent which means that
-                // we lose out on the predicates of our actual parent if we dont return those predicates here.
-                // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
-                //
-                // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
-                //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
-                //        ^^^                                             explicit_predicates_of on
-                //        parent item we dont have set as the
-                //        parent of generics returned by `generics_of`
-                //
-                // In the above code we want the anon const to have predicates in its param env for `T: Trait`
-                let item_def_id = tcx.hir().get_parent_item(hir_id);
-                // In the above code example we would be calling `explicit_predicates_of(Foo)` here
-                return tcx.explicit_predicates_of(item_def_id);
-            }
-        }
-        gather_explicit_predicates_of(tcx, def_id)
-    }
-}
-
-/// Converts a specific `GenericBound` from the AST into a set of
-/// predicates that apply to the self type. A vector is returned
-/// because this can be anywhere from zero predicates (`T: ?Sized` adds no
-/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar`
-/// and `<T as Bar>::X == i32`).
-fn predicates_from_bound<'tcx>(
-    astconv: &dyn AstConv<'tcx>,
-    param_ty: Ty<'tcx>,
-    bound: &'tcx hir::GenericBound<'tcx>,
-    bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
-) -> Vec<(ty::Predicate<'tcx>, Span)> {
-    let mut bounds = Bounds::default();
-    astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
-    bounds.predicates(astconv.tcx(), param_ty).collect()
-}
-
 fn compute_sig_of_foreign_fn_decl<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
@@ -2544,7 +1382,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        intrinsic_operation_unsafety(tcx.item_name(def_id))
+        intrinsic_operation_unsafety(tcx, def_id)
     } else {
         hir::Unsafety::Unsafe
     };
@@ -3229,11 +2067,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
                     lint::builtin::INLINE_NO_SANITIZE,
                     hir_id,
                     no_sanitize_span,
-                    |lint| {
-                        lint.build("`no_sanitize` will have no effect after inlining")
-                            .span_note(inline_span, "inlining requested here")
-                            .emit();
-                    },
+                    "`no_sanitize` will have no effect after inlining",
+                    |lint| lint.span_note(inline_span, "inlining requested here"),
                 )
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
new file mode 100644
index 00000000000..7ffacbecf5f
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -0,0 +1,480 @@
+use crate::middle::resolve_lifetime as rl;
+use hir::{
+    intravisit::{self, Visitor},
+    GenericParamKind, HirId, Node,
+};
+use rustc_hir as hir;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::DefId;
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_session::lint;
+use rustc_span::symbol::{kw, Symbol};
+use rustc_span::Span;
+
+pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
+    use rustc_hir::*;
+
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+
+    let node = tcx.hir().get(hir_id);
+    let parent_def_id = match node {
+        Node::ImplItem(_)
+        | Node::TraitItem(_)
+        | Node::Variant(_)
+        | Node::Ctor(..)
+        | Node::Field(_) => {
+            let parent_id = tcx.hir().get_parent_item(hir_id);
+            Some(parent_id.to_def_id())
+        }
+        // FIXME(#43408) always enable this once `lazy_normalization` is
+        // stable enough and does not need a feature gate anymore.
+        Node::AnonConst(_) => {
+            let parent_def_id = tcx.hir().get_parent_item(hir_id);
+
+            let mut in_param_ty = false;
+            for (_parent, node) in tcx.hir().parent_iter(hir_id) {
+                if let Some(generics) = node.generics() {
+                    let mut visitor = AnonConstInParamTyDetector {
+                        in_param_ty: false,
+                        found_anon_const_in_param_ty: false,
+                        ct: hir_id,
+                    };
+
+                    visitor.visit_generics(generics);
+                    in_param_ty = visitor.found_anon_const_in_param_ty;
+                    break;
+                }
+            }
+
+            if in_param_ty {
+                // We do not allow generic parameters in anon consts if we are inside
+                // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
+                None
+            } else if tcx.lazy_normalization() {
+                if let Some(param_id) = tcx.hir().opt_const_param_default_param_hir_id(hir_id) {
+                    // If the def_id we are calling generics_of on is an anon ct default i.e:
+                    //
+                    // struct Foo<const N: usize = { .. }>;
+                    //        ^^^       ^          ^^^^^^ def id of this anon const
+                    //        ^         ^ param_id
+                    //        ^ parent_def_id
+                    //
+                    // then we only want to return generics for params to the left of `N`. If we don't do that we
+                    // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`.
+                    //
+                    // This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as
+                    // we substitute the defaults with the partially built substs when we build the substs. Subst'ing
+                    // the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building.
+                    //
+                    // We fix this by having this function return the parent's generics ourselves and truncating the
+                    // generics to only include non-forward declared params (with the exception of the `Self` ty)
+                    //
+                    // For the above code example that means we want `substs: []`
+                    // For the following struct def we want `substs: [N#0]` when generics_of is called on
+                    // the def id of the `{ N + 1 }` anon const
+                    // struct Foo<const N: usize, const M: usize = { N + 1 }>;
+                    //
+                    // This has some implications for how we get the predicates available to the anon const
+                    // see `explicit_predicates_of` for more information on this
+                    let generics = tcx.generics_of(parent_def_id.to_def_id());
+                    let param_def = tcx.hir().local_def_id(param_id).to_def_id();
+                    let param_def_idx = generics.param_def_id_to_index[&param_def];
+                    // In the above example this would be .params[..N#0]
+                    let params = generics.params[..param_def_idx as usize].to_owned();
+                    let param_def_id_to_index =
+                        params.iter().map(|param| (param.def_id, param.index)).collect();
+
+                    return ty::Generics {
+                        // we set the parent of these generics to be our parent's parent so that we
+                        // dont end up with substs: [N, M, N] for the const default on a struct like this:
+                        // struct Foo<const N: usize, const M: usize = { ... }>;
+                        parent: generics.parent,
+                        parent_count: generics.parent_count,
+                        params,
+                        param_def_id_to_index,
+                        has_self: generics.has_self,
+                        has_late_bound_regions: generics.has_late_bound_regions,
+                    };
+                }
+
+                // HACK(eddyb) this provides the correct generics when
+                // `feature(generic_const_expressions)` is enabled, so that const expressions
+                // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
+                //
+                // Note that we do not supply the parent generics when using
+                // `min_const_generics`.
+                Some(parent_def_id.to_def_id())
+            } else {
+                let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+                match parent_node {
+                    // HACK(eddyb) this provides the correct generics for repeat
+                    // expressions' count (i.e. `N` in `[x; N]`), and explicit
+                    // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
+                    // as they shouldn't be able to cause query cycle errors.
+                    Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
+                        if constant.hir_id() == hir_id =>
+                    {
+                        Some(parent_def_id.to_def_id())
+                    }
+                    Node::Variant(Variant { disr_expr: Some(ref constant), .. })
+                        if constant.hir_id == hir_id =>
+                    {
+                        Some(parent_def_id.to_def_id())
+                    }
+                    Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
+                        Some(tcx.typeck_root_def_id(def_id))
+                    }
+                    // Exclude `GlobalAsm` here which cannot have generics.
+                    Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
+                        if asm.operands.iter().any(|(op, _op_sp)| match op {
+                            hir::InlineAsmOperand::Const { anon_const }
+                            | hir::InlineAsmOperand::SymFn { anon_const } => {
+                                anon_const.hir_id == hir_id
+                            }
+                            _ => false,
+                        }) =>
+                    {
+                        Some(parent_def_id.to_def_id())
+                    }
+                    _ => None,
+                }
+            }
+        }
+        Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
+            Some(tcx.typeck_root_def_id(def_id))
+        }
+        Node::Item(item) => match item.kind {
+            ItemKind::OpaqueTy(hir::OpaqueTy {
+                origin:
+                    hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+                in_trait,
+                ..
+            }) => {
+                if in_trait {
+                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
+                } else {
+                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
+                }
+                Some(fn_def_id.to_def_id())
+            }
+            ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
+                let parent_id = tcx.hir().get_parent_item(hir_id);
+                assert_ne!(parent_id, hir::CRATE_OWNER_ID);
+                debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
+                // Opaque types are always nested within another item, and
+                // inherit the generics of the item.
+                Some(parent_id.to_def_id())
+            }
+            _ => None,
+        },
+        _ => None,
+    };
+
+    enum Defaults {
+        Allowed,
+        // See #36887
+        FutureCompatDisallowed,
+        Deny,
+    }
+
+    let no_generics = hir::Generics::empty();
+    let ast_generics = node.generics().unwrap_or(&no_generics);
+    let (opt_self, allow_defaults) = match node {
+        Node::Item(item) => {
+            match item.kind {
+                ItemKind::Trait(..) | ItemKind::TraitAlias(..) => {
+                    // Add in the self type parameter.
+                    //
+                    // Something of a hack: use the node id for the trait, also as
+                    // the node id for the Self type parameter.
+                    let opt_self = Some(ty::GenericParamDef {
+                        index: 0,
+                        name: kw::SelfUpper,
+                        def_id,
+                        pure_wrt_drop: false,
+                        kind: ty::GenericParamDefKind::Type {
+                            has_default: false,
+                            synthetic: false,
+                        },
+                    });
+
+                    (opt_self, Defaults::Allowed)
+                }
+                ItemKind::TyAlias(..)
+                | ItemKind::Enum(..)
+                | ItemKind::Struct(..)
+                | ItemKind::OpaqueTy(..)
+                | ItemKind::Union(..) => (None, Defaults::Allowed),
+                _ => (None, Defaults::FutureCompatDisallowed),
+            }
+        }
+
+        // GATs
+        Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
+            (None, Defaults::Deny)
+        }
+        Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => {
+            (None, Defaults::Deny)
+        }
+
+        _ => (None, Defaults::FutureCompatDisallowed),
+    };
+
+    let has_self = opt_self.is_some();
+    let mut parent_has_self = false;
+    let mut own_start = has_self as u32;
+    let parent_count = parent_def_id.map_or(0, |def_id| {
+        let generics = tcx.generics_of(def_id);
+        assert!(!has_self);
+        parent_has_self = generics.has_self;
+        own_start = generics.count() as u32;
+        generics.parent_count + generics.params.len()
+    });
+
+    let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize);
+
+    if let Some(opt_self) = opt_self {
+        params.push(opt_self);
+    }
+
+    let early_lifetimes = super::early_bound_lifetimes_from_generics(tcx, ast_generics);
+    params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef {
+        name: param.name.ident().name,
+        index: own_start + i as u32,
+        def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
+        pure_wrt_drop: param.pure_wrt_drop,
+        kind: ty::GenericParamDefKind::Lifetime,
+    }));
+
+    // Now create the real type and const parameters.
+    let type_start = own_start - has_self as u32 + params.len() as u32;
+    let mut i = 0;
+
+    const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
+    `struct`, `enum`, `type`, or `trait` definitions";
+
+    params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
+        GenericParamKind::Lifetime { .. } => None,
+        GenericParamKind::Type { ref default, synthetic, .. } => {
+            if default.is_some() {
+                match allow_defaults {
+                    Defaults::Allowed => {}
+                    Defaults::FutureCompatDisallowed
+                        if tcx.features().default_type_parameter_fallback => {}
+                    Defaults::FutureCompatDisallowed => {
+                        tcx.struct_span_lint_hir(
+                            lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
+                            param.hir_id,
+                            param.span,
+                            TYPE_DEFAULT_NOT_ALLOWED,
+                            |lint| lint,
+                        );
+                    }
+                    Defaults::Deny => {
+                        tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED);
+                    }
+                }
+            }
+
+            let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
+
+            let param_def = ty::GenericParamDef {
+                index: type_start + i as u32,
+                name: param.name.ident().name,
+                def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
+                pure_wrt_drop: param.pure_wrt_drop,
+                kind,
+            };
+            i += 1;
+            Some(param_def)
+        }
+        GenericParamKind::Const { default, .. } => {
+            if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() {
+                tcx.sess.span_err(
+                    param.span,
+                    "defaults for const parameters are only allowed in \
+                    `struct`, `enum`, `type`, or `trait` definitions",
+                );
+            }
+
+            let param_def = ty::GenericParamDef {
+                index: type_start + i as u32,
+                name: param.name.ident().name,
+                def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(),
+                pure_wrt_drop: param.pure_wrt_drop,
+                kind: ty::GenericParamDefKind::Const { has_default: default.is_some() },
+            };
+            i += 1;
+            Some(param_def)
+        }
+    }));
+
+    // provide junk type parameter defs - the only place that
+    // cares about anything but the length is instantiation,
+    // and we don't do that for closures.
+    if let Node::Expr(&hir::Expr {
+        kind: hir::ExprKind::Closure(hir::Closure { movability: gen, .. }),
+        ..
+    }) = node
+    {
+        let dummy_args = if gen.is_some() {
+            &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
+        } else {
+            &["<closure_kind>", "<closure_signature>", "<upvars>"][..]
+        };
+
+        params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef {
+            index: type_start + i as u32,
+            name: Symbol::intern(arg),
+            def_id,
+            pure_wrt_drop: false,
+            kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
+        }));
+    }
+
+    // provide junk type parameter defs for const blocks.
+    if let Node::AnonConst(_) = node {
+        let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+        if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node {
+            params.push(ty::GenericParamDef {
+                index: type_start,
+                name: Symbol::intern("<const_ty>"),
+                def_id,
+                pure_wrt_drop: false,
+                kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
+            });
+        }
+    }
+
+    let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect();
+
+    ty::Generics {
+        parent: parent_def_id,
+        parent_count,
+        params,
+        param_def_id_to_index,
+        has_self: has_self || parent_has_self,
+        has_late_bound_regions: has_late_bound_regions(tcx, node),
+    }
+}
+
+fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<Span> {
+    struct LateBoundRegionsDetector<'tcx> {
+        tcx: TyCtxt<'tcx>,
+        outer_index: ty::DebruijnIndex,
+        has_late_bound_regions: Option<Span>,
+    }
+
+    impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> {
+        fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
+            if self.has_late_bound_regions.is_some() {
+                return;
+            }
+            match ty.kind {
+                hir::TyKind::BareFn(..) => {
+                    self.outer_index.shift_in(1);
+                    intravisit::walk_ty(self, ty);
+                    self.outer_index.shift_out(1);
+                }
+                _ => intravisit::walk_ty(self, ty),
+            }
+        }
+
+        fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) {
+            if self.has_late_bound_regions.is_some() {
+                return;
+            }
+            self.outer_index.shift_in(1);
+            intravisit::walk_poly_trait_ref(self, tr);
+            self.outer_index.shift_out(1);
+        }
+
+        fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
+            if self.has_late_bound_regions.is_some() {
+                return;
+            }
+
+            match self.tcx.named_region(lt.hir_id) {
+                Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {}
+                Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {}
+                Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => {
+                    self.has_late_bound_regions = Some(lt.span);
+                }
+            }
+        }
+    }
+
+    fn has_late_bound_regions<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        generics: &'tcx hir::Generics<'tcx>,
+        decl: &'tcx hir::FnDecl<'tcx>,
+    ) -> Option<Span> {
+        let mut visitor = LateBoundRegionsDetector {
+            tcx,
+            outer_index: ty::INNERMOST,
+            has_late_bound_regions: None,
+        };
+        for param in generics.params {
+            if let GenericParamKind::Lifetime { .. } = param.kind {
+                if tcx.is_late_bound(param.hir_id) {
+                    return Some(param.span);
+                }
+            }
+        }
+        visitor.visit_fn_decl(decl);
+        visitor.has_late_bound_regions
+    }
+
+    match node {
+        Node::TraitItem(item) => match item.kind {
+            hir::TraitItemKind::Fn(ref sig, _) => {
+                has_late_bound_regions(tcx, &item.generics, sig.decl)
+            }
+            _ => None,
+        },
+        Node::ImplItem(item) => match item.kind {
+            hir::ImplItemKind::Fn(ref sig, _) => {
+                has_late_bound_regions(tcx, &item.generics, sig.decl)
+            }
+            _ => None,
+        },
+        Node::ForeignItem(item) => match item.kind {
+            hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => {
+                has_late_bound_regions(tcx, generics, fn_decl)
+            }
+            _ => None,
+        },
+        Node::Item(item) => match item.kind {
+            hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
+                has_late_bound_regions(tcx, generics, sig.decl)
+            }
+            _ => None,
+        },
+        _ => None,
+    }
+}
+
+struct AnonConstInParamTyDetector {
+    in_param_ty: bool,
+    found_anon_const_in_param_ty: bool,
+    ct: HirId,
+}
+
+impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
+    fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
+        if let GenericParamKind::Const { ty, default: _ } = p.kind {
+            let prev = self.in_param_ty;
+            self.in_param_ty = true;
+            self.visit_ty(ty);
+            self.in_param_ty = prev;
+        }
+    }
+
+    fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
+        if self.in_param_ty && self.ct == c.hir_id {
+            self.found_anon_const_in_param_ty = true;
+        } else {
+            intravisit::walk_anon_const(self, c)
+        }
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
new file mode 100644
index 00000000000..db8f8de68f2
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -0,0 +1,707 @@
+use crate::astconv::AstConv;
+use crate::bounds::Bounds;
+use crate::collect::ItemCtxt;
+use crate::constrained_generic_params as cgp;
+use hir::{HirId, Node};
+use rustc_data_structures::fx::FxIndexSet;
+use rustc_hir as hir;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::ToPredicate;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::symbol::{sym, Ident};
+use rustc_span::{Span, DUMMY_SP};
+
+#[derive(Debug)]
+struct OnlySelfBounds(bool);
+
+/// Returns a list of all type predicates (explicit and implicit) for the definition with
+/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
+/// `Self: Trait` predicates for traits.
+pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
+    let mut result = tcx.predicates_defined_on(def_id);
+
+    if tcx.is_trait(def_id) {
+        // For traits, add `Self: Trait` predicate. This is
+        // not part of the predicates that a user writes, but it
+        // is something that one must prove in order to invoke a
+        // method or project an associated type.
+        //
+        // In the chalk setup, this predicate is not part of the
+        // "predicates" for a trait item. But it is useful in
+        // rustc because if you directly (e.g.) invoke a trait
+        // method like `Trait::method(...)`, you must naturally
+        // prove that the trait applies to the types that were
+        // used, and adding the predicate into this list ensures
+        // that this is done.
+        //
+        // We use a DUMMY_SP here as a way to signal trait bounds that come
+        // from the trait itself that *shouldn't* be shown as the source of
+        // an obligation and instead be skipped. Otherwise we'd use
+        // `tcx.def_span(def_id);`
+
+        let constness = if tcx.has_attr(def_id, sym::const_trait) {
+            ty::BoundConstness::ConstIfConst
+        } else {
+            ty::BoundConstness::NotConst
+        };
+
+        let span = rustc_span::DUMMY_SP;
+        result.predicates =
+            tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
+                ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
+                span,
+            ))));
+    }
+    debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
+    result
+}
+
+/// Returns a list of user-specified type predicates for the definition with ID `def_id`.
+/// N.B., this does not include any implied/inferred constraints.
+#[instrument(level = "trace", skip(tcx), ret)]
+fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
+    use rustc_hir::*;
+
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+    let node = tcx.hir().get(hir_id);
+
+    let mut is_trait = None;
+    let mut is_default_impl_trait = None;
+
+    let icx = ItemCtxt::new(tcx, def_id);
+
+    const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
+
+    // We use an `IndexSet` to preserves order of insertion.
+    // Preserving the order of insertion is important here so as not to break UI tests.
+    let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default();
+
+    let ast_generics = match node {
+        Node::TraitItem(item) => item.generics,
+
+        Node::ImplItem(item) => item.generics,
+
+        Node::Item(item) => {
+            match item.kind {
+                ItemKind::Impl(ref impl_) => {
+                    if impl_.defaultness.is_default() {
+                        is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy);
+                    }
+                    &impl_.generics
+                }
+                ItemKind::Fn(.., ref generics, _)
+                | ItemKind::TyAlias(_, ref generics)
+                | ItemKind::Enum(_, ref generics)
+                | ItemKind::Struct(_, ref generics)
+                | ItemKind::Union(_, ref generics) => *generics,
+
+                ItemKind::Trait(_, _, ref generics, ..) => {
+                    is_trait = Some(ty::TraitRef::identity(tcx, def_id));
+                    *generics
+                }
+                ItemKind::TraitAlias(ref generics, _) => {
+                    is_trait = Some(ty::TraitRef::identity(tcx, def_id));
+                    *generics
+                }
+                ItemKind::OpaqueTy(OpaqueTy {
+                    origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
+                    ..
+                }) => {
+                    // return-position impl trait
+                    //
+                    // We don't inherit predicates from the parent here:
+                    // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
+                    // then the return type is `f::<'static, T>::{{opaque}}`.
+                    //
+                    // If we inherited the predicates of `f` then we would
+                    // require that `T: 'static` to show that the return
+                    // type is well-formed.
+                    //
+                    // The only way to have something with this opaque type
+                    // is from the return type of the containing function,
+                    // which will ensure that the function's predicates
+                    // hold.
+                    return ty::GenericPredicates { parent: None, predicates: &[] };
+                }
+                ItemKind::OpaqueTy(OpaqueTy {
+                    ref generics,
+                    origin: hir::OpaqueTyOrigin::TyAlias,
+                    ..
+                }) => {
+                    // type-alias impl trait
+                    generics
+                }
+
+                _ => NO_GENERICS,
+            }
+        }
+
+        Node::ForeignItem(item) => match item.kind {
+            ForeignItemKind::Static(..) => NO_GENERICS,
+            ForeignItemKind::Fn(_, _, ref generics) => *generics,
+            ForeignItemKind::Type => NO_GENERICS,
+        },
+
+        _ => NO_GENERICS,
+    };
+
+    let generics = tcx.generics_of(def_id);
+    let parent_count = generics.parent_count as u32;
+    let has_own_self = generics.has_self && parent_count == 0;
+
+    // Below we'll consider the bounds on the type parameters (including `Self`)
+    // and the explicit where-clauses, but to get the full set of predicates
+    // on a trait we need to add in the supertrait bounds and bounds found on
+    // associated types.
+    if let Some(_trait_ref) = is_trait {
+        predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
+    }
+
+    // In default impls, we can assume that the self type implements
+    // the trait. So in:
+    //
+    //     default impl Foo for Bar { .. }
+    //
+    // we add a default where clause `Foo: Bar`. We do a similar thing for traits
+    // (see below). Recall that a default impl is not itself an impl, but rather a
+    // set of defaults that can be incorporated into another impl.
+    if let Some(trait_ref) = is_default_impl_trait {
+        predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
+    }
+
+    // Collect the region predicates that were declared inline as
+    // well. In the case of parameters declared on a fn or method, we
+    // have to be careful to only iterate over early-bound regions.
+    let mut index = parent_count
+        + has_own_self as u32
+        + super::early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
+
+    trace!(?predicates);
+    trace!(?ast_generics);
+
+    // Collect the predicates that were written inline by the user on each
+    // type parameter (e.g., `<T: Foo>`).
+    for param in ast_generics.params {
+        match param.kind {
+            // We already dealt with early bound lifetimes above.
+            GenericParamKind::Lifetime { .. } => (),
+            GenericParamKind::Type { .. } => {
+                let name = param.name.ident().name;
+                let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
+                index += 1;
+
+                let mut bounds = Bounds::default();
+                // Params are implicitly sized unless a `?Sized` bound is found
+                <dyn AstConv<'_>>::add_implicitly_sized(
+                    &icx,
+                    &mut bounds,
+                    &[],
+                    Some((param.hir_id, ast_generics.predicates)),
+                    param.span,
+                );
+                trace!(?bounds);
+                predicates.extend(bounds.predicates(tcx, param_ty));
+                trace!(?predicates);
+            }
+            GenericParamKind::Const { .. } => {
+                // Bounds on const parameters are currently not possible.
+                index += 1;
+            }
+        }
+    }
+
+    trace!(?predicates);
+    // Add in the bounds that appear in the where-clause.
+    for predicate in ast_generics.predicates {
+        match predicate {
+            hir::WherePredicate::BoundPredicate(bound_pred) => {
+                let ty = icx.to_ty(bound_pred.bounded_ty);
+                let bound_vars = icx.tcx.late_bound_vars(bound_pred.hir_id);
+
+                // Keep the type around in a dummy predicate, in case of no bounds.
+                // That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
+                // is still checked for WF.
+                if bound_pred.bounds.is_empty() {
+                    if let ty::Param(_) = ty.kind() {
+                        // This is a `where T:`, which can be in the HIR from the
+                        // transformation that moves `?Sized` to `T`'s declaration.
+                        // We can skip the predicate because type parameters are
+                        // trivially WF, but also we *should*, to avoid exposing
+                        // users who never wrote `where Type:,` themselves, to
+                        // compiler/tooling bugs from not handling WF predicates.
+                    } else {
+                        let span = bound_pred.bounded_ty.span;
+                        let predicate = ty::Binder::bind_with_vars(
+                            ty::PredicateKind::WellFormed(ty.into()),
+                            bound_vars,
+                        );
+                        predicates.insert((predicate.to_predicate(tcx), span));
+                    }
+                }
+
+                let mut bounds = Bounds::default();
+                <dyn AstConv<'_>>::add_bounds(
+                    &icx,
+                    ty,
+                    bound_pred.bounds.iter(),
+                    &mut bounds,
+                    bound_vars,
+                );
+                predicates.extend(bounds.predicates(tcx, ty));
+            }
+
+            hir::WherePredicate::RegionPredicate(region_pred) => {
+                let r1 = <dyn AstConv<'_>>::ast_region_to_region(&icx, &region_pred.lifetime, None);
+                predicates.extend(region_pred.bounds.iter().map(|bound| {
+                    let (r2, span) = match bound {
+                        hir::GenericBound::Outlives(lt) => {
+                            (<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.span)
+                        }
+                        _ => bug!(),
+                    };
+                    let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives(
+                        ty::OutlivesPredicate(r1, r2),
+                    ))
+                    .to_predicate(icx.tcx);
+
+                    (pred, span)
+                }))
+            }
+
+            hir::WherePredicate::EqPredicate(..) => {
+                // FIXME(#20041)
+            }
+        }
+    }
+
+    if tcx.features().generic_const_exprs {
+        predicates.extend(const_evaluatable_predicates_of(tcx, def_id.expect_local()));
+    }
+
+    let mut predicates: Vec<_> = predicates.into_iter().collect();
+
+    // Subtle: before we store the predicates into the tcx, we
+    // sort them so that predicates like `T: Foo<Item=U>` come
+    // before uses of `U`.  This avoids false ambiguity errors
+    // in trait checking. See `setup_constraining_predicates`
+    // for details.
+    if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
+        let self_ty = tcx.type_of(def_id);
+        let trait_ref = tcx.impl_trait_ref(def_id);
+        cgp::setup_constraining_predicates(
+            tcx,
+            &mut predicates,
+            trait_ref,
+            &mut cgp::parameters_for_impl(self_ty, trait_ref),
+        );
+    }
+
+    ty::GenericPredicates {
+        parent: generics.parent,
+        predicates: tcx.arena.alloc_from_iter(predicates),
+    }
+}
+
+fn const_evaluatable_predicates_of<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> FxIndexSet<(ty::Predicate<'tcx>, Span)> {
+    struct ConstCollector<'tcx> {
+        tcx: TyCtxt<'tcx>,
+        preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>,
+    }
+
+    impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> {
+        fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
+            let def_id = self.tcx.hir().local_def_id(c.hir_id);
+            let ct = ty::Const::from_anon_const(self.tcx, def_id);
+            if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
+                let span = self.tcx.hir().span(c.hir_id);
+                self.preds.insert((
+                    ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
+                        .to_predicate(self.tcx),
+                    span,
+                ));
+            }
+        }
+
+        fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) {
+            // Do not look into const param defaults,
+            // these get checked when they are actually instantiated.
+            //
+            // We do not want the following to error:
+            //
+            //     struct Foo<const N: usize, const M: usize = { N + 1 }>;
+            //     struct Bar<const N: usize>(Foo<N, 3>);
+        }
+    }
+
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+    let node = tcx.hir().get(hir_id);
+
+    let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
+    if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(ref impl_) = item.kind {
+        if let Some(of_trait) = &impl_.of_trait {
+            debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
+            collector.visit_trait_ref(of_trait);
+        }
+
+        debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id);
+        collector.visit_ty(impl_.self_ty);
+    }
+
+    if let Some(generics) = node.generics() {
+        debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id);
+        collector.visit_generics(generics);
+    }
+
+    if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) {
+        debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id);
+        collector.visit_fn_decl(fn_sig.decl);
+    }
+    debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds);
+
+    collector.preds
+}
+
+pub(super) fn trait_explicit_predicates_and_bounds(
+    tcx: TyCtxt<'_>,
+    def_id: LocalDefId,
+) -> ty::GenericPredicates<'_> {
+    assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
+    gather_explicit_predicates_of(tcx, def_id.to_def_id())
+}
+
+pub(super) fn explicit_predicates_of<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+) -> ty::GenericPredicates<'tcx> {
+    let def_kind = tcx.def_kind(def_id);
+    if let DefKind::Trait = def_kind {
+        // Remove bounds on associated types from the predicates, they will be
+        // returned by `explicit_item_bounds`.
+        let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local());
+        let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
+
+        let is_assoc_item_ty = |ty: Ty<'tcx>| {
+            // For a predicate from a where clause to become a bound on an
+            // associated type:
+            // * It must use the identity substs of the item.
+            //     * Since any generic parameters on the item are not in scope,
+            //       this means that the item is not a GAT, and its identity
+            //       substs are the same as the trait's.
+            // * It must be an associated type for this trait (*not* a
+            //   supertrait).
+            if let ty::Projection(projection) = ty.kind() {
+                projection.substs == trait_identity_substs
+                    && tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id
+            } else {
+                false
+            }
+        };
+
+        let predicates: Vec<_> = predicates_and_bounds
+            .predicates
+            .iter()
+            .copied()
+            .filter(|(pred, _)| match pred.kind().skip_binder() {
+                ty::PredicateKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
+                ty::PredicateKind::Projection(proj) => {
+                    !is_assoc_item_ty(proj.projection_ty.self_ty())
+                }
+                ty::PredicateKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
+                _ => true,
+            })
+            .collect();
+        if predicates.len() == predicates_and_bounds.predicates.len() {
+            predicates_and_bounds
+        } else {
+            ty::GenericPredicates {
+                parent: predicates_and_bounds.parent,
+                predicates: tcx.arena.alloc_slice(&predicates),
+            }
+        }
+    } else {
+        if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
+            let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+            if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() {
+                // In `generics_of` we set the generics' parent to be our parent's parent which means that
+                // we lose out on the predicates of our actual parent if we dont return those predicates here.
+                // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
+                //
+                // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
+                //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
+                //        ^^^                                             explicit_predicates_of on
+                //        parent item we dont have set as the
+                //        parent of generics returned by `generics_of`
+                //
+                // In the above code we want the anon const to have predicates in its param env for `T: Trait`
+                let item_def_id = tcx.hir().get_parent_item(hir_id);
+                // In the above code example we would be calling `explicit_predicates_of(Foo)` here
+                return tcx.explicit_predicates_of(item_def_id);
+            }
+        }
+        gather_explicit_predicates_of(tcx, def_id)
+    }
+}
+
+/// Ensures that the super-predicates of the trait with a `DefId`
+/// of `trait_def_id` are converted and stored. This also ensures that
+/// the transitive super-predicates are converted.
+pub(super) fn super_predicates_of(
+    tcx: TyCtxt<'_>,
+    trait_def_id: DefId,
+) -> ty::GenericPredicates<'_> {
+    tcx.super_predicates_that_define_assoc_type((trait_def_id, None))
+}
+
+/// Ensures that the super-predicates of the trait with a `DefId`
+/// of `trait_def_id` are converted and stored. This also ensures that
+/// the transitive super-predicates are converted.
+pub(super) fn super_predicates_that_define_assoc_type(
+    tcx: TyCtxt<'_>,
+    (trait_def_id, assoc_name): (DefId, Option<Ident>),
+) -> ty::GenericPredicates<'_> {
+    if trait_def_id.is_local() {
+        debug!("local trait");
+        let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
+
+        let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
+            bug!("trait_node_id {} is not an item", trait_hir_id);
+        };
+
+        let (generics, bounds) = match item.kind {
+            hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
+            hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
+            _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
+        };
+
+        let icx = ItemCtxt::new(tcx, trait_def_id);
+
+        // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
+        let self_param_ty = tcx.types.self_param;
+        let superbounds1 = if let Some(assoc_name) = assoc_name {
+            <dyn AstConv<'_>>::compute_bounds_that_match_assoc_type(
+                &icx,
+                self_param_ty,
+                bounds,
+                assoc_name,
+            )
+        } else {
+            <dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds)
+        };
+
+        let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
+
+        // Convert any explicit superbounds in the where-clause,
+        // e.g., `trait Foo where Self: Bar`.
+        // In the case of trait aliases, however, we include all bounds in the where-clause,
+        // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>`
+        // as one of its "superpredicates".
+        let is_trait_alias = tcx.is_trait_alias(trait_def_id);
+        let superbounds2 = icx.type_parameter_bounds_in_generics(
+            generics,
+            item.hir_id(),
+            self_param_ty,
+            OnlySelfBounds(!is_trait_alias),
+            assoc_name,
+        );
+
+        // Combine the two lists to form the complete set of superbounds:
+        let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2));
+        debug!(?superbounds);
+
+        // Now require that immediate supertraits are converted,
+        // which will, in turn, reach indirect supertraits.
+        if assoc_name.is_none() {
+            // Now require that immediate supertraits are converted,
+            // which will, in turn, reach indirect supertraits.
+            for &(pred, span) in superbounds {
+                debug!("superbound: {:?}", pred);
+                if let ty::PredicateKind::Trait(bound) = pred.kind().skip_binder() {
+                    tcx.at(span).super_predicates_of(bound.def_id());
+                }
+            }
+        }
+
+        ty::GenericPredicates { parent: None, predicates: superbounds }
+    } else {
+        // if `assoc_name` is None, then the query should've been redirected to an
+        // external provider
+        assert!(assoc_name.is_some());
+        tcx.super_predicates_of(trait_def_id)
+    }
+}
+
+/// Returns the predicates defined on `item_def_id` of the form
+/// `X: Foo` where `X` is the type parameter `def_id`.
+#[instrument(level = "trace", skip(tcx))]
+pub(super) fn type_param_predicates(
+    tcx: TyCtxt<'_>,
+    (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
+) -> ty::GenericPredicates<'_> {
+    use rustc_hir::*;
+
+    // In the AST, bounds can derive from two places. Either
+    // written inline like `<T: Foo>` or in a where-clause like
+    // `where T: Foo`.
+
+    let param_id = tcx.hir().local_def_id_to_hir_id(def_id);
+    let param_owner = tcx.hir().ty_param_owner(def_id);
+    let generics = tcx.generics_of(param_owner);
+    let index = generics.param_def_id_to_index[&def_id.to_def_id()];
+    let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id));
+
+    // Don't look for bounds where the type parameter isn't in scope.
+    let parent = if item_def_id == param_owner.to_def_id() {
+        None
+    } else {
+        tcx.generics_of(item_def_id).parent
+    };
+
+    let mut result = parent
+        .map(|parent| {
+            let icx = ItemCtxt::new(tcx, parent);
+            icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name)
+        })
+        .unwrap_or_default();
+    let mut extend = None;
+
+    let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local());
+    let ast_generics = match tcx.hir().get(item_hir_id) {
+        Node::TraitItem(item) => &item.generics,
+
+        Node::ImplItem(item) => &item.generics,
+
+        Node::Item(item) => {
+            match item.kind {
+                ItemKind::Fn(.., ref generics, _)
+                | ItemKind::Impl(hir::Impl { ref generics, .. })
+                | ItemKind::TyAlias(_, ref generics)
+                | ItemKind::OpaqueTy(OpaqueTy {
+                    ref generics,
+                    origin: hir::OpaqueTyOrigin::TyAlias,
+                    ..
+                })
+                | ItemKind::Enum(_, ref generics)
+                | ItemKind::Struct(_, ref generics)
+                | ItemKind::Union(_, ref generics) => generics,
+                ItemKind::Trait(_, _, ref generics, ..) => {
+                    // Implied `Self: Trait` and supertrait bounds.
+                    if param_id == item_hir_id {
+                        let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
+                        extend =
+                            Some((identity_trait_ref.without_const().to_predicate(tcx), item.span));
+                    }
+                    generics
+                }
+                _ => return result,
+            }
+        }
+
+        Node::ForeignItem(item) => match item.kind {
+            ForeignItemKind::Fn(_, _, ref generics) => generics,
+            _ => return result,
+        },
+
+        _ => return result,
+    };
+
+    let icx = ItemCtxt::new(tcx, item_def_id);
+    let extra_predicates = extend.into_iter().chain(
+        icx.type_parameter_bounds_in_generics(
+            ast_generics,
+            param_id,
+            ty,
+            OnlySelfBounds(true),
+            Some(assoc_name),
+        )
+        .into_iter()
+        .filter(|(predicate, _)| match predicate.kind().skip_binder() {
+            ty::PredicateKind::Trait(data) => data.self_ty().is_param(index),
+            _ => false,
+        }),
+    );
+    result.predicates =
+        tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates));
+    result
+}
+
+impl<'tcx> ItemCtxt<'tcx> {
+    /// Finds bounds from `hir::Generics`. This requires scanning through the
+    /// AST. We do this to avoid having to convert *all* the bounds, which
+    /// would create artificial cycles. Instead, we can only convert the
+    /// bounds for a type parameter `X` if `X::Foo` is used.
+    #[instrument(level = "trace", skip(self, ast_generics))]
+    fn type_parameter_bounds_in_generics(
+        &self,
+        ast_generics: &'tcx hir::Generics<'tcx>,
+        param_id: hir::HirId,
+        ty: Ty<'tcx>,
+        only_self_bounds: OnlySelfBounds,
+        assoc_name: Option<Ident>,
+    ) -> Vec<(ty::Predicate<'tcx>, Span)> {
+        let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
+        trace!(?param_def_id);
+        ast_generics
+            .predicates
+            .iter()
+            .filter_map(|wp| match *wp {
+                hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
+                _ => None,
+            })
+            .flat_map(|bp| {
+                let bt = if bp.is_param_bound(param_def_id) {
+                    Some(ty)
+                } else if !only_self_bounds.0 {
+                    Some(self.to_ty(bp.bounded_ty))
+                } else {
+                    None
+                };
+                let bvars = self.tcx.late_bound_vars(bp.hir_id);
+
+                bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter(
+                    |(_, b, _)| match assoc_name {
+                        Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
+                        None => true,
+                    },
+                )
+            })
+            .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars))
+            .collect()
+    }
+
+    #[instrument(level = "trace", skip(self))]
+    fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
+        match b {
+            hir::GenericBound::Trait(poly_trait_ref, _) => {
+                let trait_ref = &poly_trait_ref.trait_ref;
+                if let Some(trait_did) = trait_ref.trait_def_id() {
+                    self.tcx.trait_may_define_assoc_type(trait_did, assoc_name)
+                } else {
+                    false
+                }
+            }
+            _ => false,
+        }
+    }
+}
+
+/// Converts a specific `GenericBound` from the AST into a set of
+/// predicates that apply to the self type. A vector is returned
+/// because this can be anywhere from zero predicates (`T: ?Sized` adds no
+/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar`
+/// and `<T as Bar>::X == i32`).
+fn predicates_from_bound<'tcx>(
+    astconv: &dyn AstConv<'tcx>,
+    param_ty: Ty<'tcx>,
+    bound: &'tcx hir::GenericBound<'tcx>,
+    bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
+) -> Vec<(ty::Predicate<'tcx>, Span)> {
+    let mut bounds = Bounds::default();
+    astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars);
+    bounds.predicates(astconv.tcx(), param_ty).collect()
+}
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 24fb0b1fd26..f8a62c84910 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -333,7 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     find_opaque_ty_constraints_for_tait(tcx, def_id)
                 }
                 // Opaque types desugared from `impl Trait`.
-                ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, .. }) => {
+                ItemKind::OpaqueTy(OpaqueTy {
+                    origin:
+                        hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
+                    in_trait,
+                    ..
+                }) => {
                     if in_trait {
                         span_bug!(item.span, "impl-trait in trait has no default")
                     } else {
@@ -378,7 +383,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 
         Node::Field(field) => icx.to_ty(field.ty),
 
-        Node::Expr(&Expr { kind: ExprKind::Closure{..}, .. }) => tcx.typeck(def_id).node_type(hir_id),
+        Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => {
+            tcx.typeck(def_id).node_type(hir_id)
+        }
 
         Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
             // We defer to `type_of` of the corresponding parameter
@@ -410,40 +417,91 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
                     if asm.operands.iter().any(|(op, _op_sp)| match op {
                         hir::InlineAsmOperand::Const { anon_const }
-                        | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
+                        | hir::InlineAsmOperand::SymFn { anon_const } => {
+                            anon_const.hir_id == hir_id
+                        }
                         _ => false,
                     }) =>
                 {
                     tcx.typeck(def_id).node_type(hir_id)
                 }
 
-                Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx
-                    .adt_def(tcx.hir().get_parent_item(hir_id))
-                    .repr()
-                    .discr_type()
-                    .to_ty(tcx),
+                Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
+                    tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
+                }
 
-                Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, ..  })
-                    if let Node::TraitRef(trait_ref) = tcx.hir().get(
-                        tcx.hir().get_parent_node(binding_id)
-                    ) =>
+                Node::TypeBinding(
+                    binding @ &TypeBinding {
+                        hir_id: binding_id,
+                        kind: TypeBindingKind::Equality { term: Term::Const(ref e) },
+                        ..
+                    },
+                ) if let Node::TraitRef(trait_ref) =
+                    tcx.hir().get(tcx.hir().get_parent_node(binding_id))
+                    && e.hir_id == hir_id =>
                 {
-                  let Some(trait_def_id) = trait_ref.trait_def_id() else {
-                    return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
-                  };
-                  let assoc_items = tcx.associated_items(trait_def_id);
-                  let assoc_item = assoc_items.find_by_name_and_kind(
-                    tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
-                  );
-                  if let Some(assoc_item) = assoc_item {
-                    tcx.type_of(assoc_item.def_id)
-                  } else {
-                      // FIXME(associated_const_equality): add a useful error message here.
-                      tcx.ty_error_with_message(
-                        DUMMY_SP,
-                        "Could not find associated const on trait",
-                    )
-                  }
+                    let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                        return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
+                    };
+                    let assoc_items = tcx.associated_items(trait_def_id);
+                    let assoc_item = assoc_items.find_by_name_and_kind(
+                        tcx,
+                        binding.ident,
+                        ty::AssocKind::Const,
+                        def_id.to_def_id(),
+                    );
+                    if let Some(assoc_item) = assoc_item {
+                        tcx.type_of(assoc_item.def_id)
+                    } else {
+                        // FIXME(associated_const_equality): add a useful error message here.
+                        tcx.ty_error_with_message(
+                            DUMMY_SP,
+                            "Could not find associated const on trait",
+                        )
+                    }
+                }
+
+                Node::TypeBinding(
+                    binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. },
+                ) if let Node::TraitRef(trait_ref) =
+                    tcx.hir().get(tcx.hir().get_parent_node(binding_id))
+                    && let Some((idx, _)) =
+                        gen_args.args.iter().enumerate().find(|(_, arg)| {
+                            if let GenericArg::Const(ct) = arg {
+                                ct.value.hir_id == hir_id
+                            } else {
+                                false
+                            }
+                        }) =>
+                {
+                    let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                        return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait");
+                    };
+                    let assoc_items = tcx.associated_items(trait_def_id);
+                    let assoc_item = assoc_items.find_by_name_and_kind(
+                        tcx,
+                        binding.ident,
+                        match kind {
+                            // I think `<A: T>` type bindings requires that `A` is a type
+                            TypeBindingKind::Constraint { .. }
+                            | TypeBindingKind::Equality { term: Term::Ty(..) } => {
+                                ty::AssocKind::Type
+                            }
+                            TypeBindingKind::Equality { term: Term::Const(..) } => {
+                                ty::AssocKind::Const
+                            }
+                        },
+                        def_id.to_def_id(),
+                    );
+                    if let Some(assoc_item) = assoc_item {
+                        tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id)
+                    } else {
+                        // FIXME(associated_const_equality): add a useful error message here.
+                        tcx.ty_error_with_message(
+                            DUMMY_SP,
+                            "Could not find associated const on trait",
+                        )
+                    }
                 }
 
                 Node::GenericParam(&GenericParam {
@@ -452,8 +510,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     ..
                 }) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)),
 
-                x =>
-                  tcx.ty_error_with_message(
+                x => tcx.ty_error_with_message(
                     DUMMY_SP,
                     &format!("unexpected const parent in type_of(): {x:?}"),
                 ),
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 44df47e2fa0..d891171b824 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1,4 +1,5 @@
-//! Errors emitted by typeck.
+//! Errors emitted by `hir_analysis`.
+
 use rustc_errors::IntoDiagnostic;
 use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -6,18 +7,18 @@ use rustc_middle::ty::Ty;
 use rustc_span::{symbol::Ident, Span, Symbol};
 
 #[derive(Diagnostic)]
-#[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")]
+#[diag(hir_analysis::field_multiply_specified_in_initializer, code = "E0062")]
 pub struct FieldMultiplySpecifiedInInitializer {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(typeck::previous_use_label)]
+    #[label(hir_analysis::previous_use_label)]
     pub prev_span: Span,
     pub ident: Ident,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::unrecognized_atomic_operation, code = "E0092")]
+#[diag(hir_analysis::unrecognized_atomic_operation, code = "E0092")]
 pub struct UnrecognizedAtomicOperation<'a> {
     #[primary_span]
     #[label]
@@ -26,7 +27,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
+#[diag(hir_analysis::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
 pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
     #[primary_span]
     #[label]
@@ -37,7 +38,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::unrecognized_intrinsic_function, code = "E0093")]
+#[diag(hir_analysis::unrecognized_intrinsic_function, code = "E0093")]
 pub struct UnrecognizedIntrinsicFunction {
     #[primary_span]
     #[label]
@@ -46,19 +47,19 @@ pub struct UnrecognizedIntrinsicFunction {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
+#[diag(hir_analysis::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
 pub struct LifetimesOrBoundsMismatchOnTrait {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(typeck::generics_label)]
+    #[label(hir_analysis::generics_label)]
     pub generics_span: Option<Span>,
     pub item_kind: &'static str,
     pub ident: Ident,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::drop_impl_on_wrong_item, code = "E0120")]
+#[diag(hir_analysis::drop_impl_on_wrong_item, code = "E0120")]
 pub struct DropImplOnWrongItem {
     #[primary_span]
     #[label]
@@ -66,18 +67,18 @@ pub struct DropImplOnWrongItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::field_already_declared, code = "E0124")]
+#[diag(hir_analysis::field_already_declared, code = "E0124")]
 pub struct FieldAlreadyDeclared {
     pub field_name: Ident,
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(typeck::previous_decl_label)]
+    #[label(hir_analysis::previous_decl_label)]
     pub prev_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::copy_impl_on_type_with_dtor, code = "E0184")]
+#[diag(hir_analysis::copy_impl_on_type_with_dtor, code = "E0184")]
 pub struct CopyImplOnTypeWithDtor {
     #[primary_span]
     #[label]
@@ -85,14 +86,14 @@ pub struct CopyImplOnTypeWithDtor {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::multiple_relaxed_default_bounds, code = "E0203")]
+#[diag(hir_analysis::multiple_relaxed_default_bounds, code = "E0203")]
 pub struct MultipleRelaxedDefaultBounds {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::copy_impl_on_non_adt, code = "E0206")]
+#[diag(hir_analysis::copy_impl_on_non_adt, code = "E0206")]
 pub struct CopyImplOnNonAdt {
     #[primary_span]
     #[label]
@@ -100,23 +101,23 @@ pub struct CopyImplOnNonAdt {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::trait_object_declared_with_no_traits, code = "E0224")]
+#[diag(hir_analysis::trait_object_declared_with_no_traits, code = "E0224")]
 pub struct TraitObjectDeclaredWithNoTraits {
     #[primary_span]
     pub span: Span,
-    #[label(typeck::alias_span)]
+    #[label(hir_analysis::alias_span)]
     pub trait_alias_span: Option<Span>,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0227")]
+#[diag(hir_analysis::ambiguous_lifetime_bound, code = "E0227")]
 pub struct AmbiguousLifetimeBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::assoc_type_binding_not_allowed, code = "E0229")]
+#[diag(hir_analysis::assoc_type_binding_not_allowed, code = "E0229")]
 pub struct AssocTypeBindingNotAllowed {
     #[primary_span]
     #[label]
@@ -124,14 +125,14 @@ pub struct AssocTypeBindingNotAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::functional_record_update_on_non_struct, code = "E0436")]
+#[diag(hir_analysis::functional_record_update_on_non_struct, code = "E0436")]
 pub struct FunctionalRecordUpdateOnNonStruct {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::typeof_reserved_keyword_used, code = "E0516")]
+#[diag(hir_analysis::typeof_reserved_keyword_used, code = "E0516")]
 pub struct TypeofReservedKeywordUsed<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
@@ -142,25 +143,25 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::return_stmt_outside_of_fn_body, code = "E0572")]
+#[diag(hir_analysis::return_stmt_outside_of_fn_body, code = "E0572")]
 pub struct ReturnStmtOutsideOfFnBody {
     #[primary_span]
     pub span: Span,
-    #[label(typeck::encl_body_label)]
+    #[label(hir_analysis::encl_body_label)]
     pub encl_body_span: Option<Span>,
-    #[label(typeck::encl_fn_label)]
+    #[label(hir_analysis::encl_fn_label)]
     pub encl_fn_span: Option<Span>,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::yield_expr_outside_of_generator, code = "E0627")]
+#[diag(hir_analysis::yield_expr_outside_of_generator, code = "E0627")]
 pub struct YieldExprOutsideOfGenerator {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::struct_expr_non_exhaustive, code = "E0639")]
+#[diag(hir_analysis::struct_expr_non_exhaustive, code = "E0639")]
 pub struct StructExprNonExhaustive {
     #[primary_span]
     pub span: Span,
@@ -168,26 +169,26 @@ pub struct StructExprNonExhaustive {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::method_call_on_unknown_type, code = "E0699")]
+#[diag(hir_analysis::method_call_on_unknown_type, code = "E0699")]
 pub struct MethodCallOnUnknownType {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::value_of_associated_struct_already_specified, code = "E0719")]
+#[diag(hir_analysis::value_of_associated_struct_already_specified, code = "E0719")]
 pub struct ValueOfAssociatedStructAlreadySpecified {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(typeck::previous_bound_label)]
+    #[label(hir_analysis::previous_bound_label)]
     pub prev_span: Span,
     pub item_name: Ident,
     pub def_path: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::address_of_temporary_taken, code = "E0745")]
+#[diag(hir_analysis::address_of_temporary_taken, code = "E0745")]
 pub struct AddressOfTemporaryTaken {
     #[primary_span]
     #[label]
@@ -197,7 +198,7 @@ pub struct AddressOfTemporaryTaken {
 #[derive(Subdiagnostic)]
 pub enum AddReturnTypeSuggestion {
     #[suggestion(
-        typeck::add_return_type_add,
+        hir_analysis::add_return_type_add,
         code = "-> {found} ",
         applicability = "machine-applicable"
     )]
@@ -207,7 +208,7 @@ pub enum AddReturnTypeSuggestion {
         found: String,
     },
     #[suggestion(
-        typeck::add_return_type_missing_here,
+        hir_analysis::add_return_type_missing_here,
         code = "-> _ ",
         applicability = "has-placeholders"
     )]
@@ -219,12 +220,12 @@ pub enum AddReturnTypeSuggestion {
 
 #[derive(Subdiagnostic)]
 pub enum ExpectedReturnTypeLabel<'tcx> {
-    #[label(typeck::expected_default_return_type)]
+    #[label(hir_analysis::expected_default_return_type)]
     Unit {
         #[primary_span]
         span: Span,
     },
-    #[label(typeck::expected_return_type)]
+    #[label(hir_analysis::expected_return_type)]
     Other {
         #[primary_span]
         span: Span,
@@ -233,7 +234,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::unconstrained_opaque_type)]
+#[diag(hir_analysis::unconstrained_opaque_type)]
 #[note]
 pub struct UnconstrainedOpaqueType {
     #[primary_span]
@@ -254,7 +255,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
         let mut err = handler.struct_span_err_with_code(
             self.span,
-            rustc_errors::fluent::typeck::missing_type_params,
+            rustc_errors::fluent::hir_analysis::missing_type_params,
             error_code!(E0393),
         );
         err.set_arg("parameterCount", self.missing_type_params.len());
@@ -267,7 +268,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
                 .join(", "),
         );
 
-        err.span_label(self.def_span, rustc_errors::fluent::typeck::label);
+        err.span_label(self.def_span, rustc_errors::fluent::hir_analysis::label);
 
         let mut suggested = false;
         // Don't suggest setting the type params if there are some already: the order is
@@ -282,7 +283,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
                 // least we can clue them to the correct syntax `Iterator<Type>`.
                 err.span_suggestion(
                     self.span,
-                    rustc_errors::fluent::typeck::suggestion,
+                    rustc_errors::fluent::hir_analysis::suggestion,
                     format!(
                         "{}<{}>",
                         snippet,
@@ -298,16 +299,16 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams {
             }
         }
         if !suggested {
-            err.span_label(self.span, rustc_errors::fluent::typeck::no_suggestion_label);
+            err.span_label(self.span, rustc_errors::fluent::hir_analysis::no_suggestion_label);
         }
 
-        err.note(rustc_errors::fluent::typeck::note);
+        err.note(rustc_errors::fluent::hir_analysis::note);
         err
     }
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::manual_implementation, code = "E0183")]
+#[diag(hir_analysis::manual_implementation, code = "E0183")]
 #[help]
 pub struct ManualImplementation {
     #[primary_span]
@@ -317,21 +318,21 @@ pub struct ManualImplementation {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::substs_on_overridden_impl)]
+#[diag(hir_analysis::substs_on_overridden_impl)]
 pub struct SubstsOnOverriddenImpl {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[diag(typeck::unused_extern_crate)]
+#[diag(hir_analysis::unused_extern_crate)]
 pub struct UnusedExternCrate {
     #[suggestion(applicability = "machine-applicable", code = "")]
     pub span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[diag(typeck::extern_crate_not_idiomatic)]
+#[diag(hir_analysis::extern_crate_not_idiomatic)]
 pub struct ExternCrateNotIdiomatic {
     #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")]
     pub span: Span,
@@ -340,7 +341,7 @@ pub struct ExternCrateNotIdiomatic {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::expected_used_symbol)]
+#[diag(hir_analysis::expected_used_symbol)]
 pub struct ExpectedUsedSymbol {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 1859473166a..d31b9b7ae46 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -70,7 +70,7 @@ This API is completely unstable and subject to change.
 #![feature(once_cell)]
 #![feature(slice_partition_dedup)]
 #![feature(try_blocks)]
-#![feature(is_some_with)]
+#![feature(is_some_and)]
 #![feature(type_alias_impl_trait)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_hir_analysis/src/mem_categorization.rs b/compiler/rustc_hir_analysis/src/mem_categorization.rs
index 39610e3ae38..46b49647836 100644
--- a/compiler/rustc_hir_analysis/src/mem_categorization.rs
+++ b/compiler/rustc_hir_analysis/src/mem_categorization.rs
@@ -560,7 +560,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
             Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
             | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfCtor(..)
-            | Res::SelfTy { .. } => {
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. } => {
                 // Structs and Unions have only have one variant.
                 Ok(VariantIdx::new(0))
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 99de5b65981..9d56764d489 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2158,8 +2158,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
         diag: &mut Diagnostic,
     ) {
+        if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
+            && let Some(msg) = self.should_suggest_as_ref(exp_found.expected, exp_found.found)
+        {
+            diag.span_suggestion(
+                span,
+                msg,
+                // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&`
+                format!("{}.as_ref()", snippet.trim_start_matches('&')),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
+    pub fn should_suggest_as_ref(&self, expected: Ty<'tcx>, found: Ty<'tcx>) -> Option<&str> {
         if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) =
-            (exp_found.expected.kind(), exp_found.found.kind())
+            (expected.kind(), found.kind())
         {
             if let ty::Adt(found_def, found_substs) = *found_ty.kind() {
                 if exp_def == &found_def {
@@ -2197,21 +2211,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                 _ => show_suggestion = false,
                             }
                         }
-                        if let (Ok(snippet), true) =
-                            (self.tcx.sess.source_map().span_to_snippet(span), show_suggestion)
-                        {
-                            diag.span_suggestion(
-                                span,
-                                *msg,
-                                // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&`
-                                format!("{}.as_ref()", snippet.trim_start_matches('&')),
-                                Applicability::MachineApplicable,
-                            );
+                        if show_suggestion {
+                            return Some(*msg);
                         }
                     }
                 }
             }
         }
+        None
     }
 
     pub fn report_and_explain_type_error(
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 baa97d72a4b..2775d14a847 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
@@ -435,6 +435,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 generics_def_id,
                 def_id: _,
                 generic_args,
+                have_turbofish,
             } => {
                 let generics = self.tcx.generics_of(generics_def_id);
                 let is_type = matches!(arg.unpack(), GenericArgKind::Type(_));
@@ -482,11 +483,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     .unwrap()
                     .into_buffer();
 
-                infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
-                    span: insert_span,
-                    arg_count: generic_args.len(),
-                    args,
-                });
+                if !have_turbofish {
+                    infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
+                        span: insert_span,
+                        arg_count: generic_args.len(),
+                        args,
+                    });
+                }
             }
             InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
                 let printer = fmt_printer(self, Namespace::ValueNS);
@@ -616,6 +619,7 @@ enum InferSourceKind<'tcx> {
         generics_def_id: DefId,
         def_id: DefId,
         generic_args: &'tcx [GenericArg<'tcx>],
+        have_turbofish: bool,
     },
     FullyQualifiedMethodCall {
         receiver: &'tcx Expr<'tcx>,
@@ -676,6 +680,7 @@ struct InsertableGenericArgs<'tcx> {
     substs: SubstsRef<'tcx>,
     generics_def_id: DefId,
     def_id: DefId,
+    have_turbofish: bool,
 }
 
 /// A visitor which searches for the "best" spot to use in the inference error.
@@ -916,6 +921,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                             substs,
                             generics_def_id: def_id,
                             def_id,
+                            have_turbofish: false,
                         }
                     };
                     return Box::new(insertable.into_iter());
@@ -933,6 +939,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
         substs: SubstsRef<'tcx>,
     ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a {
         let tcx = self.infcx.tcx;
+        let have_turbofish = path.segments.iter().any(|segment| {
+            segment.args.map_or(false, |args| args.args.iter().any(|arg| arg.is_ty_or_const()))
+        });
         // The last segment of a path often has `Res::Err` and the
         // correct `Res` is the one of the whole path.
         //
@@ -942,7 +951,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
             let generics_def_id = tcx.res_generics_def_id(path.res)?;
             let generics = tcx.generics_of(generics_def_id);
             if generics.has_impl_trait() {
-                None?
+                None?;
             }
             let insert_span =
                 path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi());
@@ -951,6 +960,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                 substs,
                 generics_def_id,
                 def_id: path.res.def_id(),
+                have_turbofish,
             }
         };
 
@@ -970,6 +980,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     substs,
                     generics_def_id,
                     def_id: res.def_id(),
+                    have_turbofish,
                 })
             })
             .chain(last_segment_using_path_data)
@@ -998,7 +1009,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     }
                     let span = tcx.hir().span(segment.hir_id);
                     let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
-                    InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id }
+                    InsertableGenericArgs {
+                        insert_span,
+                        substs,
+                        generics_def_id: def_id,
+                        def_id,
+                        have_turbofish: false,
+                    }
                 };
 
                 let parent_def_id = generics.parent.unwrap();
@@ -1021,7 +1038,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                                     }
                                     // There cannot be inference variables in the self type,
                                     // so there's nothing for us to do here.
-                                    Res::SelfTy { .. } => {}
+                                    Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {}
                                     _ => warn!(
                                         "unexpected path: def={:?} substs={:?} path={:?}",
                                         def, substs, path,
@@ -1121,7 +1138,13 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
 
         for args in self.expr_inferred_subst_iter(expr) {
             debug!(?args);
-            let InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } = args;
+            let InsertableGenericArgs {
+                insert_span,
+                substs,
+                generics_def_id,
+                def_id,
+                have_turbofish,
+            } = args;
             let generics = tcx.generics_of(generics_def_id);
             if let Some(argument_index) = generics
                 .own_substs(substs)
@@ -1144,6 +1167,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
                         generics_def_id,
                         def_id,
                         generic_args,
+                        have_turbofish,
                     },
                 });
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index a6a39d062d5..778c4fc01c8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -156,7 +156,8 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
                 [segment]
                     if matches!(
                         segment.res,
-                        Res::SelfTy { trait_: _, alias_to: _ }
+                        Res::SelfTyParam { .. }
+                            | Res::SelfTyAlias { .. }
                             | Res::Def(hir::def::DefKind::TyParam, _)
                     ) =>
                 {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index b9fd79e0d2f..70edcd10f5f 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -712,9 +712,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     ) -> bool {
         // Reject any attempt to unify two unevaluated constants that contain inference
         // variables, since inference variables in queries lead to ICEs.
-        if a.substs.has_infer_types_or_consts()
-            || b.substs.has_infer_types_or_consts()
-            || param_env.has_infer_types_or_consts()
+        if a.substs.has_non_region_infer()
+            || b.substs.has_non_region_infer()
+            || param_env.has_non_region_infer()
         {
             debug!("a or b or param_env contain infer vars in its substs -> cannot unify");
             return false;
@@ -1734,7 +1734,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         // Postpone the evaluation of constants whose substs depend on inference
         // variables
-        if substs.has_infer_types_or_consts() {
+        if substs.has_non_region_infer() {
             let ac = AbstractConst::new(self.tcx, unevaluated);
             match ac {
                 Ok(None) => {
@@ -2072,21 +2072,17 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
 ) -> SubstsRef<'tcx> {
     tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
         match arg.unpack() {
-            GenericArgKind::Type(_)
-                if arg.has_param_types_or_consts() || arg.has_infer_types_or_consts() =>
-            {
+            GenericArgKind::Type(_) if arg.has_non_region_param() || arg.has_non_region_infer() => {
                 tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
                     universe: ty::UniverseIndex::ROOT,
                     name: ty::BoundVar::from_usize(idx),
                 }))
                 .into()
             }
-            GenericArgKind::Const(ct)
-                if ct.has_infer_types_or_consts() || ct.has_param_types_or_consts() =>
-            {
+            GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => {
                 let ty = ct.ty();
                 // If the type references param or infer, replace that too...
-                if ty.has_param_types_or_consts() || ty.has_infer_types_or_consts() {
+                if ty.has_non_region_param() || ty.has_non_region_infer() {
                     bug!("const `{ct}`'s type should not reference params or types");
                 }
                 tcx.mk_const(ty::ConstS {
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index bb6f6ae60e2..91e73451a0f 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -357,7 +357,7 @@ where
             // In NLL, we don't have type inference variables
             // floating around, so we can do this rather imprecise
             // variant of the occurs-check.
-            assert!(!generalized_ty.has_infer_types_or_consts());
+            assert!(!generalized_ty.has_non_region_infer());
         }
 
         self.infcx.inner.borrow_mut().type_variables().instantiate(vid, generalized_ty);
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 3d99f0958f7..bb188496caa 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -32,7 +32,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        if !t.has_infer_types_or_consts() {
+        if !t.has_non_region_infer() {
             t // micro-optimize -- if there is nothing in this type that this fold affects...
         } else {
             let t = self.infcx.shallow_resolve(t);
@@ -41,7 +41,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
     }
 
     fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> {
-        if !ct.has_infer_types_or_consts() {
+        if !ct.has_non_region_infer() {
             ct // micro-optimize -- if there is nothing in this const that this fold affects...
         } else {
             let ct = self.infcx.shallow_resolve(ct);
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 6c725a01b53..91d180e1eb7 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -246,6 +246,10 @@ impl<'tcx> Queries<'tcx> {
                 // Don't do code generation if there were any errors
                 self.session().compile_status()?;
 
+                // If we have any delayed bugs, for example because we created TyKind::Error earlier,
+                // it's likely that codegen will only cause more ICEs, obscuring the original problem
+                self.session().diagnostic().flush_delayed();
+
                 // Hook for UI tests.
                 Self::check_for_rustc_errors_attr(tcx);
 
diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs
index b97f8acb37f..bd6b637f76f 100644
--- a/compiler/rustc_lint/src/array_into_iter.rs
+++ b/compiler/rustc_lint/src/array_into_iter.rs
@@ -118,37 +118,41 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
                 // to an array or to a slice.
                 _ => bug!("array type coerced to something other than array or slice"),
             };
-            cx.struct_span_lint(ARRAY_INTO_ITER, call.ident.span, |lint| {
-                let mut diag = lint.build(fluent::lint::array_into_iter);
-                diag.set_arg("target", target);
-                diag.span_suggestion(
-                    call.ident.span,
-                    fluent::lint::use_iter_suggestion,
-                    "iter",
-                    Applicability::MachineApplicable,
-                );
-                if self.for_expr_span == expr.span {
+            cx.struct_span_lint(
+                ARRAY_INTO_ITER,
+                call.ident.span,
+                fluent::lint::array_into_iter,
+                |diag| {
+                    diag.set_arg("target", target);
                     diag.span_suggestion(
-                        receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
-                        fluent::lint::remove_into_iter_suggestion,
-                        "",
-                        Applicability::MaybeIncorrect,
+                        call.ident.span,
+                        fluent::lint::use_iter_suggestion,
+                        "iter",
+                        Applicability::MachineApplicable,
                     );
-                } else if receiver_ty.is_array() {
-                    diag.multipart_suggestion(
-                        fluent::lint::use_explicit_into_iter_suggestion,
-                        vec![
-                            (expr.span.shrink_to_lo(), "IntoIterator::into_iter(".into()),
-                            (
-                                receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
-                                ")".into(),
-                            ),
-                        ],
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                diag.emit();
-            })
+                    if self.for_expr_span == expr.span {
+                        diag.span_suggestion(
+                            receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
+                            fluent::lint::remove_into_iter_suggestion,
+                            "",
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else if receiver_ty.is_array() {
+                        diag.multipart_suggestion(
+                            fluent::lint::use_explicit_into_iter_suggestion,
+                            vec![
+                                (expr.span.shrink_to_lo(), "IntoIterator::into_iter(".into()),
+                                (
+                                    receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
+                                    ")".into(),
+                                ),
+                            ],
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    diag
+                },
+            )
         }
     }
 }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 146c4971348..f28cfbd8b4c 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -33,8 +33,8 @@ use rustc_ast_pretty::pprust::{self, expr_to_string};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    fluent, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
-    LintDiagnosticBuilder, MultiSpan,
+    fluent, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
+    DiagnosticStyledString, MultiSpan,
 };
 use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
 use rustc_hir as hir;
@@ -97,30 +97,31 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
 
 impl EarlyLintPass for WhileTrue {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
-        if let ast::ExprKind::While(cond, _, label) = &e.kind {
-            if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind {
-                if let ast::LitKind::Bool(true) = lit.kind {
-                    if !lit.span.from_expansion() {
-                        let condition_span = e.span.with_hi(cond.span.hi());
-                        cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
-                            lint.build(fluent::lint::builtin_while_true)
-                                .span_suggestion_short(
-                                    condition_span,
-                                    fluent::lint::suggestion,
-                                    format!(
-                                        "{}loop",
-                                        label.map_or_else(String::new, |label| format!(
-                                            "{}: ",
-                                            label.ident,
-                                        ))
-                                    ),
-                                    Applicability::MachineApplicable,
-                                )
-                                .emit();
-                        })
-                    }
-                }
-            }
+        if let ast::ExprKind::While(cond, _, label) = &e.kind
+            && let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind
+            && let ast::LitKind::Bool(true) = lit.kind
+            && !lit.span.from_expansion()
+        {
+            let condition_span = e.span.with_hi(cond.span.hi());
+            cx.struct_span_lint(
+                            WHILE_TRUE,
+                            condition_span,
+                fluent::lint::builtin_while_true,
+                            |lint| {
+                    lint.span_suggestion_short(
+                        condition_span,
+                        fluent::lint::suggestion,
+                        format!(
+                            "{}loop",
+                            label.map_or_else(String::new, |label| format!(
+                                "{}: ",
+                                label.ident,
+                            ))
+                        ),
+                        Applicability::MachineApplicable,
+                    )
+                },
+            )
         }
     }
 }
@@ -156,9 +157,12 @@ impl BoxPointers {
         for leaf in ty.walk() {
             if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
                 if leaf_ty.is_box() {
-                    cx.struct_span_lint(BOX_POINTERS, span, |lint| {
-                        lint.build(fluent::lint::builtin_box_pointers).set_arg("ty", ty).emit();
-                    });
+                    cx.struct_span_lint(
+                        BOX_POINTERS,
+                        span,
+                        fluent::lint::builtin_box_pointers,
+                        |lint| lint.set_arg("ty", ty),
+                    );
                 }
             }
         }
@@ -257,19 +261,21 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
                     if cx.tcx.find_field_index(ident, &variant)
                         == Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results()))
                     {
-                        cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, |lint| {
-                            let suggested_ident =
-                                format!("{}{}", binding_annot.prefix_str(), ident);
-                            lint.build(fluent::lint::builtin_non_shorthand_field_patterns)
-                                .set_arg("ident", ident.clone())
-                                .span_suggestion(
+                        cx.struct_span_lint(
+                            NON_SHORTHAND_FIELD_PATTERNS,
+                            fieldpat.span,
+                            fluent::lint::builtin_non_shorthand_field_patterns,
+                            |lint| {
+                                let suggested_ident =
+                                    format!("{}{}", binding_annot.prefix_str(), ident);
+                                lint.set_arg("ident", ident.clone()).span_suggestion(
                                     fieldpat.span,
                                     fluent::lint::suggestion,
                                     suggested_ident,
                                     Applicability::MachineApplicable,
                                 )
-                                .emit();
-                        });
+                            },
+                        );
                     }
                 }
             }
@@ -309,14 +315,17 @@ impl UnsafeCode {
         &self,
         cx: &EarlyContext<'_>,
         span: Span,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
         // This comes from a macro that has `#[allow_internal_unsafe]`.
         if span.allows_unsafe() {
             return;
         }
 
-        cx.struct_span_lint(UNSAFE_CODE, span, decorate);
+        cx.struct_span_lint(UNSAFE_CODE, span, msg, decorate);
     }
 
     fn report_overridden_symbol_name(
@@ -325,8 +334,8 @@ impl UnsafeCode {
         span: Span,
         msg: DiagnosticMessage,
     ) {
-        self.report_unsafe(cx, span, |lint| {
-            lint.build(msg).note(fluent::lint::builtin_overridden_symbol_name).emit();
+        self.report_unsafe(cx, span, msg, |lint| {
+            lint.note(fluent::lint::builtin_overridden_symbol_name)
         })
     }
 
@@ -336,8 +345,8 @@ impl UnsafeCode {
         span: Span,
         msg: DiagnosticMessage,
     ) {
-        self.report_unsafe(cx, span, |lint| {
-            lint.build(msg).note(fluent::lint::builtin_overridden_symbol_section).emit();
+        self.report_unsafe(cx, span, msg, |lint| {
+            lint.note(fluent::lint::builtin_overridden_symbol_section)
         })
     }
 }
@@ -345,9 +354,12 @@ impl UnsafeCode {
 impl EarlyLintPass for UnsafeCode {
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
         if attr.has_name(sym::allow_internal_unsafe) {
-            self.report_unsafe(cx, attr.span, |lint| {
-                lint.build(fluent::lint::builtin_allow_internal_unsafe).emit();
-            });
+            self.report_unsafe(
+                cx,
+                attr.span,
+                fluent::lint::builtin_allow_internal_unsafe,
+                |lint| lint,
+            );
         }
     }
 
@@ -355,24 +367,20 @@ impl EarlyLintPass for UnsafeCode {
         if let ast::ExprKind::Block(ref blk, _) = e.kind {
             // Don't warn about generated blocks; that'll just pollute the output.
             if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
-                self.report_unsafe(cx, blk.span, |lint| {
-                    lint.build(fluent::lint::builtin_unsafe_block).emit();
-                });
+                self.report_unsafe(cx, blk.span, fluent::lint::builtin_unsafe_block, |lint| lint);
             }
         }
     }
 
     fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
         match it.kind {
-            ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self
-                .report_unsafe(cx, it.span, |lint| {
-                    lint.build(fluent::lint::builtin_unsafe_trait).emit();
-                }),
+            ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => {
+                self.report_unsafe(cx, it.span, fluent::lint::builtin_unsafe_trait, |lint| lint)
+            }
 
-            ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self
-                .report_unsafe(cx, it.span, |lint| {
-                    lint.build(fluent::lint::builtin_unsafe_impl).emit();
-                }),
+            ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => {
+                self.report_unsafe(cx, it.span, fluent::lint::builtin_unsafe_impl, |lint| lint)
+            }
 
             ast::ItemKind::Fn(..) => {
                 if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
@@ -465,9 +473,7 @@ impl EarlyLintPass for UnsafeCode {
                 FnCtxt::Assoc(_) if body.is_none() => fluent::lint::builtin_decl_unsafe_method,
                 FnCtxt::Assoc(_) => fluent::lint::builtin_impl_unsafe_method,
             };
-            self.report_unsafe(cx, span, |lint| {
-                lint.build(msg).emit();
-            });
+            self.report_unsafe(cx, span, msg, |lint| lint);
         }
     }
 }
@@ -568,12 +574,12 @@ impl MissingDoc {
         let attrs = cx.tcx.hir().attrs(cx.tcx.hir().local_def_id_to_hir_id(def_id));
         let has_doc = attrs.iter().any(has_doc);
         if !has_doc {
-            cx.struct_span_lint(MISSING_DOCS, cx.tcx.def_span(def_id), |lint| {
-                lint.build(fluent::lint::builtin_missing_doc)
-                    .set_arg("article", article)
-                    .set_arg("desc", desc)
-                    .emit();
-            });
+            cx.struct_span_lint(
+                MISSING_DOCS,
+                cx.tcx.def_span(def_id),
+                fluent::lint::builtin_missing_doc,
+                |lint| lint.set_arg("article", article).set_arg("desc", desc),
+            );
         }
     }
 }
@@ -760,9 +766,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
         )
         .is_ok()
         {
-            cx.struct_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, |lint| {
-                lint.build(fluent::lint::builtin_missing_copy_impl).emit();
-            })
+            cx.struct_span_lint(
+                MISSING_COPY_IMPLEMENTATIONS,
+                item.span,
+                fluent::lint::builtin_missing_copy_impl,
+                |lint| lint,
+            )
         }
     }
 }
@@ -836,11 +845,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
         }
 
         if !self.impling_types.as_ref().unwrap().contains(&item.def_id.def_id) {
-            cx.struct_span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, |lint| {
-                lint.build(fluent::lint::builtin_missing_debug_impl)
-                    .set_arg("debug", cx.tcx.def_path_str(debug))
-                    .emit();
-            });
+            cx.struct_span_lint(
+                MISSING_DEBUG_IMPLEMENTATIONS,
+                item.span,
+                fluent::lint::builtin_missing_debug_impl,
+                |lint| lint.set_arg("debug", cx.tcx.def_path_str(debug)),
+            );
         }
     }
 }
@@ -908,24 +918,26 @@ impl EarlyLintPass for AnonymousParameters {
             for arg in sig.decl.inputs.iter() {
                 if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
                     if ident.name == kw::Empty {
-                        cx.struct_span_lint(ANONYMOUS_PARAMETERS, arg.pat.span, |lint| {
-                            let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span);
-
-                            let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
-                                (snip.as_str(), Applicability::MachineApplicable)
-                            } else {
-                                ("<type>", Applicability::HasPlaceholders)
-                            };
+                        let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span);
 
-                            lint.build(fluent::lint::builtin_anonymous_params)
-                                .span_suggestion(
+                        let (ty_snip, appl) = if let Ok(ref snip) = ty_snip {
+                            (snip.as_str(), Applicability::MachineApplicable)
+                        } else {
+                            ("<type>", Applicability::HasPlaceholders)
+                        };
+                        cx.struct_span_lint(
+                            ANONYMOUS_PARAMETERS,
+                            arg.pat.span,
+                            fluent::lint::builtin_anonymous_params,
+                            |lint| {
+                                lint.span_suggestion(
                                     arg.pat.span,
                                     fluent::lint::suggestion,
                                     format!("_: {}", ty_snip),
                                     appl,
                                 )
-                                .emit();
-                        })
+                            },
+                        )
                     }
                 }
             }
@@ -960,38 +972,44 @@ impl EarlyLintPass for DeprecatedAttr {
                     _,
                 ) = gate
                 {
-                    cx.struct_span_lint(DEPRECATED, attr.span, |lint| {
-                        // FIXME(davidtwco) translatable deprecated attr
-                        lint.build(fluent::lint::builtin_deprecated_attr_link)
-                            .set_arg("name", name)
-                            .set_arg("reason", reason)
-                            .set_arg("link", link)
-                            .span_suggestion_short(
-                                attr.span,
-                                suggestion.map(|s| s.into()).unwrap_or(
-                                    fluent::lint::builtin_deprecated_attr_default_suggestion,
-                                ),
-                                "",
-                                Applicability::MachineApplicable,
-                            )
-                            .emit();
-                    });
+                    // FIXME(davidtwco) translatable deprecated attr
+                    cx.struct_span_lint(
+                        DEPRECATED,
+                        attr.span,
+                        fluent::lint::builtin_deprecated_attr_link,
+                        |lint| {
+                            lint.set_arg("name", name)
+                                .set_arg("reason", reason)
+                                .set_arg("link", link)
+                                .span_suggestion_short(
+                                    attr.span,
+                                    suggestion.map(|s| s.into()).unwrap_or(
+                                        fluent::lint::builtin_deprecated_attr_default_suggestion,
+                                    ),
+                                    "",
+                                    Applicability::MachineApplicable,
+                                )
+                        },
+                    );
                 }
                 return;
             }
         }
         if attr.has_name(sym::no_start) || attr.has_name(sym::crate_id) {
-            cx.struct_span_lint(DEPRECATED, attr.span, |lint| {
-                lint.build(fluent::lint::builtin_deprecated_attr_used)
-                    .set_arg("name", pprust::path_to_string(&attr.get_normal_item().path))
-                    .span_suggestion_short(
-                        attr.span,
-                        fluent::lint::builtin_deprecated_attr_default_suggestion,
-                        "",
-                        Applicability::MachineApplicable,
-                    )
-                    .emit();
-            });
+            cx.struct_span_lint(
+                DEPRECATED,
+                attr.span,
+                fluent::lint::builtin_deprecated_attr_used,
+                |lint| {
+                    lint.set_arg("name", pprust::path_to_string(&attr.get_normal_item().path))
+                        .span_suggestion_short(
+                            attr.span,
+                            fluent::lint::builtin_deprecated_attr_default_suggestion,
+                            "",
+                            Applicability::MachineApplicable,
+                        )
+                },
+            );
         }
     }
 }
@@ -1018,20 +1036,21 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &
         let span = sugared_span.take().unwrap_or(attr.span);
 
         if is_doc_comment || attr.has_name(sym::doc) {
-            cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| {
-                let mut err = lint.build(fluent::lint::builtin_unused_doc_comment);
-                err.set_arg("kind", node_kind);
-                err.span_label(node_span, fluent::lint::label);
-                match attr.kind {
-                    AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => {
-                        err.help(fluent::lint::plain_help);
-                    }
-                    AttrKind::DocComment(CommentKind::Block, _) => {
-                        err.help(fluent::lint::block_help);
-                    }
-                }
-                err.emit();
-            });
+            cx.struct_span_lint(
+                UNUSED_DOC_COMMENTS,
+                span,
+                fluent::lint::builtin_unused_doc_comment,
+                |lint| {
+                    lint.set_arg("kind", node_kind).span_label(node_span, fluent::lint::label).help(
+                        match attr.kind {
+                            AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => {
+                                fluent::lint::plain_help
+                            }
+                            AttrKind::DocComment(CommentKind::Block, _) => fluent::lint::block_help,
+                        },
+                    )
+                },
+            );
         }
     }
 }
@@ -1145,9 +1164,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
                 match param.kind {
                     GenericParamKind::Lifetime { .. } => {}
                     GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
-                        cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS, span, |lint| {
-                            lint.build(fluent::lint::builtin_no_mangle_generic)
-                                .span_suggestion_short(
+                        cx.struct_span_lint(
+                            NO_MANGLE_GENERIC_ITEMS,
+                            span,
+                            fluent::lint::builtin_no_mangle_generic,
+                            |lint| {
+                                lint.span_suggestion_short(
                                     no_mangle_attr.span,
                                     fluent::lint::suggestion,
                                     "",
@@ -1155,8 +1177,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
                                     // fix may be to monomorphize source by hand
                                     Applicability::MaybeIncorrect,
                                 )
-                                .emit();
-                        });
+                            },
+                        );
                         break;
                     }
                 }
@@ -1172,27 +1194,29 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
                 if cx.sess().contains_name(attrs, sym::no_mangle) {
                     // Const items do not refer to a particular location in memory, and therefore
                     // don't have anything to attach a symbol to
-                    cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, |lint| {
-                        let mut err = lint.build(fluent::lint::builtin_const_no_mangle);
-
-                        // account for "pub const" (#45562)
-                        let start = cx
-                            .tcx
-                            .sess
-                            .source_map()
-                            .span_to_snippet(it.span)
-                            .map(|snippet| snippet.find("const").unwrap_or(0))
-                            .unwrap_or(0) as u32;
-                        // `const` is 5 chars
-                        let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
-                        err.span_suggestion(
-                            const_span,
-                            fluent::lint::suggestion,
-                            "pub static",
-                            Applicability::MachineApplicable,
-                        );
-                        err.emit();
-                    });
+                    cx.struct_span_lint(
+                        NO_MANGLE_CONST_ITEMS,
+                        it.span,
+                        fluent::lint::builtin_const_no_mangle,
+                        |lint| {
+                            // account for "pub const" (#45562)
+                            let start = cx
+                                .tcx
+                                .sess
+                                .source_map()
+                                .span_to_snippet(it.span)
+                                .map(|snippet| snippet.find("const").unwrap_or(0))
+                                .unwrap_or(0) as u32;
+                            // `const` is 5 chars
+                            let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
+                            lint.span_suggestion(
+                                const_span,
+                                fluent::lint::suggestion,
+                                "pub static",
+                                Applicability::MachineApplicable,
+                            )
+                        },
+                    );
                 }
             }
             hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => {
@@ -1252,9 +1276,12 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
             get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind()))
         {
             if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not {
-                cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| {
-                    lint.build(fluent::lint::builtin_mutable_transmutes).emit();
-                });
+                cx.struct_span_lint(
+                    MUTABLE_TRANSMUTES,
+                    expr.span,
+                    fluent::lint::builtin_mutable_transmutes,
+                    |lint| lint,
+                );
             }
         }
 
@@ -1302,9 +1329,12 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
         if attr.has_name(sym::feature) {
             if let Some(items) = attr.meta_item_list() {
                 for item in items {
-                    cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| {
-                        lint.build(fluent::lint::builtin_unstable_features).emit();
-                    });
+                    cx.struct_span_lint(
+                        UNSTABLE_FEATURES,
+                        item.span(),
+                        fluent::lint::builtin_unstable_features,
+                        |lint| lint,
+                    );
                 }
             }
         }
@@ -1363,21 +1393,25 @@ impl UnreachablePub {
                 applicability = Applicability::MaybeIncorrect;
             }
             let def_span = cx.tcx.def_span(def_id);
-            cx.struct_span_lint(UNREACHABLE_PUB, def_span, |lint| {
-                let mut err = lint.build(fluent::lint::builtin_unreachable_pub);
-                err.set_arg("what", what);
-
-                err.span_suggestion(
-                    vis_span,
-                    fluent::lint::suggestion,
-                    "pub(crate)",
-                    applicability,
-                );
-                if exportable {
-                    err.help(fluent::lint::help);
-                }
-                err.emit();
-            });
+            cx.struct_span_lint(
+                UNREACHABLE_PUB,
+                def_span,
+                fluent::lint::builtin_unreachable_pub,
+                |lint| {
+                    lint.set_arg("what", what);
+
+                    lint.span_suggestion(
+                        vis_span,
+                        fluent::lint::suggestion,
+                        "pub(crate)",
+                        applicability,
+                    );
+                    if exportable {
+                        lint.help(fluent::lint::help);
+                    }
+                    lint
+                },
+            );
         }
     }
 }
@@ -1507,36 +1541,34 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
 
         let mut suggested_changing_assoc_types = false;
         if !where_spans.is_empty() {
-            cx.lint(TYPE_ALIAS_BOUNDS, |lint| {
-                let mut err = lint.build(fluent::lint::builtin_type_alias_where_clause);
-                err.set_span(where_spans);
-                err.span_suggestion(
+            cx.lint(TYPE_ALIAS_BOUNDS, fluent::lint::builtin_type_alias_where_clause, |lint| {
+                lint.set_span(where_spans);
+                lint.span_suggestion(
                     type_alias_generics.where_clause_span,
                     fluent::lint::suggestion,
                     "",
                     Applicability::MachineApplicable,
                 );
                 if !suggested_changing_assoc_types {
-                    TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err);
+                    TypeAliasBounds::suggest_changing_assoc_types(ty, lint);
                     suggested_changing_assoc_types = true;
                 }
-                err.emit();
+                lint
             });
         }
 
         if !inline_spans.is_empty() {
-            cx.lint(TYPE_ALIAS_BOUNDS, |lint| {
-                let mut err = lint.build(fluent::lint::builtin_type_alias_generic_bounds);
-                err.set_span(inline_spans);
-                err.multipart_suggestion(
+            cx.lint(TYPE_ALIAS_BOUNDS, fluent::lint::builtin_type_alias_generic_bounds, |lint| {
+                lint.set_span(inline_spans);
+                lint.multipart_suggestion(
                     fluent::lint::suggestion,
                     inline_sugg,
                     Applicability::MachineApplicable,
                 );
                 if !suggested_changing_assoc_types {
-                    TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err);
+                    TypeAliasBounds::suggest_changing_assoc_types(ty, lint);
                 }
-                err.emit();
+                lint
             });
         }
     }
@@ -1635,12 +1667,15 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
                     TypeWellFormedFromEnv(..) => continue,
                 };
                 if predicate.is_global() {
-                    cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| {
-                        lint.build(fluent::lint::builtin_trivial_bounds)
-                            .set_arg("predicate_kind_name", predicate_kind_name)
-                            .set_arg("predicate", predicate)
-                            .emit();
-                    });
+                    cx.struct_span_lint(
+                        TRIVIAL_BOUNDS,
+                        span,
+                        fluent::lint::builtin_trivial_bounds,
+                        |lint| {
+                            lint.set_arg("predicate_kind_name", predicate_kind_name)
+                                .set_arg("predicate", predicate)
+                        },
+                    );
                 }
             }
         }
@@ -1756,15 +1791,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
                         replace,
                     });
                 } else {
-                    cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| {
-                        lint.build(msg)
-                            .span_suggestion(
-                                pat.span,
-                                suggestion,
-                                replace,
-                                Applicability::MachineApplicable,
-                            )
-                            .emit();
+                    cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, msg, |lint| {
+                        lint.span_suggestion(
+                            pat.span,
+                            suggestion,
+                            replace,
+                            Applicability::MachineApplicable,
+                        )
                     });
                 }
             } else {
@@ -1776,15 +1809,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
                         replace: replace.to_string(),
                     });
                 } else {
-                    cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| {
-                        lint.build(msg)
-                            .span_suggestion_short(
-                                join,
-                                suggestion,
-                                replace,
-                                Applicability::MachineApplicable,
-                            )
-                            .emit();
+                    cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, msg, |lint| {
+                        lint.span_suggestion_short(
+                            join,
+                            suggestion,
+                            replace,
+                            Applicability::MachineApplicable,
+                        )
                     });
                 }
             };
@@ -1865,9 +1896,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
 
         let attrs = cx.tcx.hir().attrs(it.hir_id());
         if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) {
-            cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| {
-                lint.build(fluent::lint::builtin_unnameable_test_items).emit();
-            });
+            cx.struct_span_lint(
+                UNNAMEABLE_TEST_ITEMS,
+                attr.span,
+                fluent::lint::builtin_unnameable_test_items,
+                |lint| lint,
+            );
         }
     }
 
@@ -1983,18 +2017,19 @@ impl KeywordIdents {
             return;
         }
 
-        cx.struct_span_lint(KEYWORD_IDENTS, ident.span, |lint| {
-            lint.build(fluent::lint::builtin_keyword_idents)
-                .set_arg("kw", ident.clone())
-                .set_arg("next", next_edition)
-                .span_suggestion(
+        cx.struct_span_lint(
+            KEYWORD_IDENTS,
+            ident.span,
+            fluent::lint::builtin_keyword_idents,
+            |lint| {
+                lint.set_arg("kw", ident.clone()).set_arg("next", next_edition).span_suggestion(
                     ident.span,
                     fluent::lint::suggestion,
                     format!("r#{}", ident),
                     Applicability::MachineApplicable,
                 )
-                .emit();
-        });
+            },
+        );
     }
 }
 
@@ -2245,10 +2280,12 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
             }
 
             if !lint_spans.is_empty() {
-                cx.struct_span_lint(EXPLICIT_OUTLIVES_REQUIREMENTS, lint_spans.clone(), |lint| {
-                    lint.build(fluent::lint::builtin_explicit_outlives)
-                        .set_arg("count", bound_count)
-                        .multipart_suggestion(
+                cx.struct_span_lint(
+                    EXPLICIT_OUTLIVES_REQUIREMENTS,
+                    lint_spans.clone(),
+                    fluent::lint::builtin_explicit_outlives,
+                    |lint| {
+                        lint.set_arg("count", bound_count).multipart_suggestion(
                             fluent::lint::suggestion,
                             lint_spans
                                 .into_iter()
@@ -2256,8 +2293,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                 .collect::<Vec<_>>(),
                             Applicability::MachineApplicable,
                         )
-                        .emit();
-                });
+                    },
+                );
             }
         }
     }
@@ -2304,18 +2341,24 @@ impl EarlyLintPass for IncompleteFeatures {
             .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
             .filter(|(&name, _)| features.incomplete(name))
             .for_each(|(&name, &span)| {
-                cx.struct_span_lint(INCOMPLETE_FEATURES, span, |lint| {
-                    let mut builder = lint.build(fluent::lint::builtin_incomplete_features);
-                    builder.set_arg("name", name);
-                    if let Some(n) = rustc_feature::find_feature_issue(name, GateIssue::Language) {
-                        builder.set_arg("n", n);
-                        builder.note(fluent::lint::note);
-                    }
-                    if HAS_MIN_FEATURES.contains(&name) {
-                        builder.help(fluent::lint::help);
-                    }
-                    builder.emit();
-                })
+                cx.struct_span_lint(
+                    INCOMPLETE_FEATURES,
+                    span,
+                    fluent::lint::builtin_incomplete_features,
+                    |lint| {
+                        lint.set_arg("name", name);
+                        if let Some(n) =
+                            rustc_feature::find_feature_issue(name, GateIssue::Language)
+                        {
+                            lint.set_arg("n", n);
+                            lint.note(fluent::lint::note);
+                        }
+                        if HAS_MIN_FEATURES.contains(&name) {
+                            lint.help(fluent::lint::help);
+                        }
+                        lint
+                    },
+                )
             });
     }
 }
@@ -2630,28 +2673,37 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                 with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init))
             {
                 // FIXME(davidtwco): make translatable
-                cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| {
-                    let mut err = lint.build(&format!(
-                        "the type `{}` does not permit {}",
-                        conjured_ty,
-                        match init {
-                            InitKind::Zeroed => "zero-initialization",
-                            InitKind::Uninit => "being left uninitialized",
-                        },
-                    ));
-                    err.span_label(expr.span, "this code causes undefined behavior when executed");
-                    err.span_label(
-                        expr.span,
-                        "help: use `MaybeUninit<T>` instead, \
+                cx.struct_span_lint(
+                    INVALID_VALUE,
+                    expr.span,
+                    DelayDm(|| {
+                        format!(
+                            "the type `{}` does not permit {}",
+                            conjured_ty,
+                            match init {
+                                InitKind::Zeroed => "zero-initialization",
+                                InitKind::Uninit => "being left uninitialized",
+                            },
+                        )
+                    }),
+                    |lint| {
+                        lint.span_label(
+                            expr.span,
+                            "this code causes undefined behavior when executed",
+                        );
+                        lint.span_label(
+                            expr.span,
+                            "help: use `MaybeUninit<T>` instead, \
                             and only call `assume_init` after initialization is done",
-                    );
-                    if let Some(span) = span {
-                        err.span_note(span, &msg);
-                    } else {
-                        err.note(&msg);
-                    }
-                    err.emit();
-                });
+                        );
+                        if let Some(span) = span {
+                            lint.span_note(span, &msg);
+                        } else {
+                            lint.note(&msg);
+                        }
+                        lint
+                    },
+                );
             }
         }
     }
@@ -2997,31 +3049,35 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations {
                             SymbolName::Link(_, annot_span) => fi.span.to(annot_span),
                         };
                     // Finally, emit the diagnostic.
+
+                    let msg = if orig.get_name() == this_fi.ident.name {
+                        fluent::lint::builtin_clashing_extern_same_name
+                    } else {
+                        fluent::lint::builtin_clashing_extern_diff_name
+                    };
                     tcx.struct_span_lint_hir(
                         CLASHING_EXTERN_DECLARATIONS,
                         this_fi.hir_id(),
                         get_relevant_span(this_fi),
+                        msg,
                         |lint| {
                             let mut expected_str = DiagnosticStyledString::new();
                             expected_str.push(existing_decl_ty.fn_sig(tcx).to_string(), false);
                             let mut found_str = DiagnosticStyledString::new();
                             found_str.push(this_decl_ty.fn_sig(tcx).to_string(), true);
 
-                            lint.build(if orig.get_name() == this_fi.ident.name {
-                                fluent::lint::builtin_clashing_extern_same_name
-                            } else {
-                                fluent::lint::builtin_clashing_extern_diff_name
-                            })
-                            .set_arg("this_fi", this_fi.ident.name)
-                            .set_arg("orig", orig.get_name())
-                            .span_label(
-                                get_relevant_span(orig_fi),
-                                fluent::lint::previous_decl_label,
-                            )
-                            .span_label(get_relevant_span(this_fi), fluent::lint::mismatch_label)
-                            // FIXME(davidtwco): translatable expected/found
-                            .note_expected_found(&"", expected_str, &"", found_str)
-                            .emit();
+                            lint.set_arg("this_fi", this_fi.ident.name)
+                                .set_arg("orig", orig.get_name())
+                                .span_label(
+                                    get_relevant_span(orig_fi),
+                                    fluent::lint::previous_decl_label,
+                                )
+                                .span_label(
+                                    get_relevant_span(this_fi),
+                                    fluent::lint::mismatch_label,
+                                )
+                                // FIXME(davidtwco): translatable expected/found
+                                .note_expected_found(&"", expected_str, &"", found_str)
                         },
                     );
                 }
@@ -3102,11 +3158,12 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
 
         if let rustc_hir::ExprKind::Unary(rustc_hir::UnOp::Deref, expr_deref) = expr.kind {
             if is_null_ptr(cx, expr_deref) {
-                cx.struct_span_lint(DEREF_NULLPTR, expr.span, |lint| {
-                    let mut err = lint.build(fluent::lint::builtin_deref_nullptr);
-                    err.span_label(expr.span, fluent::lint::label);
-                    err.emit();
-                });
+                cx.struct_span_lint(
+                    DEREF_NULLPTR,
+                    expr.span,
+                    fluent::lint::builtin_deref_nullptr,
+                    |lint| lint.span_label(expr.span, fluent::lint::label),
+                );
             }
         }
     }
@@ -3216,9 +3273,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
                     cx.lookup_with_diagnostics(
                             NAMED_ASM_LABELS,
                             Some(target_spans),
-                            |diag| {
-                                diag.build(fluent::lint::builtin_asm_labels).emit();
-                            },
+                            fluent::lint::builtin_asm_labels,
+                            |lint| lint,
                             BuiltinLintDiagnostics::NamedAsmLabel(
                                 "only local labels of the form `<number>:` should be used in inline asm"
                                     .to_string(),
@@ -3290,16 +3346,14 @@ impl EarlyLintPass for SpecialModuleName {
                 }
 
                 match item.ident.name.as_str() {
-                    "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
-                        lint.build("found module declaration for lib.rs")
+                    "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, "found module declaration for lib.rs", |lint| {
+                        lint
                             .note("lib.rs is the root of this crate's library target")
                             .help("to refer to it from other targets, use the library's name as the path")
-                            .emit()
                     }),
-                    "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| {
-                        lint.build("found module declaration for main.rs")
+                    "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, "found module declaration for main.rs", |lint| {
+                        lint
                             .note("a binary crate cannot be used as library")
-                            .emit()
                     }),
                     _ => continue
                 }
@@ -3319,24 +3373,27 @@ impl EarlyLintPass for UnexpectedCfgs {
         for &(name, value) in cfg {
             if let Some(names_valid) = &check_cfg.names_valid {
                 if !names_valid.contains(&name) {
-                    cx.lookup(UNEXPECTED_CFGS, None::<MultiSpan>, |diag| {
-                        diag.build(fluent::lint::builtin_unexpected_cli_config_name)
-                            .help(fluent::lint::help)
-                            .set_arg("name", name)
-                            .emit();
-                    });
+                    cx.lookup(
+                        UNEXPECTED_CFGS,
+                        None::<MultiSpan>,
+                        fluent::lint::builtin_unexpected_cli_config_name,
+                        |diag| diag.help(fluent::lint::help).set_arg("name", name),
+                    );
                 }
             }
             if let Some(value) = value {
                 if let Some(values) = &check_cfg.values_valid.get(&name) {
                     if !values.contains(&value) {
-                        cx.lookup(UNEXPECTED_CFGS, None::<MultiSpan>, |diag| {
-                            diag.build(fluent::lint::builtin_unexpected_cli_config_value)
-                                .help(fluent::lint::help)
-                                .set_arg("name", name)
-                                .set_arg("value", value)
-                                .emit();
-                        });
+                        cx.lookup(
+                            UNEXPECTED_CFGS,
+                            None::<MultiSpan>,
+                            fluent::lint::builtin_unexpected_cli_config_value,
+                            |diag| {
+                                diag.help(fluent::lint::help)
+                                    .set_arg("name", name)
+                                    .set_arg("value", value)
+                            },
+                        );
                     }
                 }
             }
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index cbab56f2066..74e35afc87d 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -25,10 +25,8 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject};
 use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync;
-use rustc_errors::add_elided_lifetime_in_path_suggestion;
-use rustc_errors::{
-    Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle,
-};
+use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder, DiagnosticMessage};
+use rustc_errors::{Applicability, DecorateLint, MultiSpan, SuggestionStyle};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -560,7 +558,7 @@ pub struct LateContext<'tcx> {
 
 /// Context for lint checking of the AST, after expansion, before lowering to HIR.
 pub struct EarlyContext<'a> {
-    pub builder: LintLevelsBuilder<'a>,
+    pub builder: LintLevelsBuilder<'a, crate::levels::TopDown>,
     pub buffered: LintBuffer,
 }
 
@@ -580,13 +578,14 @@ pub trait LintContext: Sized {
         &self,
         lint: &'static Lint,
         span: Option<impl Into<MultiSpan>>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
         diagnostic: BuiltinLintDiagnostics,
     ) {
-        self.lookup(lint, span, |lint| {
-            // We first generate a blank diagnostic.
-            let mut db = lint.build("");
-
+        // We first generate a blank diagnostic.
+        self.lookup(lint, span, msg,|db| {
             // Now, set up surrounding context.
             let sess = self.sess();
             match diagnostic {
@@ -660,7 +659,7 @@ pub trait LintContext: Sized {
                 ) => {
                     add_elided_lifetime_in_path_suggestion(
                         sess.source_map(),
-                        &mut db,
+                        db,
                         n,
                         path_span,
                         incl_angl_brckt,
@@ -696,7 +695,7 @@ pub trait LintContext: Sized {
                     }
                 }
                 BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => {
-                    stability::deprecation_suggestion(&mut db, "macro", suggestion, span)
+                    stability::deprecation_suggestion(db, "macro", suggestion, span)
                 }
                 BuiltinLintDiagnostics::UnusedDocComment(span) => {
                     db.span_label(span, "rustdoc does not generate documentation for macro invocations");
@@ -867,7 +866,7 @@ pub trait LintContext: Sized {
                 }
             }
             // Rewrap `db`, and pass control to the user.
-            decorate(LintDiagnosticBuilder::new(db));
+            decorate(db)
         });
     }
 
@@ -877,7 +876,10 @@ pub trait LintContext: Sized {
         &self,
         lint: &'static Lint,
         span: Option<S>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     );
 
     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
@@ -888,31 +890,39 @@ pub trait LintContext: Sized {
         span: S,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.lookup(lint, Some(span), |diag| decorator.decorate_lint(diag));
+        self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag));
     }
 
     fn struct_span_lint<S: Into<MultiSpan>>(
         &self,
         lint: &'static Lint,
         span: S,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
-        self.lookup(lint, Some(span), decorate);
+        self.lookup(lint, Some(span), msg, decorate);
     }
 
     /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
     /// generated by `#[derive(LintDiagnostic)]`).
     fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) {
-        self.lookup(lint, None as Option<Span>, |diag| decorator.decorate_lint(diag));
+        self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| {
+            decorator.decorate_lint(diag)
+        });
     }
 
     /// Emit a lint at the appropriate level, with no associated span.
     fn lint(
         &self,
         lint: &'static Lint,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
-        self.lookup(lint, None as Option<Span>, decorate);
+        self.lookup(lint, None as Option<Span>, msg, decorate);
     }
 
     /// This returns the lint level for the given lint at the current location.
@@ -975,13 +985,16 @@ impl<'tcx> LintContext for LateContext<'tcx> {
         &self,
         lint: &'static Lint,
         span: Option<S>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
         let hir_id = self.last_node_with_lint_attrs;
 
         match span {
-            Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, decorate),
-            None => self.tcx.struct_lint_node(lint, hir_id, decorate),
+            Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, msg, decorate),
+            None => self.tcx.struct_lint_node(lint, hir_id, msg, decorate),
         }
     }
 
@@ -1006,9 +1019,12 @@ impl LintContext for EarlyContext<'_> {
         &self,
         lint: &'static Lint,
         span: Option<S>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
-        self.builder.struct_lint(lint, span.map(|s| s.into()), decorate)
+        self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate)
     }
 
     fn get_lint_level(&self, lint: &'static Lint) -> Level {
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 96ecd79a69c..f7759bec908 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -43,9 +43,8 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
             self.context.lookup_with_diagnostics(
                 lint_id.lint,
                 Some(span),
-                |lint| {
-                    lint.build(msg).emit();
-                },
+                msg,
+                |lint| lint,
                 diagnostic,
             );
         }
@@ -59,6 +58,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
         F: FnOnce(&mut Self),
     {
         let is_crate_node = id == ast::CRATE_NODE_ID;
+        debug!(?id);
         let push = self.context.builder.push(attrs, is_crate_node, None);
 
         self.check_id(id);
diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
index f41ee640499..e8d307814b9 100644
--- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
+++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
@@ -50,26 +50,24 @@ fn enforce_mem_discriminant(
 ) {
     let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0);
     if is_non_enum(ty_param) {
-        cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, expr_span, |builder| {
-            builder
-                .build(fluent::lint::enum_intrinsics_mem_discriminant)
-                .set_arg("ty_param", ty_param)
-                .span_note(args_span, fluent::lint::note)
-                .emit();
-        });
+        cx.struct_span_lint(
+            ENUM_INTRINSICS_NON_ENUMS,
+            expr_span,
+            fluent::lint::enum_intrinsics_mem_discriminant,
+            |lint| lint.set_arg("ty_param", ty_param).span_note(args_span, fluent::lint::note),
+        );
     }
 }
 
 fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, span: Span) {
     let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0);
     if is_non_enum(ty_param) {
-        cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, span, |builder| {
-            builder
-                .build(fluent::lint::enum_intrinsics_mem_variant)
-                .set_arg("ty_param", ty_param)
-                .note(fluent::lint::note)
-                .emit();
-        });
+        cx.struct_span_lint(
+            ENUM_INTRINSICS_NON_ENUMS,
+            span,
+            fluent::lint::enum_intrinsics_mem_variant,
+            |lint| lint.set_arg("ty_param", ty_param).note(fluent::lint::note),
+        );
     }
 }
 
diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs
index 699e8154318..4c3c39734dd 100644
--- a/compiler/rustc_lint/src/expect.rs
+++ b/compiler/rustc_lint/src/expect.rs
@@ -16,8 +16,10 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
         return;
     }
 
+    let lint_expectations = tcx.lint_expectations(());
     let fulfilled_expectations = tcx.sess.diagnostic().steal_fulfilled_expectation_ids();
-    let lint_expectations = &tcx.lint_levels(()).lint_expectations;
+
+    tracing::debug!(?lint_expectations, ?fulfilled_expectations);
 
     for (id, expectation) in lint_expectations {
         // This check will always be true, since `lint_expectations` only
@@ -43,17 +45,17 @@ fn emit_unfulfilled_expectation_lint(
         builtin::UNFULFILLED_LINT_EXPECTATIONS,
         hir_id,
         expectation.emission_span,
-        |diag| {
-            let mut diag = diag.build(fluent::lint::expectation);
+        fluent::lint::expectation,
+        |lint| {
             if let Some(rationale) = expectation.reason {
-                diag.note(rationale.as_str());
+                lint.note(rationale.as_str());
             }
 
             if expectation.is_unfulfilled_lint_expectations {
-                diag.note(fluent::lint::note);
+                lint.note(fluent::lint::note);
             }
 
-            diag.emit();
+            lint
         },
     );
 }
diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
index 8f22221324a..42557068bd3 100644
--- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
+++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs
@@ -60,52 +60,56 @@ impl HiddenUnicodeCodepoints {
             })
             .collect();
 
-        cx.struct_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, |lint| {
-            let mut err = lint.build(fluent::lint::hidden_unicode_codepoints);
-            err.set_arg("label", label);
-            err.set_arg("count", spans.len());
-            err.span_label(span, fluent::lint::label);
-            err.note(fluent::lint::note);
-            if point_at_inner_spans {
-                for (c, span) in &spans {
-                    err.span_label(*span, format!("{:?}", c));
+        cx.struct_span_lint(
+            TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
+            span,
+            fluent::lint::hidden_unicode_codepoints,
+            |lint| {
+                lint.set_arg("label", label);
+                lint.set_arg("count", spans.len());
+                lint.span_label(span, fluent::lint::label);
+                lint.note(fluent::lint::note);
+                if point_at_inner_spans {
+                    for (c, span) in &spans {
+                        lint.span_label(*span, format!("{:?}", c));
+                    }
                 }
-            }
-            if point_at_inner_spans && !spans.is_empty() {
-                err.multipart_suggestion_with_style(
-                    fluent::lint::suggestion_remove,
-                    spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
-                    Applicability::MachineApplicable,
-                    SuggestionStyle::HideCodeAlways,
-                );
-                err.multipart_suggestion(
-                    fluent::lint::suggestion_escape,
-                    spans
-                        .into_iter()
-                        .map(|(c, span)| {
-                            let c = format!("{:?}", c);
-                            (span, c[1..c.len() - 1].to_string())
-                        })
-                        .collect(),
-                    Applicability::MachineApplicable,
-                );
-            } else {
-                // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
-                // should do the same here to provide the same good suggestions as we do for
-                // literals above.
-                err.set_arg(
-                    "escaped",
-                    spans
-                        .into_iter()
-                        .map(|(c, _)| format!("{:?}", c))
-                        .collect::<Vec<String>>()
-                        .join(", "),
-                );
-                err.note(fluent::lint::suggestion_remove);
-                err.note(fluent::lint::no_suggestion_note_escape);
-            }
-            err.emit();
-        });
+                if point_at_inner_spans && !spans.is_empty() {
+                    lint.multipart_suggestion_with_style(
+                        fluent::lint::suggestion_remove,
+                        spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
+                        Applicability::MachineApplicable,
+                        SuggestionStyle::HideCodeAlways,
+                    );
+                    lint.multipart_suggestion(
+                        fluent::lint::suggestion_escape,
+                        spans
+                            .into_iter()
+                            .map(|(c, span)| {
+                                let c = format!("{:?}", c);
+                                (span, c[1..c.len() - 1].to_string())
+                            })
+                            .collect(),
+                        Applicability::MachineApplicable,
+                    );
+                } else {
+                    // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
+                    // should do the same here to provide the same good suggestions as we do for
+                    // literals above.
+                    lint.set_arg(
+                        "escaped",
+                        spans
+                            .into_iter()
+                            .map(|(c, _)| format!("{:?}", c))
+                            .collect::<Vec<String>>()
+                            .join(", "),
+                    );
+                    lint.note(fluent::lint::suggestion_remove);
+                    lint.note(fluent::lint::no_suggestion_note_escape);
+                }
+                lint
+            },
+        );
     }
 }
 impl EarlyLintPass for HiddenUnicodeCodepoints {
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index d8a03024d13..8f5e38fdbcc 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -34,13 +34,16 @@ impl LateLintPass<'_> for DefaultHashTypes {
             Some(sym::HashSet) => "FxHashSet",
             _ => return,
         };
-        cx.struct_span_lint(DEFAULT_HASH_TYPES, path.span, |lint| {
-            lint.build(fluent::lint::default_hash_types)
-                .set_arg("preferred", replace)
-                .set_arg("used", cx.tcx.item_name(def_id))
-                .note(fluent::lint::note)
-                .emit();
-        });
+        cx.struct_span_lint(
+            DEFAULT_HASH_TYPES,
+            path.span,
+            fluent::lint::default_hash_types,
+            |lint| {
+                lint.set_arg("preferred", replace)
+                    .set_arg("used", cx.tcx.item_name(def_id))
+                    .note(fluent::lint::note)
+            },
+        );
     }
 }
 
@@ -80,12 +83,12 @@ impl LateLintPass<'_> for QueryStability {
         if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) {
             let def_id = instance.def_id();
             if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) {
-                cx.struct_span_lint(POTENTIAL_QUERY_INSTABILITY, span, |lint| {
-                    lint.build(fluent::lint::query_instability)
-                        .set_arg("query", cx.tcx.item_name(def_id))
-                        .note(fluent::lint::note)
-                        .emit();
-                })
+                cx.struct_span_lint(
+                    POTENTIAL_QUERY_INSTABILITY,
+                    span,
+                    fluent::lint::query_instability,
+                    |lint| lint.set_arg("query", cx.tcx.item_name(def_id)).note(fluent::lint::note),
+                )
             }
         }
     }
@@ -123,15 +126,14 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
             let span = path.span.with_hi(
                 segment.args.map_or(segment.ident.span, |a| a.span_ext).hi()
             );
-            cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| {
-                lint.build(fluent::lint::tykind_kind)
+            cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, fluent::lint::tykind_kind, |lint| {
+                lint
                     .span_suggestion(
                         span,
                         fluent::lint::suggestion,
                         "ty",
                         Applicability::MaybeIncorrect, // ty maybe needs an import
                     )
-                    .emit();
             });
         }
     }
@@ -140,76 +142,77 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
         match &ty.kind {
             TyKind::Path(QPath::Resolved(_, path)) => {
                 if lint_ty_kind_usage(cx, &path.res) {
-                    cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| {
-                        let hir = cx.tcx.hir();
-                        match hir.find(hir.get_parent_node(ty.hir_id)) {
-                            Some(Node::Pat(Pat {
-                                kind:
-                                    PatKind::Path(qpath)
-                                    | PatKind::TupleStruct(qpath, ..)
-                                    | PatKind::Struct(qpath, ..),
-                                ..
-                            })) => {
-                                if let QPath::TypeRelative(qpath_ty, ..) = qpath
-                                    && qpath_ty.hir_id == ty.hir_id
-                                {
-                                    lint.build(fluent::lint::tykind_kind)
-                                        .span_suggestion(
-                                            path.span,
-                                            fluent::lint::suggestion,
-                                            "ty",
-                                            Applicability::MaybeIncorrect, // ty maybe needs an import
-                                        )
-                                        .emit();
-                                    return;
-                                }
+                    let hir = cx.tcx.hir();
+                    let span = match hir.find(hir.get_parent_node(ty.hir_id)) {
+                        Some(Node::Pat(Pat {
+                            kind:
+                                PatKind::Path(qpath)
+                                | PatKind::TupleStruct(qpath, ..)
+                                | PatKind::Struct(qpath, ..),
+                            ..
+                        })) => {
+                            if let QPath::TypeRelative(qpath_ty, ..) = qpath
+                                && qpath_ty.hir_id == ty.hir_id
+                            {
+                                Some(path.span)
+                            } else {
+                                None
                             }
-                            Some(Node::Expr(Expr {
-                                kind: ExprKind::Path(qpath),
-                                ..
-                            })) => {
-                                if let QPath::TypeRelative(qpath_ty, ..) = qpath
-                                    && qpath_ty.hir_id == ty.hir_id
-                                {
-                                    lint.build(fluent::lint::tykind_kind)
-                                        .span_suggestion(
-                                            path.span,
-                                            fluent::lint::suggestion,
-                                            "ty",
-                                            Applicability::MaybeIncorrect, // ty maybe needs an import
-                                        )
-                                        .emit();
-                                    return;
-                                }
+                        }
+                        Some(Node::Expr(Expr {
+                            kind: ExprKind::Path(qpath),
+                            ..
+                        })) => {
+                            if let QPath::TypeRelative(qpath_ty, ..) = qpath
+                                && qpath_ty.hir_id == ty.hir_id
+                            {
+                                Some(path.span)
+                            } else {
+                                None
                             }
-                            // Can't unify these two branches because qpath below is `&&` and above is `&`
-                            // and `A | B` paths don't play well together with adjustments, apparently.
-                            Some(Node::Expr(Expr {
-                                kind: ExprKind::Struct(qpath, ..),
-                                ..
-                            })) => {
-                                if let QPath::TypeRelative(qpath_ty, ..) = qpath
-                                    && qpath_ty.hir_id == ty.hir_id
-                                {
-                                    lint.build(fluent::lint::tykind_kind)
-                                        .span_suggestion(
-                                            path.span,
-                                            fluent::lint::suggestion,
-                                            "ty",
-                                            Applicability::MaybeIncorrect, // ty maybe needs an import
-                                        )
-                                        .emit();
-                                    return;
-                                }
+                        }
+                        // Can't unify these two branches because qpath below is `&&` and above is `&`
+                        // and `A | B` paths don't play well together with adjustments, apparently.
+                        Some(Node::Expr(Expr {
+                            kind: ExprKind::Struct(qpath, ..),
+                            ..
+                        })) => {
+                            if let QPath::TypeRelative(qpath_ty, ..) = qpath
+                                && qpath_ty.hir_id == ty.hir_id
+                            {
+                                Some(path.span)
+                            } else {
+                                None
                             }
-                            _ => {}
                         }
-                        lint.build(fluent::lint::tykind).help(fluent::lint::help).emit();
-                    })
+                        _ => None
+                    };
+
+                    match span {
+                        Some(span) => {
+                            cx.struct_span_lint(
+                                USAGE_OF_TY_TYKIND,
+                                path.span,
+                                fluent::lint::tykind_kind,
+                                |lint| lint.span_suggestion(
+                                    span,
+                                    fluent::lint::suggestion,
+                                    "ty",
+                                    Applicability::MaybeIncorrect, // ty maybe needs an import
+                                )
+                            )
+                        },
+                        None => cx.struct_span_lint(
+                            USAGE_OF_TY_TYKIND,
+                            path.span,
+                            fluent::lint::tykind,
+                            |lint| lint.help(fluent::lint::help)
+                        )
+                    }
                 } else if !ty.span.from_expansion() && let Some(t) = is_ty_or_ty_ctxt(cx, &path) {
                     if path.segments.len() > 1 {
-                        cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, |lint| {
-                            lint.build(fluent::lint::ty_qualified)
+                        cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, fluent::lint::ty_qualified, |lint| {
+                            lint
                                 .set_arg("ty", t.clone())
                                 .span_suggestion(
                                     path.span,
@@ -218,7 +221,6 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
                                     // The import probably needs to be changed
                                     Applicability::MaybeIncorrect,
                                 )
-                                .emit();
                         })
                     }
                 }
@@ -244,7 +246,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
             }
         }
         // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
-        Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
+        Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
             if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
                 if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
                 {
@@ -308,11 +310,8 @@ impl EarlyLintPass for LintPassImpl {
                         cx.struct_span_lint(
                             LINT_PASS_IMPL_WITHOUT_MACRO,
                             lint_pass.path.span,
-                            |lint| {
-                                lint.build(fluent::lint::lintpass_by_hand)
-                                    .help(fluent::lint::help)
-                                    .emit();
-                            },
+                            fluent::lint::lintpass_by_hand,
+                            |lint| lint.help(fluent::lint::help),
                         )
                     }
                 }
@@ -349,12 +348,12 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
                         if is_doc_keyword(v) {
                             return;
                         }
-                        cx.struct_span_lint(EXISTING_DOC_KEYWORD, attr.span, |lint| {
-                            lint.build(fluent::lint::non_existant_doc_keyword)
-                                .set_arg("keyword", v)
-                                .help(fluent::lint::help)
-                                .emit();
-                        });
+                        cx.struct_span_lint(
+                            EXISTING_DOC_KEYWORD,
+                            attr.span,
+                            fluent::lint::non_existant_doc_keyword,
+                            |lint| lint.set_arg("keyword", v).help(fluent::lint::help),
+                        );
                     }
                 }
             }
@@ -412,9 +411,12 @@ impl LateLintPass<'_> for Diagnostics {
         }
         debug!(?found_impl);
         if !found_parent_with_attr && !found_impl {
-            cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| {
-                lint.build(fluent::lint::diag_out_of_impl).emit();
-            })
+            cx.struct_span_lint(
+                DIAGNOSTIC_OUTSIDE_OF_IMPL,
+                span,
+                fluent::lint::diag_out_of_impl,
+                |lint| lint,
+            )
         }
 
         let mut found_diagnostic_message = false;
@@ -430,9 +432,12 @@ impl LateLintPass<'_> for Diagnostics {
         }
         debug!(?found_diagnostic_message);
         if !found_parent_with_attr && !found_diagnostic_message {
-            cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| {
-                lint.build(fluent::lint::untranslatable_diag).emit();
-            })
+            cx.struct_span_lint(
+                UNTRANSLATABLE_DIAGNOSTIC,
+                span,
+                fluent::lint::untranslatable_diag,
+                |lint| lint,
+            )
         }
     }
 }
@@ -464,8 +469,8 @@ impl LateLintPass<'_> for BadOptAccess {
                 let Some(literal) = item.literal()  &&
                 let ast::LitKind::Str(val, _) = literal.kind
             {
-                cx.struct_span_lint(BAD_OPT_ACCESS, expr.span, |lint| {
-                    lint.build(val.as_str()).emit(); }
+                cx.struct_span_lint(BAD_OPT_ACCESS, expr.span, val.as_str(), |lint|
+                    lint
                 );
             }
         }
diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs
index 7e885e6c51a..78f355ec3d0 100644
--- a/compiler/rustc_lint/src/let_underscore.rs
+++ b/compiler/rustc_lint/src/let_underscore.rs
@@ -1,5 +1,5 @@
 use crate::{LateContext, LateLintPass, LintContext};
-use rustc_errors::{Applicability, LintDiagnosticBuilder, MultiSpan};
+use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan};
 use rustc_hir as hir;
 use rustc_middle::ty;
 use rustc_span::Symbol;
@@ -128,48 +128,41 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
                     init.span,
                     "this binding will immediately drop the value assigned to it".to_string(),
                 );
-                cx.struct_span_lint(LET_UNDERSCORE_LOCK, span, |lint| {
-                    build_and_emit_lint(
-                        lint,
-                        local,
-                        init.span,
-                        "non-binding let on a synchronization lock",
-                    )
-                })
+                cx.struct_span_lint(
+                    LET_UNDERSCORE_LOCK,
+                    span,
+                    "non-binding let on a synchronization lock",
+                    |lint| build_lint(lint, local, init.span),
+                )
             } else {
-                cx.struct_span_lint(LET_UNDERSCORE_DROP, local.span, |lint| {
-                    build_and_emit_lint(
-                        lint,
-                        local,
-                        init.span,
-                        "non-binding let on a type that implements `Drop`",
-                    );
-                })
+                cx.struct_span_lint(
+                    LET_UNDERSCORE_DROP,
+                    local.span,
+                    "non-binding let on a type that implements `Drop`",
+                    |lint| build_lint(lint, local, init.span),
+                )
             }
         }
     }
 }
 
-fn build_and_emit_lint(
-    lint: LintDiagnosticBuilder<'_, ()>,
+fn build_lint<'a, 'b>(
+    lint: &'a mut DiagnosticBuilder<'b, ()>,
     local: &hir::Local<'_>,
     init_span: rustc_span::Span,
-    msg: &str,
-) {
-    lint.build(msg)
-        .span_suggestion_verbose(
-            local.pat.span,
-            "consider binding to an unused variable to avoid immediately dropping the value",
-            "_unused",
-            Applicability::MachineApplicable,
-        )
-        .multipart_suggestion(
-            "consider immediately dropping the value",
-            vec![
-                (local.span.until(init_span), "drop(".to_string()),
-                (init_span.shrink_to_hi(), ")".to_string()),
-            ],
-            Applicability::MachineApplicable,
-        )
-        .emit();
+) -> &'a mut DiagnosticBuilder<'b, ()> {
+    lint.span_suggestion_verbose(
+        local.pat.span,
+        "consider binding to an unused variable to avoid immediately dropping the value",
+        "_unused",
+        Applicability::MachineApplicable,
+    )
+    .multipart_suggestion(
+        "consider immediately dropping the value",
+        vec![
+            (local.span.until(init_span), "drop(".to_string()),
+            (init_span.shrink_to_hi(), ")".to_string()),
+        ],
+        Applicability::MachineApplicable,
+    )
 }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 1e16ac51e9e..be1d7d98aa6 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -3,13 +3,15 @@ use crate::late::unerased_lint_store;
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan};
+use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
 use rustc_hir as hir;
-use rustc_hir::{intravisit, HirId};
+use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::HirId;
+use rustc_index::vec::IndexVec;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::{
-    struct_lint_level, LevelAndSource, LintExpectation, LintLevelMap, LintLevelSets,
-    LintLevelSource, LintSet, LintStackIndex, COMMAND_LINE,
+    reveal_actual_level, struct_lint_level, LevelAndSource, LintExpectation, LintLevelSource,
+    ShallowLintLevelMap,
 };
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{RegisteredTools, TyCtxt};
@@ -27,47 +29,408 @@ use crate::errors::{
     UnknownToolInScopedLint,
 };
 
-fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
-    let store = unerased_lint_store(tcx);
-    let levels =
-        LintLevelsBuilder::new(tcx.sess, false, &store, &tcx.resolutions(()).registered_tools);
-    let mut builder = LintLevelMapBuilder { levels, tcx };
-    let krate = tcx.hir().krate();
+/// Collection of lint levels for the whole crate.
+/// This is used by AST-based lints, which do not
+/// wait until we have built HIR to be emitted.
+#[derive(Debug)]
+struct LintLevelSets {
+    /// Linked list of specifications.
+    list: IndexVec<LintStackIndex, LintSet>,
+}
+
+rustc_index::newtype_index! {
+    struct LintStackIndex {
+        ENCODABLE = custom, // we don't need encoding
+        const COMMAND_LINE = 0,
+    }
+}
+
+/// Specifications found at this position in the stack.  This map only represents the lints
+/// found for one set of attributes (like `shallow_lint_levels_on` does).
+///
+/// We store the level specifications as a linked list.
+/// Each `LintSet` represents a set of attributes on the same AST node.
+/// The `parent` forms a linked list that matches the AST tree.
+/// This way, walking the linked list is equivalent to walking the AST bottom-up
+/// to find the specifications for a given lint.
+#[derive(Debug)]
+struct LintSet {
+    // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
+    // flag.
+    specs: FxHashMap<LintId, LevelAndSource>,
+    parent: LintStackIndex,
+}
+
+impl LintLevelSets {
+    fn new() -> Self {
+        LintLevelSets { list: IndexVec::new() }
+    }
+
+    fn get_lint_level(
+        &self,
+        lint: &'static Lint,
+        idx: LintStackIndex,
+        aux: Option<&FxHashMap<LintId, LevelAndSource>>,
+        sess: &Session,
+    ) -> LevelAndSource {
+        let lint = LintId::of(lint);
+        let (level, mut src) = self.raw_lint_id_level(lint, idx, aux);
+        let level = reveal_actual_level(level, &mut src, sess, lint, |id| {
+            self.raw_lint_id_level(id, idx, aux)
+        });
+        (level, src)
+    }
 
-    builder.levels.id_to_set.reserve(krate.owners.len() + 1);
+    fn raw_lint_id_level(
+        &self,
+        id: LintId,
+        mut idx: LintStackIndex,
+        aux: Option<&FxHashMap<LintId, LevelAndSource>>,
+    ) -> (Option<Level>, LintLevelSource) {
+        if let Some(specs) = aux {
+            if let Some(&(level, src)) = specs.get(&id) {
+                return (Some(level), src);
+            }
+        }
+        loop {
+            let LintSet { ref specs, parent } = self.list[idx];
+            if let Some(&(level, src)) = specs.get(&id) {
+                return (Some(level), src);
+            }
+            if idx == COMMAND_LINE {
+                return (None, LintLevelSource::Default);
+            }
+            idx = parent;
+        }
+    }
+}
 
-    let push =
-        builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), true, Some(hir::CRATE_HIR_ID));
+fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> {
+    let store = unerased_lint_store(tcx);
 
-    builder.levels.register_id(hir::CRATE_HIR_ID);
+    let mut builder = LintLevelsBuilder {
+        sess: tcx.sess,
+        provider: QueryMapExpectationsWrapper {
+            tcx,
+            cur: hir::CRATE_HIR_ID,
+            specs: ShallowLintLevelMap::default(),
+            expectations: Vec::new(),
+            unstable_to_stable_ids: FxHashMap::default(),
+            empty: FxHashMap::default(),
+        },
+        warn_about_weird_lints: false,
+        store,
+        registered_tools: &tcx.resolutions(()).registered_tools,
+    };
+
+    builder.add_command_line();
+    builder.add_id(hir::CRATE_HIR_ID);
     tcx.hir().walk_toplevel_module(&mut builder);
-    builder.levels.pop(push);
 
-    builder.levels.update_unstable_expectation_ids();
-    builder.levels.build_map()
+    tcx.sess.diagnostic().update_unstable_expectation_id(&builder.provider.unstable_to_stable_ids);
+
+    builder.provider.expectations
 }
 
-pub struct LintLevelsBuilder<'s> {
-    sess: &'s Session,
-    lint_expectations: Vec<(LintExpectationId, LintExpectation)>,
-    /// Each expectation has a stable and an unstable identifier. This map
-    /// is used to map from unstable to stable [`LintExpectationId`]s.
-    expectation_id_map: FxHashMap<LintExpectationId, LintExpectationId>,
+#[instrument(level = "trace", skip(tcx), ret)]
+fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap {
+    let store = unerased_lint_store(tcx);
+    let attrs = tcx.hir_attrs(owner);
+
+    let mut levels = LintLevelsBuilder {
+        sess: tcx.sess,
+        provider: LintLevelQueryMap {
+            tcx,
+            cur: owner.into(),
+            specs: ShallowLintLevelMap::default(),
+            empty: FxHashMap::default(),
+            attrs,
+        },
+        warn_about_weird_lints: false,
+        store,
+        registered_tools: &tcx.resolutions(()).registered_tools,
+    };
+
+    if owner == hir::CRATE_OWNER_ID {
+        levels.add_command_line();
+    }
+
+    match attrs.map.range(..) {
+        // There is only something to do if there are attributes at all.
+        [] => {}
+        // Most of the time, there is only one attribute.  Avoid fetching HIR in that case.
+        [(local_id, _)] => levels.add_id(HirId { owner, local_id: *local_id }),
+        // Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
+        // a standard visit.
+        // FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's.
+        _ => match tcx.hir().expect_owner(owner) {
+            hir::OwnerNode::Item(item) => levels.visit_item(item),
+            hir::OwnerNode::ForeignItem(item) => levels.visit_foreign_item(item),
+            hir::OwnerNode::TraitItem(item) => levels.visit_trait_item(item),
+            hir::OwnerNode::ImplItem(item) => levels.visit_impl_item(item),
+            hir::OwnerNode::Crate(mod_) => {
+                levels.add_id(hir::CRATE_HIR_ID);
+                levels.visit_mod(mod_, mod_.spans.inner_span, hir::CRATE_HIR_ID)
+            }
+        },
+    }
+
+    let specs = levels.provider.specs;
+
+    #[cfg(debug_assertions)]
+    for (_, v) in specs.specs.iter() {
+        debug_assert!(!v.is_empty());
+    }
+
+    specs
+}
+
+pub struct TopDown {
     sets: LintLevelSets,
-    id_to_set: FxHashMap<HirId, LintStackIndex>,
     cur: LintStackIndex,
+}
+
+pub trait LintLevelsProvider {
+    fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource>;
+    fn insert(&mut self, id: LintId, lvl: LevelAndSource);
+    fn get_lint_level(&self, lint: &'static Lint, sess: &Session) -> LevelAndSource;
+    fn push_expectation(&mut self, _id: LintExpectationId, _expectation: LintExpectation) {}
+}
+
+impl LintLevelsProvider for TopDown {
+    fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> {
+        &self.sets.list[self.cur].specs
+    }
+
+    fn insert(&mut self, id: LintId, lvl: LevelAndSource) {
+        self.sets.list[self.cur].specs.insert(id, lvl);
+    }
+
+    fn get_lint_level(&self, lint: &'static Lint, sess: &Session) -> LevelAndSource {
+        self.sets.get_lint_level(lint, self.cur, Some(self.current_specs()), sess)
+    }
+}
+
+struct LintLevelQueryMap<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    cur: HirId,
+    specs: ShallowLintLevelMap,
+    /// Empty hash map to simplify code.
+    empty: FxHashMap<LintId, LevelAndSource>,
+    attrs: &'tcx hir::AttributeMap<'tcx>,
+}
+
+impl LintLevelsProvider for LintLevelQueryMap<'_> {
+    fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> {
+        self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty)
+    }
+    fn insert(&mut self, id: LintId, lvl: LevelAndSource) {
+        self.specs.specs.get_mut_or_insert_default(self.cur.local_id).insert(id, lvl);
+    }
+    fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource {
+        self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur)
+    }
+}
+
+struct QueryMapExpectationsWrapper<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    cur: HirId,
+    specs: ShallowLintLevelMap,
+    expectations: Vec<(LintExpectationId, LintExpectation)>,
+    unstable_to_stable_ids: FxHashMap<LintExpectationId, LintExpectationId>,
+    /// Empty hash map to simplify code.
+    empty: FxHashMap<LintId, LevelAndSource>,
+}
+
+impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> {
+    fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> {
+        self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty)
+    }
+    fn insert(&mut self, id: LintId, lvl: LevelAndSource) {
+        let specs = self.specs.specs.get_mut_or_insert_default(self.cur.local_id);
+        specs.clear();
+        specs.insert(id, lvl);
+    }
+    fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource {
+        self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur)
+    }
+    fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation) {
+        let LintExpectationId::Stable { attr_id: Some(attr_id), hir_id, attr_index, .. } = id else { bug!("unstable expectation id should already be mapped") };
+        let key = LintExpectationId::Unstable { attr_id, lint_index: None };
+
+        if !self.unstable_to_stable_ids.contains_key(&key) {
+            self.unstable_to_stable_ids.insert(
+                key,
+                LintExpectationId::Stable { hir_id, attr_index, lint_index: None, attr_id: None },
+            );
+        }
+
+        self.expectations.push((id.normalize(), expectation));
+    }
+}
+
+impl<'tcx> LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
+    fn add_id(&mut self, hir_id: HirId) {
+        self.provider.cur = hir_id;
+        self.add(
+            self.provider.attrs.get(hir_id.local_id),
+            hir_id == hir::CRATE_HIR_ID,
+            Some(hir_id),
+        );
+    }
+}
+
+impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
+    type NestedFilter = nested_filter::OnlyBodies;
+
+    fn nested_visit_map(&mut self) -> Self::Map {
+        self.provider.tcx.hir()
+    }
+
+    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
+        self.add_id(param.hir_id);
+        intravisit::walk_param(self, param);
+    }
+
+    fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
+        self.add_id(it.hir_id());
+        intravisit::walk_item(self, it);
+    }
+
+    fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
+        self.add_id(it.hir_id());
+        intravisit::walk_foreign_item(self, it);
+    }
+
+    fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) {
+        // We will call `add_id` when we walk
+        // the `StmtKind`. The outer statement itself doesn't
+        // define the lint levels.
+        intravisit::walk_stmt(self, e);
+    }
+
+    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
+        self.add_id(e.hir_id);
+        intravisit::walk_expr(self, e);
+    }
+
+    fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
+        self.add_id(s.hir_id);
+        intravisit::walk_field_def(self, s);
+    }
+
+    fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
+        self.add_id(v.id);
+        intravisit::walk_variant(self, v);
+    }
+
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
+        self.add_id(l.hir_id);
+        intravisit::walk_local(self, l);
+    }
+
+    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
+        self.add_id(a.hir_id);
+        intravisit::walk_arm(self, a);
+    }
+
+    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
+        self.add_id(trait_item.hir_id());
+        intravisit::walk_trait_item(self, trait_item);
+    }
+
+    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
+        self.add_id(impl_item.hir_id());
+        intravisit::walk_impl_item(self, impl_item);
+    }
+}
+
+impl<'tcx> LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> {
+    fn add_id(&mut self, hir_id: HirId) {
+        self.provider.cur = hir_id;
+        self.add(self.provider.tcx.hir().attrs(hir_id), hir_id == hir::CRATE_HIR_ID, Some(hir_id));
+    }
+}
+
+impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> {
+    type NestedFilter = nested_filter::All;
+
+    fn nested_visit_map(&mut self) -> Self::Map {
+        self.provider.tcx.hir()
+    }
+
+    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
+        self.add_id(param.hir_id);
+        intravisit::walk_param(self, param);
+    }
+
+    fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
+        self.add_id(it.hir_id());
+        intravisit::walk_item(self, it);
+    }
+
+    fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
+        self.add_id(it.hir_id());
+        intravisit::walk_foreign_item(self, it);
+    }
+
+    fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) {
+        // We will call `add_id` when we walk
+        // the `StmtKind`. The outer statement itself doesn't
+        // define the lint levels.
+        intravisit::walk_stmt(self, e);
+    }
+
+    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
+        self.add_id(e.hir_id);
+        intravisit::walk_expr(self, e);
+    }
+
+    fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
+        self.add_id(s.hir_id);
+        intravisit::walk_field_def(self, s);
+    }
+
+    fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
+        self.add_id(v.id);
+        intravisit::walk_variant(self, v);
+    }
+
+    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
+        self.add_id(l.hir_id);
+        intravisit::walk_local(self, l);
+    }
+
+    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
+        self.add_id(a.hir_id);
+        intravisit::walk_arm(self, a);
+    }
+
+    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
+        self.add_id(trait_item.hir_id());
+        intravisit::walk_trait_item(self, trait_item);
+    }
+
+    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
+        self.add_id(impl_item.hir_id());
+        intravisit::walk_impl_item(self, impl_item);
+    }
+}
+
+pub struct LintLevelsBuilder<'s, P> {
+    sess: &'s Session,
+    provider: P,
     warn_about_weird_lints: bool,
     store: &'s LintStore,
     registered_tools: &'s RegisteredTools,
 }
 
-pub struct BuilderPush {
+pub(crate) struct BuilderPush {
     prev: LintStackIndex,
-    pub changed: bool,
 }
 
-impl<'s> LintLevelsBuilder<'s> {
-    pub fn new(
+impl<'s> LintLevelsBuilder<'s, TopDown> {
+    pub(crate) fn new(
         sess: &'s Session,
         warn_about_weird_lints: bool,
         store: &'s LintStore,
@@ -75,20 +438,74 @@ impl<'s> LintLevelsBuilder<'s> {
     ) -> Self {
         let mut builder = LintLevelsBuilder {
             sess,
-            lint_expectations: Default::default(),
-            expectation_id_map: Default::default(),
-            sets: LintLevelSets::new(),
-            cur: COMMAND_LINE,
-            id_to_set: Default::default(),
+            provider: TopDown { sets: LintLevelSets::new(), cur: COMMAND_LINE },
             warn_about_weird_lints,
             store,
             registered_tools,
         };
-        builder.process_command_line(sess, store);
-        assert_eq!(builder.sets.list.len(), 1);
+        builder.process_command_line();
+        assert_eq!(builder.provider.sets.list.len(), 1);
         builder
     }
 
+    fn process_command_line(&mut self) {
+        self.provider.cur = self
+            .provider
+            .sets
+            .list
+            .push(LintSet { specs: FxHashMap::default(), parent: COMMAND_LINE });
+        self.add_command_line();
+    }
+
+    /// Pushes a list of AST lint attributes onto this context.
+    ///
+    /// This function will return a `BuilderPush` object which should be passed
+    /// to `pop` when this scope for the attributes provided is exited.
+    ///
+    /// This function will perform a number of tasks:
+    ///
+    /// * It'll validate all lint-related attributes in `attrs`
+    /// * It'll mark all lint-related attributes as used
+    /// * Lint levels will be updated based on the attributes provided
+    /// * Lint attributes are validated, e.g., a `#[forbid]` can't be switched to
+    ///   `#[allow]`
+    ///
+    /// Don't forget to call `pop`!
+    pub(crate) fn push(
+        &mut self,
+        attrs: &[ast::Attribute],
+        is_crate_node: bool,
+        source_hir_id: Option<HirId>,
+    ) -> BuilderPush {
+        let prev = self.provider.cur;
+        self.provider.cur =
+            self.provider.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev });
+
+        self.add(attrs, is_crate_node, source_hir_id);
+
+        if self.provider.current_specs().is_empty() {
+            self.provider.sets.list.pop();
+            self.provider.cur = prev;
+        }
+
+        BuilderPush { prev }
+    }
+
+    /// Called after `push` when the scope of a set of attributes are exited.
+    pub(crate) fn pop(&mut self, push: BuilderPush) {
+        self.provider.cur = push.prev;
+        std::mem::forget(push);
+    }
+}
+
+#[cfg(debug_assertions)]
+impl Drop for BuilderPush {
+    fn drop(&mut self) {
+        panic!("Found a `push` without a `pop`.");
+    }
+}
+
+impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     pub(crate) fn sess(&self) -> &Session {
         self.sess
     }
@@ -98,24 +515,20 @@ impl<'s> LintLevelsBuilder<'s> {
     }
 
     fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> {
-        &self.sets.list[self.cur].specs
+        self.provider.current_specs()
     }
 
-    fn current_specs_mut(&mut self) -> &mut FxHashMap<LintId, LevelAndSource> {
-        &mut self.sets.list[self.cur].specs
+    fn insert(&mut self, id: LintId, lvl: LevelAndSource) {
+        self.provider.insert(id, lvl)
     }
 
-    fn process_command_line(&mut self, sess: &Session, store: &LintStore) {
-        self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid);
-
-        self.cur =
-            self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: COMMAND_LINE });
-        for &(ref lint_name, level) in &sess.opts.lint_opts {
-            store.check_lint_name_cmdline(sess, &lint_name, level, self.registered_tools);
+    fn add_command_line(&mut self) {
+        for &(ref lint_name, level) in &self.sess.opts.lint_opts {
+            self.store.check_lint_name_cmdline(self.sess, &lint_name, level, self.registered_tools);
             let orig_level = level;
             let lint_flag_val = Symbol::intern(lint_name);
 
-            let Ok(ids) = store.find_lints(&lint_name) else {
+            let Ok(ids) = self.store.find_lints(&lint_name) else {
                 // errors handled in check_lint_name_cmdline above
                 continue
             };
@@ -129,7 +542,7 @@ impl<'s> LintLevelsBuilder<'s> {
 
                 if self.check_gated_lint(id, DUMMY_SP) {
                     let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
-                    self.current_specs_mut().insert(id, (level, src));
+                    self.insert(id, (level, src));
                 }
             }
         }
@@ -138,9 +551,11 @@ impl<'s> LintLevelsBuilder<'s> {
     /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful
     /// (e.g. if a forbid was already inserted on the same scope), then emits a
     /// diagnostic with no change to `specs`.
-    fn insert_spec(&mut self, id: LintId, (level, src): LevelAndSource) {
-        let (old_level, old_src) =
-            self.sets.get_lint_level(id.lint, self.cur, Some(self.current_specs()), &self.sess);
+    fn insert_spec(&mut self, id: LintId, (mut level, src): LevelAndSource) {
+        let (old_level, old_src) = self.provider.get_lint_level(id.lint, &self.sess);
+        if let Level::Expect(id) = &mut level && let LintExpectationId::Stable { .. } = id {
+            *id = id.normalize();
+        }
         // Setting to a non-forbid level is an error if the lint previously had
         // a forbid level. Note that this is not necessarily true even with a
         // `#[forbid(..)]` attribute present, as that is overridden by `--cap-lints`.
@@ -158,7 +573,7 @@ impl<'s> LintLevelsBuilder<'s> {
                 let id_name = id.lint.name_lower();
                 let fcw_warning = match old_src {
                     LintLevelSource::Default => false,
-                    LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol),
+                    LintLevelSource::Node { name, .. } => self.store.is_lint_group(name),
                     LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol),
                 };
                 debug!(
@@ -178,8 +593,8 @@ impl<'s> LintLevelsBuilder<'s> {
                                 id.to_string()
                             ));
                         }
-                        LintLevelSource::Node(_, forbid_source_span, reason) => {
-                            diag.span_label(forbid_source_span, "`forbid` level set here");
+                        LintLevelSource::Node { span, reason, .. } => {
+                            diag.span_label(span, "`forbid` level set here");
                             if let Some(rationale) = reason {
                                 diag.note(rationale.as_str());
                             }
@@ -199,11 +614,8 @@ impl<'s> LintLevelsBuilder<'s> {
                             LintLevelSource::Default => {
                                 OverruledAttributeSub::DefaultSource { id: id.to_string() }
                             }
-                            LintLevelSource::Node(_, forbid_source_span, reason) => {
-                                OverruledAttributeSub::NodeSource {
-                                    span: forbid_source_span,
-                                    reason,
-                                }
+                            LintLevelSource::Node { span, reason, .. } => {
+                                OverruledAttributeSub::NodeSource { span, reason }
                             }
                             LintLevelSource::CommandLine(_, _) => {
                                 OverruledAttributeSub::CommandLineSource
@@ -214,14 +626,14 @@ impl<'s> LintLevelsBuilder<'s> {
                     self.struct_lint(
                         FORBIDDEN_LINT_GROUPS,
                         Some(src.span().into()),
-                        |diag_builder| {
-                            let mut diag_builder = diag_builder.build(&format!(
-                                "{}({}) incompatible with previous forbid",
-                                level.as_str(),
-                                src.name(),
-                            ));
-                            decorate_diag(&mut diag_builder);
-                            diag_builder.emit();
+                        format!(
+                            "{}({}) incompatible with previous forbid",
+                            level.as_str(),
+                            src.name(),
+                        ),
+                        |lint| {
+                            decorate_diag(lint);
+                            lint
                         },
                     );
                 }
@@ -244,45 +656,21 @@ impl<'s> LintLevelsBuilder<'s> {
 
         match (old_level, level) {
             // If the new level is an expectation store it in `ForceWarn`
-            (Level::ForceWarn(_), Level::Expect(expectation_id)) => self
-                .current_specs_mut()
-                .insert(id, (Level::ForceWarn(Some(expectation_id)), old_src)),
-            // Keep `ForceWarn` level but drop the expectation
-            (Level::ForceWarn(_), _) => {
-                self.current_specs_mut().insert(id, (Level::ForceWarn(None), old_src))
+            (Level::ForceWarn(_), Level::Expect(expectation_id)) => {
+                self.insert(id, (Level::ForceWarn(Some(expectation_id)), old_src))
             }
+            // Keep `ForceWarn` level but drop the expectation
+            (Level::ForceWarn(_), _) => self.insert(id, (Level::ForceWarn(None), old_src)),
             // Set the lint level as normal
-            _ => self.current_specs_mut().insert(id, (level, src)),
+            _ => self.insert(id, (level, src)),
         };
     }
 
-    /// Pushes a list of AST lint attributes onto this context.
-    ///
-    /// This function will return a `BuilderPush` object which should be passed
-    /// to `pop` when this scope for the attributes provided is exited.
-    ///
-    /// This function will perform a number of tasks:
-    ///
-    /// * It'll validate all lint-related attributes in `attrs`
-    /// * It'll mark all lint-related attributes as used
-    /// * Lint levels will be updated based on the attributes provided
-    /// * Lint attributes are validated, e.g., a `#[forbid]` can't be switched to
-    ///   `#[allow]`
-    ///
-    /// Don't forget to call `pop`!
-    pub(crate) fn push(
-        &mut self,
-        attrs: &[ast::Attribute],
-        is_crate_node: bool,
-        source_hir_id: Option<HirId>,
-    ) -> BuilderPush {
-        let prev = self.cur;
-        self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev });
-
+    fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option<HirId>) {
         let sess = self.sess;
         for (attr_index, attr) in attrs.iter().enumerate() {
             if attr.has_name(sym::automatically_derived) {
-                self.current_specs_mut().insert(
+                self.insert(
                     LintId::of(SINGLE_USE_LIFETIMES),
                     (Level::Allow, LintLevelSource::Default),
                 );
@@ -293,7 +681,17 @@ impl<'s> LintLevelsBuilder<'s> {
                 None => continue,
                 // This is the only lint level with a `LintExpectationId` that can be created from an attribute
                 Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {
-                    let stable_id = self.create_stable_id(unstable_id, hir_id, attr_index);
+                    let LintExpectationId::Unstable { attr_id, lint_index } = unstable_id
+                        else { bug!("stable id Level::from_attr") };
+
+                    let stable_id = LintExpectationId::Stable {
+                        hir_id,
+                        attr_index: attr_index.try_into().unwrap(),
+                        lint_index,
+                        // we pass the previous unstable attr_id such that we can trace the ast id when building a map
+                        // to go from unstable to stable id.
+                        attr_id: Some(attr_id),
+                    };
 
                     Level::Expect(stable_id)
                 }
@@ -408,7 +806,7 @@ impl<'s> LintLevelsBuilder<'s> {
                                 [lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS),
                                 _ => false,
                             };
-                            self.lint_expectations.push((
+                            self.provider.push_expectation(
                                 expect_id,
                                 LintExpectation::new(
                                     reason,
@@ -416,13 +814,19 @@ impl<'s> LintLevelsBuilder<'s> {
                                     is_unfulfilled_lint_expectations,
                                     tool_name,
                                 ),
-                            ));
+                            );
                         }
-                        let src = LintLevelSource::Node(
-                            meta_item.path.segments.last().expect("empty lint name").ident.name,
-                            sp,
+                        let src = LintLevelSource::Node {
+                            name: meta_item
+                                .path
+                                .segments
+                                .last()
+                                .expect("empty lint name")
+                                .ident
+                                .name,
+                            span: sp,
                             reason,
-                        );
+                        };
                         for &id in *ids {
                             if self.check_gated_lint(id, attr.span) {
                                 self.insert_spec(id, (level, src));
@@ -435,67 +839,60 @@ impl<'s> LintLevelsBuilder<'s> {
                             Ok(ids) => {
                                 let complete_name =
                                     &format!("{}::{}", tool_ident.unwrap().name, name);
-                                let src = LintLevelSource::Node(
-                                    Symbol::intern(complete_name),
-                                    sp,
+                                let src = LintLevelSource::Node {
+                                    name: Symbol::intern(complete_name),
+                                    span: sp,
                                     reason,
-                                );
+                                };
                                 for &id in ids {
                                     if self.check_gated_lint(id, attr.span) {
                                         self.insert_spec(id, (level, src));
                                     }
                                 }
                                 if let Level::Expect(expect_id) = level {
-                                    self.lint_expectations.push((
+                                    self.provider.push_expectation(
                                         expect_id,
                                         LintExpectation::new(reason, sp, false, tool_name),
-                                    ));
+                                    );
                                 }
                             }
                             Err((Some(ids), ref new_lint_name)) => {
                                 let lint = builtin::RENAMED_AND_REMOVED_LINTS;
-                                let (lvl, src) = self.sets.get_lint_level(
-                                    lint,
-                                    self.cur,
-                                    Some(self.current_specs()),
-                                    &sess,
-                                );
+                                let (lvl, src) = self.provider.get_lint_level(lint, &sess);
                                 struct_lint_level(
                                     self.sess,
                                     lint,
                                     lvl,
                                     src,
                                     Some(sp.into()),
+                                    format!(
+                                        "lint name `{}` is deprecated \
+                                         and may not have an effect in the future.",
+                                        name
+                                    ),
                                     |lint| {
-                                        let msg = format!(
-                                            "lint name `{}` is deprecated \
-                                             and may not have an effect in the future.",
-                                            name
-                                        );
-                                        lint.build(&msg)
-                                            .span_suggestion(
-                                                sp,
-                                                "change it to",
-                                                new_lint_name,
-                                                Applicability::MachineApplicable,
-                                            )
-                                            .emit();
+                                        lint.span_suggestion(
+                                            sp,
+                                            "change it to",
+                                            new_lint_name,
+                                            Applicability::MachineApplicable,
+                                        )
                                     },
                                 );
 
-                                let src = LintLevelSource::Node(
-                                    Symbol::intern(&new_lint_name),
-                                    sp,
+                                let src = LintLevelSource::Node {
+                                    name: Symbol::intern(&new_lint_name),
+                                    span: sp,
                                     reason,
-                                );
+                                };
                                 for id in ids {
                                     self.insert_spec(*id, (level, src));
                                 }
                                 if let Level::Expect(expect_id) = level {
-                                    self.lint_expectations.push((
+                                    self.provider.push_expectation(
                                         expect_id,
                                         LintExpectation::new(reason, sp, false, tool_name),
-                                    ));
+                                    );
                                 }
                             }
                             Err((None, _)) => {
@@ -521,57 +918,54 @@ impl<'s> LintLevelsBuilder<'s> {
 
                     CheckLintNameResult::Warning(msg, renamed) => {
                         let lint = builtin::RENAMED_AND_REMOVED_LINTS;
-                        let (renamed_lint_level, src) = self.sets.get_lint_level(
-                            lint,
-                            self.cur,
-                            Some(self.current_specs()),
-                            &sess,
-                        );
+                        let (renamed_lint_level, src) = self.provider.get_lint_level(lint, &sess);
                         struct_lint_level(
                             self.sess,
                             lint,
                             renamed_lint_level,
                             src,
                             Some(sp.into()),
+                            msg,
                             |lint| {
-                                let mut err = lint.build(msg);
                                 if let Some(new_name) = &renamed {
-                                    err.span_suggestion(
+                                    lint.span_suggestion(
                                         sp,
                                         "use the new name",
                                         new_name,
                                         Applicability::MachineApplicable,
                                     );
                                 }
-                                err.emit();
+                                lint
                             },
                         );
                     }
                     CheckLintNameResult::NoLint(suggestion) => {
                         let lint = builtin::UNKNOWN_LINTS;
-                        let (level, src) = self.sets.get_lint_level(
-                            lint,
-                            self.cur,
-                            Some(self.current_specs()),
+                        let (level, src) = self.provider.get_lint_level(lint, self.sess);
+                        let name = if let Some(tool_ident) = tool_ident {
+                            format!("{}::{}", tool_ident.name, name)
+                        } else {
+                            name.to_string()
+                        };
+                        struct_lint_level(
                             self.sess,
+                            lint,
+                            level,
+                            src,
+                            Some(sp.into()),
+                            format!("unknown lint: `{}`", name),
+                            |lint| {
+                                if let Some(suggestion) = suggestion {
+                                    lint.span_suggestion(
+                                        sp,
+                                        "did you mean",
+                                        suggestion,
+                                        Applicability::MachineApplicable,
+                                    );
+                                }
+                                lint
+                            },
                         );
-                        struct_lint_level(self.sess, lint, level, src, Some(sp.into()), |lint| {
-                            let name = if let Some(tool_ident) = tool_ident {
-                                format!("{}::{}", tool_ident.name, name)
-                            } else {
-                                name.to_string()
-                            };
-                            let mut db = lint.build(format!("unknown lint: `{}`", name));
-                            if let Some(suggestion) = suggestion {
-                                db.span_suggestion(
-                                    sp,
-                                    "did you mean",
-                                    suggestion,
-                                    Applicability::MachineApplicable,
-                                );
-                            }
-                            db.emit();
-                        });
                     }
                 }
                 // If this lint was renamed, apply the new lint instead of ignoring the attribute.
@@ -583,17 +977,21 @@ impl<'s> LintLevelsBuilder<'s> {
                     if let CheckLintNameResult::Ok(ids) =
                         self.store.check_lint_name(&new_name, None, self.registered_tools)
                     {
-                        let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason);
+                        let src = LintLevelSource::Node {
+                            name: Symbol::intern(&new_name),
+                            span: sp,
+                            reason,
+                        };
                         for &id in ids {
                             if self.check_gated_lint(id, attr.span) {
                                 self.insert_spec(id, (level, src));
                             }
                         }
                         if let Level::Expect(expect_id) = level {
-                            self.lint_expectations.push((
+                            self.provider.push_expectation(
                                 expect_id,
                                 LintExpectation::new(reason, sp, false, tool_name),
-                            ));
+                            );
                         }
                     } else {
                         panic!("renamed lint does not exist: {}", new_name);
@@ -608,232 +1006,83 @@ impl<'s> LintLevelsBuilder<'s> {
                     continue;
                 }
 
-                let LintLevelSource::Node(lint_attr_name, lint_attr_span, _) = *src else {
+                let LintLevelSource::Node { name: lint_attr_name, span: lint_attr_span, .. } = *src else {
                     continue
                 };
 
                 let lint = builtin::UNUSED_ATTRIBUTES;
-                let (lint_level, lint_src) =
-                    self.sets.get_lint_level(lint, self.cur, Some(self.current_specs()), self.sess);
+                let (lint_level, lint_src) = self.provider.get_lint_level(lint, &self.sess);
                 struct_lint_level(
                     self.sess,
                     lint,
                     lint_level,
                     lint_src,
                     Some(lint_attr_span.into()),
-                    |lint| {
-                        let mut db = lint.build(&format!(
-                            "{}({}) is ignored unless specified at crate level",
-                            level.as_str(),
-                            lint_attr_name
-                        ));
-                        db.emit();
-                    },
+                    format!(
+                        "{}({}) is ignored unless specified at crate level",
+                        level.as_str(),
+                        lint_attr_name
+                    ),
+                    |lint| lint,
                 );
                 // don't set a separate error for every lint in the group
                 break;
             }
         }
-
-        if self.current_specs().is_empty() {
-            self.sets.list.pop();
-            self.cur = prev;
-        }
-
-        BuilderPush { prev, changed: prev != self.cur }
-    }
-
-    fn create_stable_id(
-        &mut self,
-        unstable_id: LintExpectationId,
-        hir_id: HirId,
-        attr_index: usize,
-    ) -> LintExpectationId {
-        let stable_id =
-            LintExpectationId::Stable { hir_id, attr_index: attr_index as u16, lint_index: None };
-
-        self.expectation_id_map.insert(unstable_id, stable_id);
-
-        stable_id
     }
 
     /// Checks if the lint is gated on a feature that is not enabled.
     ///
     /// Returns `true` if the lint's feature is enabled.
+    // FIXME only emit this once for each attribute, instead of repeating it 4 times for
+    // pre-expansion lints, post-expansion lints, `shallow_lint_levels_on` and `lint_expectations`.
     fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool {
         if let Some(feature) = lint_id.lint.feature_gate {
             if !self.sess.features_untracked().enabled(feature) {
                 let lint = builtin::UNKNOWN_LINTS;
                 let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
-                struct_lint_level(self.sess, lint, level, src, Some(span.into()), |lint_db| {
-                    let mut db =
-                        lint_db.build(&format!("unknown lint: `{}`", lint_id.lint.name_lower()));
-                    db.note(&format!("the `{}` lint is unstable", lint_id.lint.name_lower(),));
-                    add_feature_diagnostics(&mut db, &self.sess.parse_sess, feature);
-                    db.emit();
-                });
+                struct_lint_level(
+                    self.sess,
+                    lint,
+                    level,
+                    src,
+                    Some(span.into()),
+                    format!("unknown lint: `{}`", lint_id.lint.name_lower()),
+                    |lint| {
+                        lint.note(
+                            &format!("the `{}` lint is unstable", lint_id.lint.name_lower(),),
+                        );
+                        add_feature_diagnostics(lint, &self.sess.parse_sess, feature);
+                        lint
+                    },
+                );
                 return false;
             }
         }
         true
     }
 
-    /// Called after `push` when the scope of a set of attributes are exited.
-    pub fn pop(&mut self, push: BuilderPush) {
-        self.cur = push.prev;
-    }
-
     /// Find the lint level for a lint.
-    pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintLevelSource) {
-        self.sets.get_lint_level(lint, self.cur, None, self.sess)
+    pub fn lint_level(&self, lint: &'static Lint) -> LevelAndSource {
+        self.provider.get_lint_level(lint, self.sess)
     }
 
     /// Used to emit a lint-related diagnostic based on the current state of
     /// this lint context.
-    pub fn struct_lint(
+    pub(crate) fn struct_lint(
         &self,
         lint: &'static Lint,
         span: Option<MultiSpan>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
         let (level, src) = self.lint_level(lint);
-        struct_lint_level(self.sess, lint, level, src, span, decorate)
-    }
-
-    /// Registers the ID provided with the current set of lints stored in
-    /// this context.
-    pub fn register_id(&mut self, id: HirId) {
-        self.id_to_set.insert(id, self.cur);
-    }
-
-    fn update_unstable_expectation_ids(&self) {
-        self.sess.diagnostic().update_unstable_expectation_id(&self.expectation_id_map);
-    }
-
-    pub fn build_map(self) -> LintLevelMap {
-        LintLevelMap {
-            sets: self.sets,
-            id_to_set: self.id_to_set,
-            lint_expectations: self.lint_expectations,
-        }
-    }
-}
-
-struct LintLevelMapBuilder<'tcx> {
-    levels: LintLevelsBuilder<'tcx>,
-    tcx: TyCtxt<'tcx>,
-}
-
-impl LintLevelMapBuilder<'_> {
-    fn with_lint_attrs<F>(&mut self, id: hir::HirId, f: F)
-    where
-        F: FnOnce(&mut Self),
-    {
-        let is_crate_hir = id == hir::CRATE_HIR_ID;
-        let attrs = self.tcx.hir().attrs(id);
-        let push = self.levels.push(attrs, is_crate_hir, Some(id));
-
-        if push.changed {
-            self.levels.register_id(id);
-        }
-        f(self);
-        self.levels.pop(push);
-    }
-}
-
-impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
-    type NestedFilter = nested_filter::All;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.tcx.hir()
-    }
-
-    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
-        self.with_lint_attrs(param.hir_id, |builder| {
-            intravisit::walk_param(builder, param);
-        });
-    }
-
-    fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
-        self.with_lint_attrs(it.hir_id(), |builder| {
-            intravisit::walk_item(builder, it);
-        });
-    }
-
-    fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
-        self.with_lint_attrs(it.hir_id(), |builder| {
-            intravisit::walk_foreign_item(builder, it);
-        })
-    }
-
-    fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) {
-        // We will call `with_lint_attrs` when we walk
-        // the `StmtKind`. The outer statement itself doesn't
-        // define the lint levels.
-        intravisit::walk_stmt(self, e);
-    }
-
-    fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
-        self.with_lint_attrs(e.hir_id, |builder| {
-            intravisit::walk_expr(builder, e);
-        })
-    }
-
-    fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) {
-        self.with_lint_attrs(field.hir_id, |builder| {
-            intravisit::walk_expr_field(builder, field);
-        })
-    }
-
-    fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
-        self.with_lint_attrs(s.hir_id, |builder| {
-            intravisit::walk_field_def(builder, s);
-        })
-    }
-
-    fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
-        self.with_lint_attrs(v.id, |builder| {
-            intravisit::walk_variant(builder, v);
-        })
-    }
-
-    fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
-        self.with_lint_attrs(l.hir_id, |builder| {
-            intravisit::walk_local(builder, l);
-        })
-    }
-
-    fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) {
-        self.with_lint_attrs(a.hir_id, |builder| {
-            intravisit::walk_arm(builder, a);
-        })
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
-        self.with_lint_attrs(trait_item.hir_id(), |builder| {
-            intravisit::walk_trait_item(builder, trait_item);
-        });
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
-        self.with_lint_attrs(impl_item.hir_id(), |builder| {
-            intravisit::walk_impl_item(builder, impl_item);
-        });
-    }
-
-    fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
-        self.with_lint_attrs(field.hir_id, |builder| {
-            intravisit::walk_pat_field(builder, field);
-        })
-    }
-
-    fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
-        self.with_lint_attrs(p.hir_id, |builder| {
-            intravisit::walk_generic_param(builder, p);
-        });
+        struct_lint_level(self.sess, lint, level, src, span, msg, decorate)
     }
 }
 
-pub fn provide(providers: &mut Providers) {
-    providers.lint_levels = lint_levels;
+pub(crate) fn provide(providers: &mut Providers) {
+    *providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers };
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 4408f68dd63..9148c42195f 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -62,6 +62,7 @@ mod non_ascii_idents;
 mod non_fmt_panic;
 mod nonstandard_style;
 mod noop_method_call;
+mod opaque_hidden_inferred_bound;
 mod pass_by_value;
 mod passes;
 mod redundant_semicolon;
@@ -93,6 +94,7 @@ use non_ascii_idents::*;
 use non_fmt_panic::NonPanicFmt;
 use nonstandard_style::*;
 use noop_method_call::*;
+use opaque_hidden_inferred_bound::*;
 use pass_by_value::*;
 use redundant_semicolon::*;
 use traits::*;
@@ -223,6 +225,7 @@ macro_rules! late_lint_mod_passes {
                 EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
                 InvalidAtomicOrdering: InvalidAtomicOrdering,
                 NamedAsmLabels: NamedAsmLabels,
+                OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
             ]
         );
     };
diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs
index 5f7f03480c0..313119637bc 100644
--- a/compiler/rustc_lint/src/methods.rs
+++ b/compiler/rustc_lint/src/methods.rs
@@ -90,14 +90,17 @@ fn lint_cstring_as_ptr(
         if cx.tcx.is_diagnostic_item(sym::Result, def.did()) {
             if let ty::Adt(adt, _) = substs.type_at(0).kind() {
                 if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) {
-                    cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
-                        diag.build(fluent::lint::cstring_ptr)
-                            .span_label(as_ptr_span, fluent::lint::as_ptr_label)
-                            .span_label(unwrap.span, fluent::lint::unwrap_label)
-                            .note(fluent::lint::note)
-                            .help(fluent::lint::help)
-                            .emit();
-                    });
+                    cx.struct_span_lint(
+                        TEMPORARY_CSTRING_AS_PTR,
+                        as_ptr_span,
+                        fluent::lint::cstring_ptr,
+                        |diag| {
+                            diag.span_label(as_ptr_span, fluent::lint::as_ptr_label)
+                                .span_label(unwrap.span, fluent::lint::unwrap_label)
+                                .note(fluent::lint::note)
+                                .help(fluent::lint::help)
+                        },
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 764003e61a6..b2626efb6d7 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -180,15 +180,21 @@ impl EarlyLintPass for NonAsciiIdents {
                 continue;
             }
             has_non_ascii_idents = true;
-            cx.struct_span_lint(NON_ASCII_IDENTS, sp, |lint| {
-                lint.build(fluent::lint::identifier_non_ascii_char).emit();
-            });
+            cx.struct_span_lint(
+                NON_ASCII_IDENTS,
+                sp,
+                fluent::lint::identifier_non_ascii_char,
+                |lint| lint,
+            );
             if check_uncommon_codepoints
                 && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed)
             {
-                cx.struct_span_lint(UNCOMMON_CODEPOINTS, sp, |lint| {
-                    lint.build(fluent::lint::identifier_uncommon_codepoints).emit();
-                })
+                cx.struct_span_lint(
+                    UNCOMMON_CODEPOINTS,
+                    sp,
+                    fluent::lint::identifier_uncommon_codepoints,
+                    |lint| lint,
+                )
             }
         }
 
@@ -216,13 +222,16 @@ impl EarlyLintPass for NonAsciiIdents {
                     .entry(skeleton_sym)
                     .and_modify(|(existing_symbol, existing_span, existing_is_ascii)| {
                         if !*existing_is_ascii || !is_ascii {
-                            cx.struct_span_lint(CONFUSABLE_IDENTS, sp, |lint| {
-                                lint.build(fluent::lint::confusable_identifier_pair)
-                                    .set_arg("existing_sym", *existing_symbol)
-                                    .set_arg("sym", symbol)
-                                    .span_label(*existing_span, fluent::lint::label)
-                                    .emit();
-                            });
+                            cx.struct_span_lint(
+                                CONFUSABLE_IDENTS,
+                                sp,
+                                fluent::lint::confusable_identifier_pair,
+                                |lint| {
+                                    lint.set_arg("existing_sym", *existing_symbol)
+                                        .set_arg("sym", symbol)
+                                        .span_label(*existing_span, fluent::lint::label)
+                                },
+                            );
                         }
                         if *existing_is_ascii && !is_ascii {
                             *existing_symbol = symbol;
@@ -322,22 +331,25 @@ impl EarlyLintPass for NonAsciiIdents {
                 }
 
                 for ((sp, ch_list), script_set) in lint_reports {
-                    cx.struct_span_lint(MIXED_SCRIPT_CONFUSABLES, sp, |lint| {
-                        let mut includes = String::new();
-                        for (idx, ch) in ch_list.into_iter().enumerate() {
-                            if idx != 0 {
-                                includes += ", ";
+                    cx.struct_span_lint(
+                        MIXED_SCRIPT_CONFUSABLES,
+                        sp,
+                        fluent::lint::mixed_script_confusables,
+                        |lint| {
+                            let mut includes = String::new();
+                            for (idx, ch) in ch_list.into_iter().enumerate() {
+                                if idx != 0 {
+                                    includes += ", ";
+                                }
+                                let char_info = format!("'{}' (U+{:04X})", ch, ch as u32);
+                                includes += &char_info;
                             }
-                            let char_info = format!("'{}' (U+{:04X})", ch, ch as u32);
-                            includes += &char_info;
-                        }
-                        lint.build(fluent::lint::mixed_script_confusables)
-                            .set_arg("set", script_set.to_string())
-                            .set_arg("includes", includes)
-                            .note(fluent::lint::includes_note)
-                            .note(fluent::lint::note)
-                            .emit();
-                    });
+                            lint.set_arg("set", script_set.to_string())
+                                .set_arg("includes", includes)
+                                .note(fluent::lint::includes_note)
+                                .note(fluent::lint::note)
+                        },
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index cdad2d2e8f9..9d2a23f2b5f 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -119,21 +119,19 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
         arg_span = expn.call_site;
     }
 
-    cx.struct_span_lint(NON_FMT_PANICS, arg_span, |lint| {
-        let mut l = lint.build(fluent::lint::non_fmt_panic);
-        l.set_arg("name", symbol);
-        l.note(fluent::lint::note);
-        l.note(fluent::lint::more_info_note);
+    cx.struct_span_lint(NON_FMT_PANICS, arg_span, fluent::lint::non_fmt_panic, |lint| {
+        lint.set_arg("name", symbol);
+        lint.note(fluent::lint::note);
+        lint.note(fluent::lint::more_info_note);
         if !is_arg_inside_call(arg_span, span) {
             // No clue where this argument is coming from.
-            l.emit();
-            return;
+            return lint;
         }
         if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
             // A case of `panic!(format!(..))`.
-            l.note(fluent::lint::supports_fmt_note);
+            lint.note(fluent::lint::supports_fmt_note);
             if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
-                l.multipart_suggestion(
+                lint.multipart_suggestion(
                     fluent::lint::supports_fmt_suggestion,
                     vec![
                         (arg_span.until(open.shrink_to_hi()), "".into()),
@@ -180,15 +178,15 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
             };
 
             if suggest_display {
-                l.span_suggestion_verbose(
+                lint.span_suggestion_verbose(
                     arg_span.shrink_to_lo(),
                     fluent::lint::display_suggestion,
                     "\"{}\", ",
                     fmt_applicability,
                 );
             } else if suggest_debug {
-                l.set_arg("ty", ty);
-                l.span_suggestion_verbose(
+                lint.set_arg("ty", ty);
+                lint.span_suggestion_verbose(
                     arg_span.shrink_to_lo(),
                     fluent::lint::debug_suggestion,
                     "\"{:?}\", ",
@@ -198,8 +196,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
 
             if suggest_panic_any {
                 if let Some((open, close, del)) = find_delimiters(cx, span) {
-                    l.set_arg("already_suggested", suggest_display || suggest_debug);
-                    l.multipart_suggestion(
+                    lint.set_arg("already_suggested", suggest_display || suggest_debug);
+                    lint.multipart_suggestion(
                         fluent::lint::panic_suggestion,
                         if del == '(' {
                             vec![(span.until(open), "std::panic::panic_any".into())]
@@ -214,7 +212,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 }
             }
         }
-        l.emit();
+        lint
     });
 }
 
@@ -258,26 +256,30 @@ fn check_panic_str<'tcx>(
                 .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end)))
                 .collect(),
         };
-        cx.struct_span_lint(NON_FMT_PANICS, arg_spans, |lint| {
-            let mut l = lint.build(fluent::lint::non_fmt_panic_unused);
-            l.set_arg("count", n_arguments);
-            l.note(fluent::lint::note);
-            if is_arg_inside_call(arg.span, span) {
-                l.span_suggestion(
-                    arg.span.shrink_to_hi(),
-                    fluent::lint::add_args_suggestion,
-                    ", ...",
-                    Applicability::HasPlaceholders,
-                );
-                l.span_suggestion(
-                    arg.span.shrink_to_lo(),
-                    fluent::lint::add_fmt_suggestion,
-                    "\"{}\", ",
-                    Applicability::MachineApplicable,
-                );
-            }
-            l.emit();
-        });
+        cx.struct_span_lint(
+            NON_FMT_PANICS,
+            arg_spans,
+            fluent::lint::non_fmt_panic_unused,
+            |lint| {
+                lint.set_arg("count", n_arguments);
+                lint.note(fluent::lint::note);
+                if is_arg_inside_call(arg.span, span) {
+                    lint.span_suggestion(
+                        arg.span.shrink_to_hi(),
+                        fluent::lint::add_args_suggestion,
+                        ", ...",
+                        Applicability::HasPlaceholders,
+                    );
+                    lint.span_suggestion(
+                        arg.span.shrink_to_lo(),
+                        fluent::lint::add_fmt_suggestion,
+                        "\"{}\", ",
+                        Applicability::MachineApplicable,
+                    );
+                }
+                lint
+            },
+        );
     } else {
         let brace_spans: Option<Vec<_>> =
             snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| {
@@ -287,20 +289,24 @@ fn check_panic_str<'tcx>(
                     .collect()
             });
         let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2);
-        cx.struct_span_lint(NON_FMT_PANICS, brace_spans.unwrap_or_else(|| vec![span]), |lint| {
-            let mut l = lint.build(fluent::lint::non_fmt_panic_braces);
-            l.set_arg("count", count);
-            l.note(fluent::lint::note);
-            if is_arg_inside_call(arg.span, span) {
-                l.span_suggestion(
-                    arg.span.shrink_to_lo(),
-                    fluent::lint::suggestion,
-                    "\"{}\", ",
-                    Applicability::MachineApplicable,
-                );
-            }
-            l.emit();
-        });
+        cx.struct_span_lint(
+            NON_FMT_PANICS,
+            brace_spans.unwrap_or_else(|| vec![span]),
+            fluent::lint::non_fmt_panic_braces,
+            |lint| {
+                lint.set_arg("count", count);
+                lint.note(fluent::lint::note);
+                if is_arg_inside_call(arg.span, span) {
+                    lint.span_suggestion(
+                        arg.span.shrink_to_lo(),
+                        fluent::lint::suggestion,
+                        "\"{}\", ",
+                        Applicability::MachineApplicable,
+                    );
+                }
+                lint
+            },
+        );
     }
 }
 
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 768ad84838b..9f800e9c8c9 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -136,26 +136,30 @@ impl NonCamelCaseTypes {
         let name = ident.name.as_str();
 
         if !is_camel_case(name) {
-            cx.struct_span_lint(NON_CAMEL_CASE_TYPES, ident.span, |lint| {
-                let mut err = lint.build(fluent::lint::non_camel_case_type);
-                let cc = to_camel_case(name);
-                // We cannot provide meaningful suggestions
-                // if the characters are in the category of "Lowercase Letter".
-                if *name != cc {
-                    err.span_suggestion(
-                        ident.span,
-                        fluent::lint::suggestion,
-                        to_camel_case(name),
-                        Applicability::MaybeIncorrect,
-                    );
-                } else {
-                    err.span_label(ident.span, fluent::lint::label);
-                }
+            cx.struct_span_lint(
+                NON_CAMEL_CASE_TYPES,
+                ident.span,
+                fluent::lint::non_camel_case_type,
+                |lint| {
+                    let cc = to_camel_case(name);
+                    // We cannot provide meaningful suggestions
+                    // if the characters are in the category of "Lowercase Letter".
+                    if *name != cc {
+                        lint.span_suggestion(
+                            ident.span,
+                            fluent::lint::suggestion,
+                            to_camel_case(name),
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else {
+                        lint.span_label(ident.span, fluent::lint::label);
+                    }
 
-                err.set_arg("sort", sort);
-                err.set_arg("name", name);
-                err.emit();
-            })
+                    lint.set_arg("sort", sort);
+                    lint.set_arg("name", name);
+                    lint
+                },
+            )
         }
     }
 }
@@ -280,9 +284,8 @@ impl NonSnakeCase {
         let name = ident.name.as_str();
 
         if !is_snake_case(name) {
-            cx.struct_span_lint(NON_SNAKE_CASE, ident.span, |lint| {
+            cx.struct_span_lint(NON_SNAKE_CASE, ident.span, fluent::lint::non_snake_case, |lint| {
                 let sc = NonSnakeCase::to_snake_case(name);
-                let mut err = lint.build(fluent::lint::non_snake_case);
                 // We cannot provide meaningful suggestions
                 // if the characters are in the category of "Uppercase Letter".
                 if name != sc {
@@ -297,30 +300,30 @@ impl NonSnakeCase {
                             if sc_ident.name.can_be_raw() {
                                 (fluent::lint::rename_or_convert_suggestion, sc_ident.to_string())
                             } else {
-                                err.note(fluent::lint::cannot_convert_note);
+                                lint.note(fluent::lint::cannot_convert_note);
                                 (fluent::lint::rename_suggestion, String::new())
                             }
                         } else {
                             (fluent::lint::convert_suggestion, sc.clone())
                         };
 
-                        err.span_suggestion(
+                        lint.span_suggestion(
                             ident.span,
                             message,
                             suggestion,
                             Applicability::MaybeIncorrect,
                         );
                     } else {
-                        err.help(fluent::lint::help);
+                        lint.help(fluent::lint::help);
                     }
                 } else {
-                    err.span_label(ident.span, fluent::lint::label);
+                    lint.span_label(ident.span, fluent::lint::label);
                 }
 
-                err.set_arg("sort", sort);
-                err.set_arg("name", name);
-                err.set_arg("sc", sc);
-                err.emit();
+                lint.set_arg("sort", sort);
+                lint.set_arg("name", name);
+                lint.set_arg("sc", sc);
+                lint
             });
         }
     }
@@ -478,26 +481,30 @@ impl NonUpperCaseGlobals {
     fn check_upper_case(cx: &LateContext<'_>, sort: &str, ident: &Ident) {
         let name = ident.name.as_str();
         if name.chars().any(|c| c.is_lowercase()) {
-            cx.struct_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, |lint| {
-                let uc = NonSnakeCase::to_snake_case(&name).to_uppercase();
-                let mut err = lint.build(fluent::lint::non_upper_case_global);
-                // We cannot provide meaningful suggestions
-                // if the characters are in the category of "Lowercase Letter".
-                if *name != uc {
-                    err.span_suggestion(
-                        ident.span,
-                        fluent::lint::suggestion,
-                        uc,
-                        Applicability::MaybeIncorrect,
-                    );
-                } else {
-                    err.span_label(ident.span, fluent::lint::label);
-                }
+            cx.struct_span_lint(
+                NON_UPPER_CASE_GLOBALS,
+                ident.span,
+                fluent::lint::non_upper_case_global,
+                |lint| {
+                    let uc = NonSnakeCase::to_snake_case(&name).to_uppercase();
+                    // We cannot provide meaningful suggestions
+                    // if the characters are in the category of "Lowercase Letter".
+                    if *name != uc {
+                        lint.span_suggestion(
+                            ident.span,
+                            fluent::lint::suggestion,
+                            uc,
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else {
+                        lint.span_label(ident.span, fluent::lint::label);
+                    }
 
-                err.set_arg("sort", sort);
-                err.set_arg("name", name);
-                err.emit();
-            })
+                    lint.set_arg("sort", sort);
+                    lint.set_arg("name", name);
+                    lint
+                },
+            )
         }
     }
 }
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
index d1449496d33..9a62afd3caf 100644
--- a/compiler/rustc_lint/src/noop_method_call.rs
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -1,5 +1,4 @@
 use crate::context::LintContext;
-use crate::rustc_middle::ty::TypeVisitable;
 use crate::LateContext;
 use crate::LateLintPass;
 use rustc_errors::fluent;
@@ -46,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
         };
         // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
         // traits and ignore any other method call.
-        let (trait_id, did) = match cx.typeck_results().type_dependent_def(expr.hir_id) {
+        let did = match cx.typeck_results().type_dependent_def(expr.hir_id) {
             // Verify we are dealing with a method/associated function.
             Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) {
                 // Check that we're dealing with a trait method for one of the traits we care about.
@@ -56,21 +55,17 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
                         Some(sym::Borrow | sym::Clone | sym::Deref)
                     ) =>
                 {
-                    (trait_id, did)
+                    did
                 }
                 _ => return,
             },
             _ => return,
         };
-        let substs = cx.typeck_results().node_substs(expr.hir_id);
-        if substs.needs_subst() {
-            // We can't resolve on types that require monomorphization, so we don't handle them if
-            // we need to perform substitution.
-            return;
-        }
-        let param_env = cx.tcx.param_env(trait_id);
+        let substs = cx
+            .tcx
+            .normalize_erasing_regions(cx.param_env, cx.typeck_results().node_substs(expr.hir_id));
         // Resolve the trait method instance.
-        let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) else {
+        let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, substs) else {
             return
         };
         // (Re)check that it implements the noop diagnostic.
@@ -90,13 +85,11 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
         }
         let expr_span = expr.span;
         let span = expr_span.with_lo(receiver.span.hi());
-        cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
-            lint.build(fluent::lint::noop_method_call)
-                .set_arg("method", call.ident.name)
+        cx.struct_span_lint(NOOP_METHOD_CALL, span, fluent::lint::noop_method_call, |lint| {
+            lint.set_arg("method", call.ident.name)
                 .set_arg("receiver_ty", receiver_ty)
                 .span_label(span, fluent::lint::label)
                 .note(fluent::lint::note)
-                .emit();
         });
     }
 }
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
new file mode 100644
index 00000000000..d8ce20db37c
--- /dev/null
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -0,0 +1,156 @@
+use rustc_hir as hir;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_macros::LintDiagnostic;
+use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable};
+use rustc_span::Span;
+use rustc_trait_selection::traits;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
+
+use crate::{LateContext, LateLintPass, LintContext};
+
+declare_lint! {
+    /// The `opaque_hidden_inferred_bound` lint detects cases in which nested
+    /// `impl Trait` in associated type bounds are not written generally enough
+    /// to satisfy the bounds of the associated type.
+    ///
+    /// ### Explanation
+    ///
+    /// This functionality was removed in #97346, but then rolled back in #99860
+    /// because it caused regressions.
+    ///
+    /// We plan on reintroducing this as a hard error, but in the mean time,
+    /// this lint serves to warn and suggest fixes for any use-cases which rely
+    /// on this behavior.
+    ///
+    /// ### Example
+    ///
+    /// ```
+    /// trait Trait {
+    ///     type Assoc: Send;
+    /// }
+    ///
+    /// struct Struct;
+    ///
+    /// impl Trait for Struct {
+    ///     type Assoc = i32;
+    /// }
+    ///
+    /// fn test() -> impl Trait<Assoc = impl Sized> {
+    ///     Struct
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// In this example, `test` declares that the associated type `Assoc` for
+    /// `impl Trait` is `impl Sized`, which does not satisfy the `Send` bound
+    /// on the associated type.
+    ///
+    /// Although the hidden type, `i32` does satisfy this bound, we do not
+    /// consider the return type to be well-formed with this lint. It can be
+    /// fixed by changing `impl Sized` into `impl Sized + Send`.
+    pub OPAQUE_HIDDEN_INFERRED_BOUND,
+    Warn,
+    "detects the use of nested `impl Trait` types in associated type bounds that are not general enough"
+}
+
+declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
+
+impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
+        let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; };
+        let def_id = item.def_id.def_id.to_def_id();
+        cx.tcx.infer_ctxt().enter(|ref infcx| {
+            // For every projection predicate in the opaque type's explicit bounds,
+            // check that the type that we're assigning actually satisfies the bounds
+            // of the associated type.
+            for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) {
+                // Liberate bound regions in the predicate since we
+                // don't actually care about lifetimes in this check.
+                let predicate = cx.tcx.liberate_late_bound_regions(
+                    def_id,
+                    pred.kind(),
+                );
+                let ty::PredicateKind::Projection(proj) = predicate else {
+                    continue;
+                };
+                // Only check types, since those are the only things that may
+                // have opaques in them anyways.
+                let Some(proj_term) = proj.term.ty() else { continue };
+
+                let proj_ty =
+                    cx
+                    .tcx
+                    .mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs);
+                // For every instance of the projection type in the bounds,
+                // replace them with the term we're assigning to the associated
+                // type in our opaque type.
+                let proj_replacer = &mut BottomUpFolder {
+                    tcx: cx.tcx,
+                    ty_op: |ty| if ty == proj_ty { proj_term } else { ty },
+                    lt_op: |lt| lt,
+                    ct_op: |ct| ct,
+                };
+                // For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
+                // e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
+                // with `impl Send: OtherTrait`.
+                for assoc_pred_and_span in cx
+                    .tcx
+                    .bound_explicit_item_bounds(proj.projection_ty.item_def_id)
+                    .transpose_iter()
+                {
+                    let assoc_pred_span = assoc_pred_and_span.0.1;
+                    let assoc_pred = assoc_pred_and_span
+                        .map_bound(|(pred, _)| *pred)
+                        .subst(cx.tcx, &proj.projection_ty.substs)
+                        .fold_with(proj_replacer);
+                    let Ok(assoc_pred) = traits::fully_normalize(infcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred) else {
+                        continue;
+                    };
+                    // If that predicate doesn't hold modulo regions (but passed during type-check),
+                    // then we must've taken advantage of the hack in `project_and_unify_types` where
+                    // we replace opaques with inference vars. Emit a warning!
+                    if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new(
+                        traits::ObligationCause::dummy(),
+                        cx.param_env,
+                        assoc_pred,
+                    )) {
+                        // If it's a trait bound and an opaque that doesn't satisfy it,
+                        // then we can emit a suggestion to add the bound.
+                        let (suggestion, suggest_span) =
+                            match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
+                                (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => (
+                                    format!(" + {}", trait_pred.print_modifiers_and_trait_path()),
+                                    Some(cx.tcx.def_span(def_id).shrink_to_hi()),
+                                ),
+                                _ => (String::new(), None),
+                            };
+                        cx.emit_spanned_lint(
+                            OPAQUE_HIDDEN_INFERRED_BOUND,
+                            pred_span,
+                            OpaqueHiddenInferredBoundLint {
+                                ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)),
+                                proj_ty: proj_term,
+                                assoc_pred_span,
+                                suggestion,
+                                suggest_span,
+                            },
+                        );
+                    }
+                }
+            }
+        });
+    }
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint::opaque_hidden_inferred_bound)]
+struct OpaqueHiddenInferredBoundLint<'tcx> {
+    ty: Ty<'tcx>,
+    proj_ty: Ty<'tcx>,
+    #[label(lint::specifically)]
+    assoc_pred_span: Span,
+    #[suggestion_verbose(applicability = "machine-applicable", code = "{suggestion}")]
+    suggest_span: Option<Span>,
+    suggestion: String,
+}
diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs
index af5e5faf1f5..349399b5964 100644
--- a/compiler/rustc_lint/src/pass_by_value.rs
+++ b/compiler/rustc_lint/src/pass_by_value.rs
@@ -29,18 +29,20 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
                     }
                 }
                 if let Some(t) = path_for_pass_by_value(cx, &inner_ty) {
-                    cx.struct_span_lint(PASS_BY_VALUE, ty.span, |lint| {
-                        lint.build(fluent::lint::pass_by_value)
-                            .set_arg("ty", t.clone())
-                            .span_suggestion(
+                    cx.struct_span_lint(
+                        PASS_BY_VALUE,
+                        ty.span,
+                        fluent::lint::pass_by_value,
+                        |lint| {
+                            lint.set_arg("ty", t.clone()).span_suggestion(
                                 ty.span,
                                 fluent::lint::suggestion,
                                 t,
                                 // Changing type of function argument
                                 Applicability::MaybeIncorrect,
                             )
-                            .emit();
-                    })
+                        },
+                    )
                 }
             }
             _ => {}
@@ -56,7 +58,7 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
                 let path_segment = path.segments.last().unwrap();
                 return Some(format!("{}{}", name, gen_args(cx, path_segment)));
             }
-            Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
+            Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
                 if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
                     if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
                         return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs));
diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs
index 26f41345383..46c84550e9f 100644
--- a/compiler/rustc_lint/src/redundant_semicolon.rs
+++ b/compiler/rustc_lint/src/redundant_semicolon.rs
@@ -48,11 +48,18 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo
             return;
         }
 
-        cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| {
-            lint.build(fluent::lint::redundant_semicolons)
-                .set_arg("multiple", multiple)
-                .span_suggestion(span, fluent::lint::suggestion, "", Applicability::MaybeIncorrect)
-                .emit();
-        });
+        cx.struct_span_lint(
+            REDUNDANT_SEMICOLONS,
+            span,
+            fluent::lint::redundant_semicolons,
+            |lint| {
+                lint.set_arg("multiple", multiple).span_suggestion(
+                    span,
+                    fluent::lint::suggestion,
+                    "",
+                    Applicability::MaybeIncorrect,
+                )
+            },
+        );
     }
 }
diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs
index df1587c5948..078465bdce6 100644
--- a/compiler/rustc_lint/src/traits.rs
+++ b/compiler/rustc_lint/src/traits.rs
@@ -100,15 +100,18 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
                 if trait_predicate.trait_ref.self_ty().is_impl_trait() {
                     continue;
                 }
-                cx.struct_span_lint(DROP_BOUNDS, span, |lint| {
-                    let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
-                        return
-                    };
-                    lint.build(fluent::lint::drop_trait_constraints)
-                        .set_arg("predicate", predicate)
-                        .set_arg("needs_drop", cx.tcx.def_path_str(needs_drop))
-                        .emit();
-                });
+                let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
+                    continue;
+                };
+                cx.struct_span_lint(
+                    DROP_BOUNDS,
+                    span,
+                    fluent::lint::drop_trait_constraints,
+                    |lint| {
+                        lint.set_arg("predicate", predicate)
+                            .set_arg("needs_drop", cx.tcx.def_path_str(needs_drop))
+                    },
+                );
             }
         }
     }
@@ -119,14 +122,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
         };
         for bound in &bounds[..] {
             let def_id = bound.trait_ref.trait_def_id();
-            if cx.tcx.lang_items().drop_trait() == def_id {
-                cx.struct_span_lint(DYN_DROP, bound.span, |lint| {
-                    let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else {
-                        return
-                    };
-                    lint.build(fluent::lint::drop_glue)
-                        .set_arg("needs_drop", cx.tcx.def_path_str(needs_drop))
-                        .emit();
+            if cx.tcx.lang_items().drop_trait() == def_id
+                && let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop)
+            {
+                cx.struct_span_lint(DYN_DROP, bound.span, fluent::lint::drop_glue, |lint| {
+                    lint.set_arg("needs_drop", cx.tcx.def_path_str(needs_drop))
                 });
             }
         }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 4fb6d65a6e9..b6009bd800a 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -144,12 +144,18 @@ fn lint_overflowing_range_endpoint<'tcx>(
     // We can suggest using an inclusive range
     // (`..=`) instead only if it is the `end` that is
     // overflowing and only by 1.
-    if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
-        cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| {
-            let mut err = lint.build(fluent::lint::range_endpoint_out_of_range);
-            err.set_arg("ty", ty);
-            if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
+    if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max
+        && let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span)
+    {
+        cx.struct_span_lint(
+            OVERFLOWING_LITERALS,
+            struct_expr.span,
+            fluent::lint::range_endpoint_out_of_range,
+            |lint| {
                 use ast::{LitIntType, LitKind};
+
+                lint.set_arg("ty", ty);
+
                 // We need to preserve the literal's suffix,
                 // as it may determine typing information.
                 let suffix = match lit.node {
@@ -159,16 +165,17 @@ fn lint_overflowing_range_endpoint<'tcx>(
                     _ => bug!(),
                 };
                 let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
-                err.span_suggestion(
+                lint.span_suggestion(
                     struct_expr.span,
                     fluent::lint::suggestion,
                     suggestion,
                     Applicability::MachineApplicable,
                 );
-                err.emit();
                 overwritten = true;
-            }
-        });
+
+                lint
+            },
+        );
     }
     overwritten
 }
@@ -221,52 +228,58 @@ fn report_bin_hex_error(
     negative: bool,
 ) {
     let size = Integer::from_attr(&cx.tcx, ty).size();
-    cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| {
-        let (t, actually) = match ty {
-            attr::IntType::SignedInt(t) => {
-                let actually = if negative {
-                    -(size.sign_extend(val) as i128)
-                } else {
-                    size.sign_extend(val) as i128
-                };
-                (t.name_str(), actually.to_string())
-            }
-            attr::IntType::UnsignedInt(t) => {
-                let actually = size.truncate(val);
-                (t.name_str(), actually.to_string())
-            }
-        };
-        let mut err = lint.build(fluent::lint::overflowing_bin_hex);
-        if negative {
-            // If the value is negative,
-            // emits a note about the value itself, apart from the literal.
-            err.note(fluent::lint::negative_note);
-            err.note(fluent::lint::negative_becomes_note);
-        } else {
-            err.note(fluent::lint::positive_note);
-        }
-        if let Some(sugg_ty) =
-            get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative)
-        {
-            err.set_arg("suggestion_ty", sugg_ty);
-            if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
-                let (sans_suffix, _) = repr_str.split_at(pos);
-                err.span_suggestion(
-                    expr.span,
-                    fluent::lint::suggestion,
-                    format!("{}{}", sans_suffix, sugg_ty),
-                    Applicability::MachineApplicable,
-                );
+    cx.struct_span_lint(
+        OVERFLOWING_LITERALS,
+        expr.span,
+        fluent::lint::overflowing_bin_hex,
+        |lint| {
+            let (t, actually) = match ty {
+                attr::IntType::SignedInt(t) => {
+                    let actually = if negative {
+                        -(size.sign_extend(val) as i128)
+                    } else {
+                        size.sign_extend(val) as i128
+                    };
+                    (t.name_str(), actually.to_string())
+                }
+                attr::IntType::UnsignedInt(t) => {
+                    let actually = size.truncate(val);
+                    (t.name_str(), actually.to_string())
+                }
+            };
+
+            if negative {
+                // If the value is negative,
+                // emits a note about the value itself, apart from the literal.
+                lint.note(fluent::lint::negative_note);
+                lint.note(fluent::lint::negative_becomes_note);
             } else {
-                err.help(fluent::lint::help);
+                lint.note(fluent::lint::positive_note);
             }
-        }
-        err.set_arg("ty", t);
-        err.set_arg("lit", repr_str);
-        err.set_arg("dec", val);
-        err.set_arg("actually", actually);
-        err.emit();
-    });
+            if let Some(sugg_ty) =
+                get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative)
+            {
+                lint.set_arg("suggestion_ty", sugg_ty);
+                if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
+                    let (sans_suffix, _) = repr_str.split_at(pos);
+                    lint.span_suggestion(
+                        expr.span,
+                        fluent::lint::suggestion,
+                        format!("{}{}", sans_suffix, sugg_ty),
+                        Applicability::MachineApplicable,
+                    );
+                } else {
+                    lint.help(fluent::lint::help);
+                }
+            }
+            lint.set_arg("ty", t)
+                .set_arg("lit", repr_str)
+                .set_arg("dec", val)
+                .set_arg("actually", actually);
+
+            lint
+        },
+    );
 }
 
 // This function finds the next fitting type and generates a suggestion string.
@@ -349,26 +362,27 @@ fn lint_int_literal<'tcx>(
             return;
         }
 
-        cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
-            let mut err = lint.build(fluent::lint::overflowing_int);
-            err.set_arg("ty", t.name_str());
-            err.set_arg(
-                "lit",
-                cx.sess()
-                    .source_map()
-                    .span_to_snippet(lit.span)
-                    .expect("must get snippet from literal"),
-            );
-            err.set_arg("min", min);
-            err.set_arg("max", max);
-            err.note(fluent::lint::note);
+        cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, fluent::lint::overflowing_int, |lint| {
+            lint.set_arg("ty", t.name_str())
+                .set_arg(
+                    "lit",
+                    cx.sess()
+                        .source_map()
+                        .span_to_snippet(lit.span)
+                        .expect("must get snippet from literal"),
+                )
+                .set_arg("min", min)
+                .set_arg("max", max)
+                .note(fluent::lint::note);
+
             if let Some(sugg_ty) =
                 get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
             {
-                err.set_arg("suggestion_ty", sugg_ty);
-                err.help(fluent::lint::help);
+                lint.set_arg("suggestion_ty", sugg_ty);
+                lint.help(fluent::lint::help);
             }
-            err.emit();
+
+            lint
         });
     }
 }
@@ -393,16 +407,19 @@ fn lint_uint_literal<'tcx>(
             match par_e.kind {
                 hir::ExprKind::Cast(..) => {
                     if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
-                        cx.struct_span_lint(OVERFLOWING_LITERALS, par_e.span, |lint| {
-                            lint.build(fluent::lint::only_cast_u8_to_char)
-                                .span_suggestion(
+                        cx.struct_span_lint(
+                            OVERFLOWING_LITERALS,
+                            par_e.span,
+                            fluent::lint::only_cast_u8_to_char,
+                            |lint| {
+                                lint.span_suggestion(
                                     par_e.span,
                                     fluent::lint::suggestion,
                                     format!("'\\u{{{:X}}}'", lit_val),
                                     Applicability::MachineApplicable,
                                 )
-                                .emit();
-                        });
+                            },
+                        );
                         return;
                     }
                 }
@@ -424,9 +441,8 @@ fn lint_uint_literal<'tcx>(
             );
             return;
         }
-        cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
-            lint.build(fluent::lint::overflowing_uint)
-                .set_arg("ty", t.name_str())
+        cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, fluent::lint::overflowing_uint, |lint| {
+            lint.set_arg("ty", t.name_str())
                 .set_arg(
                     "lit",
                     cx.sess()
@@ -437,7 +453,6 @@ fn lint_uint_literal<'tcx>(
                 .set_arg("min", min)
                 .set_arg("max", max)
                 .note(fluent::lint::note)
-                .emit();
         });
     }
 }
@@ -467,19 +482,22 @@ fn lint_literal<'tcx>(
                 _ => bug!(),
             };
             if is_infinite == Ok(true) {
-                cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| {
-                    lint.build(fluent::lint::overflowing_literal)
-                        .set_arg("ty", t.name_str())
-                        .set_arg(
-                            "lit",
-                            cx.sess()
-                                .source_map()
-                                .span_to_snippet(lit.span)
-                                .expect("must get snippet from literal"),
-                        )
-                        .note(fluent::lint::note)
-                        .emit();
-                });
+                cx.struct_span_lint(
+                    OVERFLOWING_LITERALS,
+                    e.span,
+                    fluent::lint::overflowing_literal,
+                    |lint| {
+                        lint.set_arg("ty", t.name_str())
+                            .set_arg(
+                                "lit",
+                                cx.sess()
+                                    .source_map()
+                                    .span_to_snippet(lit.span)
+                                    .expect("must get snippet from literal"),
+                            )
+                            .note(fluent::lint::note)
+                    },
+                );
             }
         }
         _ => {}
@@ -497,9 +515,12 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
             }
             hir::ExprKind::Binary(binop, ref l, ref r) => {
                 if is_comparison(binop) && !check_limits(cx, binop, &l, &r) {
-                    cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| {
-                        lint.build(fluent::lint::unused_comparisons).emit();
-                    });
+                    cx.struct_span_lint(
+                        UNUSED_COMPARISONS,
+                        e.span,
+                        fluent::lint::unused_comparisons,
+                        |lint| lint,
+                    );
                 }
             }
             hir::ExprKind::Lit(ref lit) => lint_literal(cx, self, e, lit),
@@ -1150,25 +1171,24 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             CItemKind::Definition => IMPROPER_CTYPES_DEFINITIONS,
         };
 
-        self.cx.struct_span_lint(lint, sp, |lint| {
+        self.cx.struct_span_lint(lint, sp, fluent::lint::improper_ctypes, |lint| {
             let item_description = match self.mode {
                 CItemKind::Declaration => "block",
                 CItemKind::Definition => "fn",
             };
-            let mut diag = lint.build(fluent::lint::improper_ctypes);
-            diag.set_arg("ty", ty);
-            diag.set_arg("desc", item_description);
-            diag.span_label(sp, fluent::lint::label);
+            lint.set_arg("ty", ty);
+            lint.set_arg("desc", item_description);
+            lint.span_label(sp, fluent::lint::label);
             if let Some(help) = help {
-                diag.help(help);
+                lint.help(help);
             }
-            diag.note(note);
+            lint.note(note);
             if let ty::Adt(def, _) = ty.kind() {
                 if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) {
-                    diag.span_note(sp, fluent::lint::note);
+                    lint.span_note(sp, fluent::lint::note);
                 }
             }
-            diag.emit();
+            lint
         });
     }
 
@@ -1381,11 +1401,8 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
                 cx.struct_span_lint(
                     VARIANT_SIZE_DIFFERENCES,
                     enum_definition.variants[largest_index].span,
-                    |lint| {
-                        lint.build(fluent::lint::variant_size_differences)
-                            .set_arg("largest", largest)
-                            .emit();
-                    },
+                    fluent::lint::variant_size_differences,
+                    |lint| lint.set_arg("largest", largest),
                 );
             }
         }
@@ -1493,25 +1510,16 @@ impl InvalidAtomicOrdering {
 
     fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) {
         if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store])
-            && let Some((ordering_arg, invalid_ordering)) = match method {
-                sym::load => Some((&args[0], sym::Release)),
-                sym::store => Some((&args[1], sym::Acquire)),
+            && let Some((ordering_arg, invalid_ordering, msg)) = match method {
+                sym::load => Some((&args[0], sym::Release, fluent::lint::atomic_ordering_load)),
+                sym::store => Some((&args[1], sym::Acquire, fluent::lint::atomic_ordering_store)),
                 _ => None,
             }
             && let Some(ordering) = Self::match_ordering(cx, ordering_arg)
             && (ordering == invalid_ordering || ordering == sym::AcqRel)
         {
-            cx.struct_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, |diag| {
-                if method == sym::load {
-                    diag.build(fluent::lint::atomic_ordering_load)
-                        .help(fluent::lint::help)
-                        .emit()
-                } else {
-                    debug_assert_eq!(method, sym::store);
-                    diag.build(fluent::lint::atomic_ordering_store)
-                        .help(fluent::lint::help)
-                        .emit();
-                }
+            cx.struct_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, msg, |lint| {
+                lint.help(fluent::lint::help)
             });
         }
     }
@@ -1523,10 +1531,9 @@ impl InvalidAtomicOrdering {
             && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::fence | sym::compiler_fence))
             && Self::match_ordering(cx, &args[0]) == Some(sym::Relaxed)
         {
-            cx.struct_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, |diag| {
-                diag.build(fluent::lint::atomic_ordering_fence)
+            cx.struct_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, fluent::lint::atomic_ordering_fence, |lint| {
+                lint
                     .help(fluent::lint::help)
-                    .emit();
             });
         }
     }
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 3d426ecbfcb..787c9518b50 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -154,9 +154,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
         };
 
         if let Some(must_use_op) = must_use_op {
-            cx.struct_span_lint(UNUSED_MUST_USE, expr.span, |lint| {
-                lint.build(fluent::lint::unused_op)
-                    .set_arg("op", must_use_op)
+            cx.struct_span_lint(UNUSED_MUST_USE, expr.span, fluent::lint::unused_op, |lint| {
+                lint.set_arg("op", must_use_op)
                     .span_label(expr.span, fluent::lint::label)
                     .span_suggestion_verbose(
                         expr.span.shrink_to_lo(),
@@ -164,14 +163,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                         "let _ = ",
                         Applicability::MachineApplicable,
                     )
-                    .emit();
             });
             op_warned = true;
         }
 
         if !(type_permits_lack_of_use || fn_warned || op_warned) {
-            cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| {
-                lint.build(fluent::lint::unused_result).set_arg("ty", ty).emit();
+            cx.struct_span_lint(UNUSED_RESULTS, s.span, fluent::lint::unused_result, |lint| {
+                lint.set_arg("ty", ty)
             });
         }
 
@@ -267,29 +265,35 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                     }
                 },
                 ty::Closure(..) => {
-                    cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
-                        // FIXME(davidtwco): this isn't properly translatable because of the
-                        // pre/post strings
-                        lint.build(fluent::lint::unused_closure)
-                            .set_arg("count", plural_len)
-                            .set_arg("pre", descr_pre)
-                            .set_arg("post", descr_post)
-                            .note(fluent::lint::note)
-                            .emit();
-                    });
+                    cx.struct_span_lint(
+                        UNUSED_MUST_USE,
+                        span,
+                        fluent::lint::unused_closure,
+                        |lint| {
+                            // FIXME(davidtwco): this isn't properly translatable because of the
+                            // pre/post strings
+                            lint.set_arg("count", plural_len)
+                                .set_arg("pre", descr_pre)
+                                .set_arg("post", descr_post)
+                                .note(fluent::lint::note)
+                        },
+                    );
                     true
                 }
                 ty::Generator(..) => {
-                    cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
-                        // FIXME(davidtwco): this isn't properly translatable because of the
-                        // pre/post strings
-                        lint.build(fluent::lint::unused_generator)
-                            .set_arg("count", plural_len)
-                            .set_arg("pre", descr_pre)
-                            .set_arg("post", descr_post)
-                            .note(fluent::lint::note)
-                            .emit();
-                    });
+                    cx.struct_span_lint(
+                        UNUSED_MUST_USE,
+                        span,
+                        fluent::lint::unused_generator,
+                        |lint| {
+                            // FIXME(davidtwco): this isn't properly translatable because of the
+                            // pre/post strings
+                            lint.set_arg("count", plural_len)
+                                .set_arg("pre", descr_pre)
+                                .set_arg("post", descr_post)
+                                .note(fluent::lint::note)
+                        },
+                    );
                     true
                 }
                 _ => false,
@@ -309,18 +313,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
             descr_post_path: &str,
         ) -> bool {
             if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) {
-                cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| {
+                cx.struct_span_lint(UNUSED_MUST_USE, span, fluent::lint::unused_def, |lint| {
                     // FIXME(davidtwco): this isn't properly translatable because of the pre/post
                     // strings
-                    let mut err = lint.build(fluent::lint::unused_def);
-                    err.set_arg("pre", descr_pre_path);
-                    err.set_arg("post", descr_post_path);
-                    err.set_arg("def", cx.tcx.def_path_str(def_id));
+                    lint.set_arg("pre", descr_pre_path);
+                    lint.set_arg("post", descr_post_path);
+                    lint.set_arg("def", cx.tcx.def_path_str(def_id));
                     // check for #[must_use = "..."]
                     if let Some(note) = attr.value_str() {
-                        err.note(note.as_str());
+                        lint.note(note.as_str());
                     }
-                    err.emit();
+                    lint
                 });
                 true
             } else {
@@ -357,25 +360,34 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
     fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
         if let hir::StmtKind::Semi(expr) = s.kind {
             if let hir::ExprKind::Path(_) = expr.kind {
-                cx.struct_span_lint(PATH_STATEMENTS, s.span, |lint| {
-                    let ty = cx.typeck_results().expr_ty(expr);
-                    if ty.needs_drop(cx.tcx, cx.param_env) {
-                        let mut lint = lint.build(fluent::lint::path_statement_drop);
-                        if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) {
-                            lint.span_suggestion(
-                                s.span,
-                                fluent::lint::suggestion,
-                                format!("drop({});", snippet),
-                                Applicability::MachineApplicable,
-                            );
-                        } else {
-                            lint.span_help(s.span, fluent::lint::suggestion);
-                        }
-                        lint.emit();
-                    } else {
-                        lint.build(fluent::lint::path_statement_no_effect).emit();
-                    }
-                });
+                let ty = cx.typeck_results().expr_ty(expr);
+                if ty.needs_drop(cx.tcx, cx.param_env) {
+                    cx.struct_span_lint(
+                        PATH_STATEMENTS,
+                        s.span,
+                        fluent::lint::path_statement_drop,
+                        |lint| {
+                            if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) {
+                                lint.span_suggestion(
+                                    s.span,
+                                    fluent::lint::suggestion,
+                                    format!("drop({});", snippet),
+                                    Applicability::MachineApplicable,
+                                );
+                            } else {
+                                lint.span_help(s.span, fluent::lint::suggestion);
+                            }
+                            lint
+                        },
+                    );
+                } else {
+                    cx.struct_span_lint(
+                        PATH_STATEMENTS,
+                        s.span,
+                        fluent::lint::path_statement_no_effect,
+                        |lint| lint,
+                    );
+                }
             }
         }
     }
@@ -545,22 +557,21 @@ trait UnusedDelimLint {
         } else {
             MultiSpan::from(value_span)
         };
-        cx.struct_span_lint(self.lint(), primary_span, |lint| {
-            let mut db = lint.build(fluent::lint::unused_delim);
-            db.set_arg("delim", Self::DELIM_STR);
-            db.set_arg("item", msg);
+        cx.struct_span_lint(self.lint(), primary_span, fluent::lint::unused_delim, |lint| {
+            lint.set_arg("delim", Self::DELIM_STR);
+            lint.set_arg("item", msg);
             if let Some((lo, hi)) = spans {
                 let replacement = vec![
                     (lo, if keep_space.0 { " ".into() } else { "".into() }),
                     (hi, if keep_space.1 { " ".into() } else { "".into() }),
                 ];
-                db.multipart_suggestion(
+                lint.multipart_suggestion(
                     fluent::lint::suggestion,
                     replacement,
                     Applicability::MachineApplicable,
                 );
             }
-            db.emit();
+            lint
         });
     }
 
@@ -1128,9 +1139,12 @@ impl UnusedImportBraces {
                 ast::UseTreeKind::Nested(_) => return,
             };
 
-            cx.struct_span_lint(UNUSED_IMPORT_BRACES, item.span, |lint| {
-                lint.build(fluent::lint::unused_import_braces).set_arg("node", node_name).emit();
-            });
+            cx.struct_span_lint(
+                UNUSED_IMPORT_BRACES,
+                item.span,
+                fluent::lint::unused_import_braces,
+                |lint| lint.set_arg("node", node_name),
+            );
         }
     }
 }
@@ -1179,15 +1193,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
 
         for adj in cx.typeck_results().expr_adjustments(e) {
             if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind {
-                cx.struct_span_lint(UNUSED_ALLOCATION, e.span, |lint| {
-                    lint.build(match m {
+                cx.struct_span_lint(
+                    UNUSED_ALLOCATION,
+                    e.span,
+                    match m {
                         adjustment::AutoBorrowMutability::Not => fluent::lint::unused_allocation,
                         adjustment::AutoBorrowMutability::Mut { .. } => {
                             fluent::lint::unused_allocation_mut
                         }
-                    })
-                    .emit();
-                });
+                    },
+                    |lint| lint,
+                );
             }
         }
     }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 11b2d057a07..cbe7afc8e55 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -92,7 +92,7 @@ pub enum LintExpectationId {
     /// stable and can be cached. The additional index ensures that nodes with
     /// several expectations can correctly match diagnostics to the individual
     /// expectation.
-    Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16> },
+    Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16>, attr_id: Option<AttrId> },
 }
 
 impl LintExpectationId {
@@ -116,13 +116,31 @@ impl LintExpectationId {
 
         *lint_index = new_lint_index
     }
+
+    /// Prepares the id for hashing. Removes references to the ast.
+    /// Should only be called when the id is stable.
+    pub fn normalize(self) -> Self {
+        match self {
+            Self::Stable { hir_id, attr_index, lint_index, .. } => {
+                Self::Stable { hir_id, attr_index, lint_index, attr_id: None }
+            }
+            Self::Unstable { .. } => {
+                unreachable!("`normalize` called when `ExpectationId` is unstable")
+            }
+        }
+    }
 }
 
 impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId {
     #[inline]
     fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
         match self {
-            LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
+            LintExpectationId::Stable {
+                hir_id,
+                attr_index,
+                lint_index: Some(lint_index),
+                attr_id: _,
+            } => {
                 hir_id.hash_stable(hcx, hasher);
                 attr_index.hash_stable(hcx, hasher);
                 lint_index.hash_stable(hcx, hasher);
@@ -142,9 +160,12 @@ impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectation
     #[inline]
     fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
         match self {
-            LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
-                (*hir_id, *attr_index, *lint_index)
-            }
+            LintExpectationId::Stable {
+                hir_id,
+                attr_index,
+                lint_index: Some(lint_index),
+                attr_id: _,
+            } => (*hir_id, *attr_index, *lint_index),
             _ => {
                 unreachable!("HashStable should only be called for a filled `LintExpectationId`")
             }
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index b9a283552f7..83040a652b1 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -36,7 +36,7 @@ impl<'a> DiagnosticDerive<'a> {
                     span_err(builder.span, "diagnostic slug not specified")
                         .help(&format!(
                             "specify the slug as the first argument to the `#[diag(...)]` \
-                            attribute, such as `#[diag(typeck::example_error)]`",
+                            attribute, such as `#[diag(hir_analysis::example_error)]`",
                         ))
                         .emit();
                     return DiagnosticDeriveError::ErrorHandled.to_compile_error();
@@ -96,38 +96,43 @@ impl<'a> LintDiagnosticDerive<'a> {
             let body = builder.body(&variant);
 
             let diag = &builder.parent.diag;
-            let init = match builder.slug.value_ref() {
+
+            quote! {
+                #preamble
+                #body
+                #diag
+            }
+        });
+
+        let msg = builder.each_variant(&mut structure, |mut builder, variant| {
+            // HACK(wafflelapkin): initialize slug (???)
+            let _preamble = builder.preamble(&variant);
+
+            match builder.slug.value_ref() {
                 None => {
                     span_err(builder.span, "diagnostic slug not specified")
                         .help(&format!(
                             "specify the slug as the first argument to the attribute, such as \
-                             `#[diag(typeck::example_error)]`",
+                            `#[diag(compiletest::example)]`",
                         ))
                         .emit();
                     return DiagnosticDeriveError::ErrorHandled.to_compile_error();
                 }
-                Some(slug) => {
-                    quote! {
-                        let mut #diag = #diag.build(rustc_errors::fluent::#slug);
-                    }
-                }
-            };
-
-            quote! {
-                #init
-                #preamble
-                #body
-                #diag.emit();
+                Some(slug) => quote! { rustc_errors::fluent::#slug.into() },
             }
         });
 
         let diag = &builder.diag;
         structure.gen_impl(quote! {
             gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self {
-                fn decorate_lint(self, #diag: rustc_errors::LintDiagnosticBuilder<'__a, ()>) {
+                fn decorate_lint<'__b>(self, #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>) -> &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> {
                     use rustc_errors::IntoDiagnosticArg;
                     #implementation
                 }
+
+                fn msg(&self) -> rustc_errors::DiagnosticMessage {
+                    #msg
+                }
             }
         })
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index dede1b2122a..466da175810 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -223,6 +223,15 @@ provide! { tcx, def_id, other, cdata,
     fn_arg_names => { table }
     generator_kind => { table }
     trait_def => { table }
+    collect_trait_impl_trait_tys => {
+        Ok(cdata
+            .root
+            .tables
+            .trait_impl_trait_tys
+            .get(cdata, def_id.index)
+            .map(|lazy| lazy.decode((cdata, tcx)))
+            .process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id)))
+     }
 
     visibility => { cdata.get_visibility(def_id.index) }
     adt_def => { cdata.get_adt_def(def_id.index, tcx) }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7cf00ca41fe..1a7a3c65c3b 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1059,6 +1059,34 @@ fn should_encode_const(def_kind: DefKind) -> bool {
     }
 }
 
+fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
+    if tcx.def_kind(def_id) != DefKind::AssocFn {
+        return false;
+    }
+
+    let Some(item) = tcx.opt_associated_item(def_id) else { return false; };
+    if item.container != ty::AssocItemContainer::ImplContainer {
+        return false;
+    }
+
+    let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
+
+    // FIXME(RPITIT): This does a somewhat manual walk through the signature
+    // of the trait fn to look for any RPITITs, but that's kinda doing a lot
+    // of work. We can probably remove this when we refactor RPITITs to be
+    // associated types.
+    tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| {
+        if let ty::GenericArgKind::Type(ty) = arg.unpack()
+            && let ty::Projection(data) = ty.kind()
+            && tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder
+        {
+            true
+        } else {
+            false
+        }
+    })
+}
+
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_attrs(&mut self, def_id: LocalDefId) {
         let mut attrs = self
@@ -1128,6 +1156,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if let DefKind::Trait | DefKind::TraitAlias = def_kind {
                 record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
             }
+            if should_encode_trait_impl_trait_tys(tcx, def_id)
+                && let Ok(table) = self.tcx.collect_trait_impl_trait_tys(def_id)
+            {
+                record!(self.tables.trait_impl_trait_tys[def_id] <- table);
+            }
         }
         let inherent_impls = tcx.crate_inherent_impls(());
         for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 748b3afec37..6d7345570af 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -1,6 +1,7 @@
 use crate::creader::CrateMetadataRef;
 use decoder::Metadata;
 use def_path_hash_map::DefPathHashMapRef;
+use rustc_data_structures::fx::FxHashMap;
 use table::TableBuilder;
 
 use rustc_ast as ast;
@@ -399,6 +400,8 @@ define_tables! {
     macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>,
     proc_macro: Table<DefIndex, MacroKind>,
     module_reexports: Table<DefIndex, LazyArray<ModChild>>,
+
+    trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>,
 }
 
 #[derive(TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index cca17a4eccd..de916ea8c49 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -12,8 +12,6 @@ chalk-ir = "0.80.0"
 either = "1.5.0"
 gsgdt = "0.1.2"
 polonius-engine = "0.13.0"
-rand = "0.8.4"
-rand_xoshiro = "0.6.0"
 rustc_apfloat = { path = "../rustc_apfloat" }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 40b9d73db94..6b556826918 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -62,7 +62,7 @@ use crate::ty::TyCtxt;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_hir::definitions::DefPathHash;
-use rustc_hir::{HirId, OwnerId};
+use rustc_hir::{HirId, ItemLocalId, OwnerId};
 use rustc_query_system::dep_graph::FingerprintStyle;
 use rustc_span::symbol::Symbol;
 use std::hash::Hash;
@@ -194,7 +194,7 @@ impl DepNodeExt for DepNode {
         let kind = dep_kind_from_label_string(label)?;
 
         match tcx.fingerprint_style(kind) {
-            FingerprintStyle::Opaque => Err(()),
+            FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()),
             FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
             FingerprintStyle::DefPathHash => {
                 Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind))
@@ -344,7 +344,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
     #[inline(always)]
     fn fingerprint_style() -> FingerprintStyle {
-        FingerprintStyle::Opaque
+        FingerprintStyle::HirId
     }
 
     // We actually would not need to specialize the implementation of this
@@ -353,10 +353,36 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
     #[inline(always)]
     fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
         let HirId { owner, local_id } = *self;
-
         let def_path_hash = tcx.def_path_hash(owner.to_def_id());
-        let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into());
+        Fingerprint::new(
+            // `owner` is local, so is completely defined by the local hash
+            def_path_hash.local_hash(),
+            local_id.as_u32().into(),
+        )
+    }
 
-        def_path_hash.0.combine(local_id)
+    #[inline(always)]
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+        let HirId { owner, local_id } = *self;
+        format!("{}.{}", tcx.def_path_str(owner.to_def_id()), local_id.as_u32())
+    }
+
+    #[inline(always)]
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
+            let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value();
+            let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
+            let def_id = tcx
+                .def_path_hash_to_def_id(def_path_hash, &mut || {
+                    panic!("Failed to extract HirId: {:?} {}", dep_node.kind, dep_node.hash)
+                })
+                .expect_local();
+            let local_id = local_id
+                .try_into()
+                .unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id));
+            Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
+        } else {
+            None
+        }
     }
 }
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index a4ceb494569..e69cb546d15 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -48,3 +48,10 @@ pub struct LimitInvalid<'a> {
     pub value_span: Span,
     pub error_str: &'a str,
 }
+
+#[derive(Diagnostic)]
+#[diag(middle::const_eval_non_int)]
+pub struct ConstEvalNonIntError {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index b5f7b26ea7a..b78c3f85596 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -14,7 +14,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::hir::nested_filter;
 use rustc_span::def_id::StableCrateId;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
 
 #[inline]
@@ -61,7 +61,7 @@ pub struct ParentHirIterator<'hir> {
 }
 
 impl<'hir> Iterator for ParentHirIterator<'hir> {
-    type Item = (HirId, Node<'hir>);
+    type Item = HirId;
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.current_id == CRATE_HIR_ID {
@@ -77,10 +77,7 @@ impl<'hir> Iterator for ParentHirIterator<'hir> {
             }
 
             self.current_id = parent_id;
-            if let Some(node) = self.map.find(parent_id) {
-                return Some((parent_id, node));
-            }
-            // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`.
+            return Some(parent_id);
         }
     }
 }
@@ -393,8 +390,8 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId {
-        for (parent, _) in self.parent_iter(hir_id) {
-            if let Some(body) = self.find(parent).map(associated_body).flatten() {
+        for (_, node) in self.parent_iter(hir_id) {
+            if let Some(body) = associated_body(node) {
                 return self.body_owner_def_id(body);
             }
         }
@@ -635,13 +632,20 @@ impl<'hir> Map<'hir> {
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
     /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
     #[inline]
-    pub fn parent_iter(self, current_id: HirId) -> ParentHirIterator<'hir> {
+    pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator<Item = HirId> + 'hir {
         ParentHirIterator { current_id, map: self }
     }
 
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
     /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
     #[inline]
+    pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
+        self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?)))
+    }
+
+    /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
+    /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
+    #[inline]
     pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> {
         ParentOwnerIterator { current_id, map: self }
     }
@@ -937,9 +941,19 @@ impl<'hir> Map<'hir> {
 
         let span = match self.find(hir_id)? {
             // Function-like.
-            Node::Item(Item { kind: ItemKind::Fn(sig, ..), .. })
-            | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, ..), .. })
-            | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, ..), .. }) => sig.span,
+            Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
+            | Node::TraitItem(TraitItem {
+                kind: TraitItemKind::Fn(sig, ..),
+                span: outer_span,
+                ..
+            })
+            | Node::ImplItem(ImplItem {
+                kind: ImplItemKind::Fn(sig, ..), span: outer_span, ..
+            }) => {
+                // Ensure that the returned span has the item's SyntaxContext, and not the
+                // SyntaxContext of the visibility.
+                sig.span.find_ancestor_in_same_ctxt(*outer_span).unwrap_or(*outer_span)
+            }
             // Constants and Statics.
             Node::Item(Item {
                 kind:
@@ -981,7 +995,11 @@ impl<'hir> Map<'hir> {
             }
             // Other cases.
             Node::Item(item) => match &item.kind {
-                ItemKind::Use(path, _) => path.span,
+                ItemKind::Use(path, _) => {
+                    // Ensure that the returned span has the item's SyntaxContext, and not the
+                    // SyntaxContext of the path.
+                    path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span)
+                }
                 _ => named_span(item.span, item.ident, item.kind.generics()),
             },
             Node::Variant(variant) => named_span(variant.span, variant.ident, None),
@@ -991,11 +1009,17 @@ impl<'hir> Map<'hir> {
                 _ => named_span(item.span, item.ident, None),
             },
             Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)),
-            Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), .. }) => {
-                *fn_decl_span
+            Node::Expr(Expr {
+                kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
+                span,
+                ..
+            }) => {
+                // Ensure that the returned span has the item's SyntaxContext.
+                fn_decl_span.find_ancestor_in_same_ctxt(*span).unwrap_or(*span)
             }
             _ => self.span_with_body(hir_id),
         };
+        debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt());
         Some(span)
     }
 
@@ -1131,7 +1155,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
                 .filter_map(|(def_id, info)| {
                     let _ = info.as_owner()?;
                     let def_path_hash = definitions.def_path_hash(def_id);
-                    let span = resolutions.source_span[def_id];
+                    let span = resolutions.source_span.get(def_id).unwrap_or(&DUMMY_SP);
                     debug_assert_eq!(span.parent(), None);
                     Some((def_path_hash, span))
                 })
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 2f45222de47..d95c5cbd654 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -1,20 +1,20 @@
 use std::cmp;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_errors::{Diagnostic, DiagnosticId, LintDiagnosticBuilder, MultiSpan};
-use rustc_hir::HirId;
-use rustc_index::vec::IndexVec;
-use rustc_query_system::ich::StableHashingContext;
+use rustc_data_structures::sorted_map::SortedMap;
+use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, MultiSpan};
+use rustc_hir::{HirId, ItemLocalId};
 use rustc_session::lint::{
     builtin::{self, FORBIDDEN_LINT_GROUPS},
-    FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId,
+    FutureIncompatibilityReason, Level, Lint, LintId,
 };
 use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::{DesugaringKind, ExpnKind};
 use rustc_span::{symbol, Span, Symbol, DUMMY_SP};
 
+use crate::ty::TyCtxt;
+
 /// How a lint level was set.
 #[derive(Clone, Copy, PartialEq, Eq, HashStable, Debug)]
 pub enum LintLevelSource {
@@ -23,7 +23,12 @@ pub enum LintLevelSource {
     Default,
 
     /// Lint level was set by an attribute.
-    Node(Symbol, Span, Option<Symbol> /* RFC 2383 reason */),
+    Node {
+        name: Symbol,
+        span: Span,
+        /// RFC 2383 reason
+        reason: Option<Symbol>,
+    },
 
     /// Lint level was set by a command-line flag.
     /// The provided `Level` is the level specified on the command line.
@@ -35,7 +40,7 @@ impl LintLevelSource {
     pub fn name(&self) -> Symbol {
         match *self {
             LintLevelSource::Default => symbol::kw::Default,
-            LintLevelSource::Node(name, _, _) => name,
+            LintLevelSource::Node { name, .. } => name,
             LintLevelSource::CommandLine(name, _) => name,
         }
     }
@@ -43,7 +48,7 @@ impl LintLevelSource {
     pub fn span(&self) -> Span {
         match *self {
             LintLevelSource::Default => DUMMY_SP,
-            LintLevelSource::Node(_, span, _) => span,
+            LintLevelSource::Node { span, .. } => span,
             LintLevelSource::CommandLine(_, _) => DUMMY_SP,
         }
     }
@@ -52,145 +57,137 @@ impl LintLevelSource {
 /// A tuple of a lint level and its source.
 pub type LevelAndSource = (Level, LintLevelSource);
 
-#[derive(Debug, HashStable)]
-pub struct LintLevelSets {
-    pub list: IndexVec<LintStackIndex, LintSet>,
-    pub lint_cap: Level,
-}
-
-rustc_index::newtype_index! {
-    #[derive(HashStable)]
-    pub struct LintStackIndex {
-        const COMMAND_LINE = 0,
-    }
-}
-
-#[derive(Debug, HashStable)]
-pub struct LintSet {
-    // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
-    // flag.
-    pub specs: FxHashMap<LintId, LevelAndSource>,
-
-    pub parent: LintStackIndex,
+/// Return type for the `shallow_lint_levels_on` query.
+///
+/// This map represents the set of allowed lints and allowance levels given
+/// by the attributes for *a single HirId*.
+#[derive(Default, Debug, HashStable)]
+pub struct ShallowLintLevelMap {
+    pub specs: SortedMap<ItemLocalId, FxHashMap<LintId, LevelAndSource>>,
 }
 
-impl LintLevelSets {
-    pub fn new() -> Self {
-        LintLevelSets { list: IndexVec::new(), lint_cap: Level::Forbid }
-    }
-
-    pub fn get_lint_level(
-        &self,
-        lint: &'static Lint,
-        idx: LintStackIndex,
-        aux: Option<&FxHashMap<LintId, LevelAndSource>>,
-        sess: &Session,
-    ) -> LevelAndSource {
-        let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
-
-        // If `level` is none then we actually assume the default level for this
-        // lint.
-        let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition()));
-
-        // If we're about to issue a warning, check at the last minute for any
-        // directives against the warnings "lint". If, for example, there's an
-        // `allow(warnings)` in scope then we want to respect that instead.
-        //
-        // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
-        // triggers in cases (like #80988) where you have `forbid(warnings)`,
-        // and so if we turned that into an error, it'd defeat the purpose of the
-        // future compatibility warning.
-        if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) {
-            let (warnings_level, warnings_src) =
-                self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux);
-            if let Some(configured_warning_level) = warnings_level {
-                if configured_warning_level != Level::Warn {
-                    level = configured_warning_level;
-                    src = warnings_src;
-                }
+/// From an initial level and source, verify the effect of special annotations:
+/// `warnings` lint level and lint caps.
+///
+/// The return of this function is suitable for diagnostics.
+pub fn reveal_actual_level(
+    level: Option<Level>,
+    src: &mut LintLevelSource,
+    sess: &Session,
+    lint: LintId,
+    probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource),
+) -> Level {
+    // If `level` is none then we actually assume the default level for this lint.
+    let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition()));
+
+    // If we're about to issue a warning, check at the last minute for any
+    // directives against the warnings "lint". If, for example, there's an
+    // `allow(warnings)` in scope then we want to respect that instead.
+    //
+    // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
+    // triggers in cases (like #80988) where you have `forbid(warnings)`,
+    // and so if we turned that into an error, it'd defeat the purpose of the
+    // future compatibility warning.
+    if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
+        let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
+        if let Some(configured_warning_level) = warnings_level {
+            if configured_warning_level != Level::Warn {
+                level = configured_warning_level;
+                *src = warnings_src;
             }
         }
+    }
 
-        // Ensure that we never exceed the `--cap-lints` argument
-        // unless the source is a --force-warn
-        level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
-            level
-        } else {
-            cmp::min(level, self.lint_cap)
-        };
-
-        if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) {
-            // Ensure that we never exceed driver level.
-            level = cmp::min(*driver_level, level);
-        }
+    // Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn
+    level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src {
+        level
+    } else {
+        cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
+    };
 
-        (level, src)
+    if let Some(driver_level) = sess.driver_lint_caps.get(&lint) {
+        // Ensure that we never exceed driver level.
+        level = cmp::min(*driver_level, level);
     }
 
-    pub fn get_lint_id_level(
+    level
+}
+
+impl ShallowLintLevelMap {
+    /// Perform a deep probe in the HIR tree looking for the actual level for the lint.
+    /// This lint level is not usable for diagnostics, it needs to be corrected by
+    /// `reveal_actual_level` beforehand.
+    #[instrument(level = "trace", skip(self, tcx), ret)]
+    fn probe_for_lint_level(
         &self,
+        tcx: TyCtxt<'_>,
         id: LintId,
-        mut idx: LintStackIndex,
-        aux: Option<&FxHashMap<LintId, LevelAndSource>>,
+        start: HirId,
     ) -> (Option<Level>, LintLevelSource) {
-        if let Some(specs) = aux {
-            if let Some(&(level, src)) = specs.get(&id) {
-                return (Some(level), src);
-            }
+        if let Some(map) = self.specs.get(&start.local_id)
+            && let Some(&(level, src)) = map.get(&id)
+        {
+            return (Some(level), src);
         }
-        loop {
-            let LintSet { ref specs, parent } = self.list[idx];
-            if let Some(&(level, src)) = specs.get(&id) {
-                return (Some(level), src);
+
+        let mut owner = start.owner;
+        let mut specs = &self.specs;
+
+        for parent in tcx.hir().parent_id_iter(start) {
+            if parent.owner != owner {
+                owner = parent.owner;
+                specs = &tcx.shallow_lint_levels_on(owner).specs;
             }
-            if idx == COMMAND_LINE {
-                return (None, LintLevelSource::Default);
+            if let Some(map) = specs.get(&parent.local_id)
+                && let Some(&(level, src)) = map.get(&id)
+            {
+                return (Some(level), src);
             }
-            idx = parent;
         }
-    }
-}
 
-#[derive(Debug)]
-pub struct LintLevelMap {
-    /// This is a collection of lint expectations as described in RFC 2383, that
-    /// can be fulfilled during this compilation session. This means that at least
-    /// one expected lint is currently registered in the lint store.
-    ///
-    /// The [`LintExpectationId`] is stored as a part of the [`Expect`](Level::Expect)
-    /// lint level.
-    pub lint_expectations: Vec<(LintExpectationId, LintExpectation)>,
-    pub sets: LintLevelSets,
-    pub id_to_set: FxHashMap<HirId, LintStackIndex>,
-}
+        (None, LintLevelSource::Default)
+    }
 
-impl LintLevelMap {
-    /// If the `id` was previously registered with `register_id` when building
-    /// this `LintLevelMap` this returns the corresponding lint level and source
-    /// of the lint level for the lint provided.
-    ///
-    /// If the `id` was not previously registered, returns `None`. If `None` is
-    /// returned then the parent of `id` should be acquired and this function
-    /// should be called again.
-    pub fn level_and_source(
+    /// Fetch and return the user-visible lint level for the given lint at the given HirId.
+    #[instrument(level = "trace", skip(self, tcx), ret)]
+    pub fn lint_level_id_at_node(
         &self,
-        lint: &'static Lint,
-        id: HirId,
-        session: &Session,
-    ) -> Option<LevelAndSource> {
-        self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session))
+        tcx: TyCtxt<'_>,
+        lint: LintId,
+        cur: HirId,
+    ) -> (Level, LintLevelSource) {
+        let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur);
+        let level = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
+            self.probe_for_lint_level(tcx, lint, cur)
+        });
+        (level, src)
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        let LintLevelMap { ref sets, ref id_to_set, ref lint_expectations } = *self;
+impl TyCtxt<'_> {
+    /// Fetch and return the user-visible lint level for the given lint at the given HirId.
+    pub fn lint_level_at_node(self, lint: &'static Lint, id: HirId) -> (Level, LintLevelSource) {
+        self.shallow_lint_levels_on(id.owner).lint_level_id_at_node(self, LintId::of(lint), id)
+    }
 
-        id_to_set.hash_stable(hcx, hasher);
-        lint_expectations.hash_stable(hcx, hasher);
+    /// Walks upwards from `id` to find a node which might change lint levels with attributes.
+    /// It stops at `bound` and just returns it if reached.
+    pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
+        let hir = self.hir();
+        loop {
+            if id == bound {
+                return bound;
+            }
 
-        hcx.while_hashing_spans(true, |hcx| sets.hash_stable(hcx, hasher))
+            if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
+                return id;
+            }
+            let next = hir.get_parent_node(id);
+            if next == id {
+                bug!("lint traversal reached the root of the crate");
+            }
+            id = next;
+        }
     }
 }
 
@@ -261,11 +258,11 @@ pub fn explain_lint_level_source(
                 ));
             }
         }
-        LintLevelSource::Node(lint_attr_name, src, reason) => {
+        LintLevelSource::Node { name: lint_attr_name, span, reason, .. } => {
             if let Some(rationale) = reason {
                 err.note(rationale.as_str());
             }
-            err.span_note_once(src, "the lint level is defined here");
+            err.span_note_once(span, "the lint level is defined here");
             if lint_attr_name.as_str() != name {
                 let level_str = level.as_str();
                 err.note_once(&format!(
@@ -277,23 +274,32 @@ pub fn explain_lint_level_source(
     }
 }
 
-pub fn struct_lint_level<'s, 'd>(
-    sess: &'s Session,
+pub fn struct_lint_level(
+    sess: &Session,
     lint: &'static Lint,
     level: Level,
     src: LintLevelSource,
     span: Option<MultiSpan>,
-    decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) + 'd,
+    msg: impl Into<DiagnosticMessage>,
+    decorate: impl for<'a, 'b> FnOnce(
+        &'b mut DiagnosticBuilder<'a, ()>,
+    ) -> &'b mut DiagnosticBuilder<'a, ()>,
 ) {
     // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
     // the "real" work.
-    fn struct_lint_level_impl<'s, 'd>(
-        sess: &'s Session,
+    fn struct_lint_level_impl(
+        sess: &Session,
         lint: &'static Lint,
         level: Level,
         src: LintLevelSource,
         span: Option<MultiSpan>,
-        decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) + 'd>,
+        msg: impl Into<DiagnosticMessage>,
+        decorate: Box<
+            dyn '_
+                + for<'a, 'b> FnOnce(
+                    &'b mut DiagnosticBuilder<'a, ()>,
+                ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        >,
     ) {
         // Check for future incompatibility lints and issue a stronger warning.
         let future_incompatible = lint.future_incompatible;
@@ -344,6 +350,8 @@ pub fn struct_lint_level<'s, 'd>(
             (Level::Deny | Level::Forbid, None) => sess.diagnostic().struct_err_lint(""),
         };
 
+        err.set_is_lint();
+
         // If this code originates in a foreign macro, aka something that this crate
         // did not itself author, then it's likely that there's nothing this crate
         // can do about it. We probably want to skip the lint entirely.
@@ -366,6 +374,10 @@ pub fn struct_lint_level<'s, 'd>(
             }
         }
 
+        // Delay evaluating and setting the primary message until after we've
+        // suppressed the lint due to macros.
+        err.set_primary_message(msg);
+
         // Lint diagnostics that are covered by the expect level will not be emitted outside
         // the compiler. It is therefore not necessary to add any information for the user.
         // This will therefore directly call the decorate function which will in turn emit
@@ -373,12 +385,12 @@ pub fn struct_lint_level<'s, 'd>(
         if let Level::Expect(_) = level {
             let name = lint.name_lower();
             err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn: false });
-            decorate(LintDiagnosticBuilder::new(err));
+
+            decorate(&mut err);
+            err.emit();
             return;
         }
 
-        explain_lint_level_source(lint, level, src, &mut err);
-
         let name = lint.name_lower();
         let is_force_warn = matches!(level, Level::ForceWarn(_));
         err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn });
@@ -417,10 +429,12 @@ pub fn struct_lint_level<'s, 'd>(
             }
         }
 
-        // Finally, run `decorate`. This function is also responsible for emitting the diagnostic.
-        decorate(LintDiagnosticBuilder::new(err));
+        // Finally, run `decorate`.
+        decorate(&mut err);
+        explain_lint_level_source(lint, level, src, &mut *err);
+        err.emit()
     }
-    struct_lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
+    struct_lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate))
 }
 
 /// Returns whether `span` originates in a foreign crate's external macro.
@@ -432,7 +446,9 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
     match expn_data.kind {
         ExpnKind::Inlined
         | ExpnKind::Root
-        | ExpnKind::Desugaring(DesugaringKind::ForLoop | DesugaringKind::WhileLoop) => false,
+        | ExpnKind::Desugaring(
+            DesugaringKind::ForLoop | DesugaringKind::WhileLoop | DesugaringKind::OpaqueTy,
+        ) => false,
         ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
             // Dummy span for the `def_site` means it's an external macro.
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index d182929c400..61bc089e431 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -253,13 +253,12 @@ fn late_report_deprecation(
         return;
     }
     let method_span = method_span.unwrap_or(span);
-    tcx.struct_span_lint_hir(lint, hir_id, method_span, |lint| {
-        let mut diag = lint.build(message);
+    tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| {
         if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
             let kind = tcx.def_kind(def_id).descr(def_id);
-            deprecation_suggestion(&mut diag, kind, suggestion, method_span);
+            deprecation_suggestion(diag, kind, suggestion, method_span);
         }
-        diag.emit();
+        diag
     });
 }
 
@@ -621,9 +620,7 @@ impl<'tcx> TyCtxt<'tcx> {
         unmarked: impl FnOnce(Span, DefId),
     ) -> bool {
         let soft_handler = |lint, span, msg: &_| {
-            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
-                lint.build(msg).emit();
-            })
+            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint)
         };
         let eval_result =
             self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 734c31192c7..8f67161420d 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -45,7 +45,7 @@ impl<'tcx> TyCtxt<'tcx> {
         //
         // When trying to evaluate constants containing inference variables,
         // use `Infcx::const_eval_resolve` instead.
-        if ct.substs.has_infer_types_or_consts() {
+        if ct.substs.has_non_region_infer() {
             bug!("did not expect inference variables here");
         }
 
@@ -76,7 +76,7 @@ impl<'tcx> TyCtxt<'tcx> {
         //
         // When trying to evaluate constants containing inference variables,
         // use `Infcx::const_eval_resolve` instead.
-        if ct.substs.has_infer_types_or_consts() {
+        if ct.substs.has_non_region_infer() {
             bug!("did not expect inference variables here");
         }
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 78a16788815..a9ebd783403 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -313,7 +313,7 @@ impl<'tcx> Body<'tcx> {
             is_polymorphic: false,
             tainted_by_errors,
         };
-        body.is_polymorphic = body.has_param_types_or_consts();
+        body.is_polymorphic = body.has_non_region_param();
         body
     }
 
@@ -339,7 +339,7 @@ impl<'tcx> Body<'tcx> {
             is_polymorphic: false,
             tainted_by_errors: None,
         };
-        body.is_polymorphic = body.has_param_types_or_consts();
+        body.is_polymorphic = body.has_non_region_param();
         body
     }
 
@@ -2760,7 +2760,7 @@ fn pretty_print_const_value<'tcx>(
             }
             // Aggregates, printed as array/tuple/struct/variant construction syntax.
             //
-            // NB: the `has_param_types_or_consts` check ensures that we can use
+            // NB: the `has_non_region_param` check ensures that we can use
             // the `destructure_const` query with an empty `ty::ParamEnv` without
             // introducing ICEs (e.g. via `layout_of`) from missing bounds.
             // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
@@ -2768,7 +2768,7 @@ fn pretty_print_const_value<'tcx>(
             //
             // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
             // correct `ty::ParamEnv` to allow printing *all* constant values.
-            (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
+            (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => {
                 let ct = tcx.lift(ct).unwrap();
                 let ty = tcx.lift(ty).unwrap();
                 if let Some(contents) = tcx.try_destructure_mir_constant(
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index eed44240f83..cf5b365b27c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -274,10 +274,15 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query lint_levels(_: ()) -> LintLevelMap {
+    query shallow_lint_levels_on(key: hir::OwnerId) -> rustc_middle::lint::ShallowLintLevelMap {
+        eval_always // fetches `resolutions`
         arena_cache
-        eval_always
-        desc { "computing the lint levels for items in this crate" }
+        desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key.to_def_id()) }
+    }
+
+    query lint_expectations(_: ()) -> Vec<(LintExpectationId, LintExpectation)> {
+        arena_cache
+        desc { "computing `#[expect]`ed lints in this crate" }
     }
 
     query parent_module_from_def_id(key: LocalDefId) -> LocalDefId {
@@ -1126,6 +1131,11 @@ rustc_queries! {
         desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) }
     }
 
+    /// Determines whether an item is annotated with `doc(notable_trait)`.
+    query is_doc_notable_trait(def_id: DefId) -> bool {
+        desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) }
+    }
+
     /// Returns the attributes on the item at `def_id`.
     ///
     /// Do not use this directly, use `tcx.get_attrs` instead.
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index 641e53f2a15..1aa4df77800 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -71,16 +71,16 @@ impl<'tcx> AbstractConst<'tcx> {
         walk_abstract_const::<!, _>(tcx, self, |node| {
             match node.root(tcx) {
                 Node::Leaf(leaf) => {
-                    if leaf.has_infer_types_or_consts() {
+                    if leaf.has_non_region_infer() {
                         failure_kind = FailureKind::MentionsInfer;
-                    } else if leaf.has_param_types_or_consts() {
+                    } else if leaf.has_non_region_param() {
                         failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
                     }
                 }
                 Node::Cast(_, _, ty) => {
-                    if ty.has_infer_types_or_consts() {
+                    if ty.has_non_region_infer() {
                         failure_kind = FailureKind::MentionsInfer;
-                    } else if ty.has_param_types_or_consts() {
+                    } else if ty.has_non_region_param() {
                         failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
                     }
                 }
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 2e596b27527..3c485e26409 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -438,7 +438,8 @@ impl<'tcx> AdtDef<'tcx> {
             | Res::Def(DefKind::Union, _)
             | Res::Def(DefKind::TyAlias, _)
             | Res::Def(DefKind::AssocTy, _)
-            | Res::SelfTy { .. }
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
             | Res::SelfCtor(..) => self.non_enum_variant(),
             _ => bug!("unexpected res {:?} in variant_of_res", res),
         }
@@ -457,11 +458,9 @@ impl<'tcx> AdtDef<'tcx> {
                     Some(Discr { val: b, ty })
                 } else {
                     info!("invalid enum discriminant: {:#?}", val);
-                    crate::mir::interpret::struct_error(
-                        tcx.at(tcx.def_span(expr_did)),
-                        "constant evaluation of enum discriminant resulted in non-integer",
-                    )
-                    .emit();
+                    tcx.sess.emit_err(crate::error::ConstEvalNonIntError {
+                        span: tcx.def_span(expr_did),
+                    });
                     None
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4781585b82c..97646003e73 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -4,7 +4,7 @@ use crate::arena::Arena;
 use crate::dep_graph::{DepGraph, DepKindStruct};
 use crate::hir::place::Place as HirPlace;
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
-use crate::lint::{struct_lint_level, LintLevelSource};
+use crate::lint::struct_lint_level;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::resolve_lifetime;
 use crate::middle::stability;
@@ -35,7 +35,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, RwLock, WorkerLocal};
 use rustc_data_structures::vec_map::VecMap;
-use rustc_errors::{DecorateLint, ErrorGuaranteed, LintDiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
@@ -55,7 +57,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use rustc_session::config::{CrateType, OutputFilenames};
 use rustc_session::cstore::CrateStoreDyn;
 use rustc_session::errors::TargetDataLayoutErrorsWrapper;
-use rustc_session::lint::{Level, Lint};
+use rustc_session::lint::Lint;
 use rustc_session::Limit;
 use rustc_session::Session;
 use rustc_span::def_id::{DefPathHash, StableCrateId};
@@ -2810,44 +2812,6 @@ impl<'tcx> TyCtxt<'tcx> {
         iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
     }
 
-    /// Walks upwards from `id` to find a node which might change lint levels with attributes.
-    /// It stops at `bound` and just returns it if reached.
-    pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
-        let hir = self.hir();
-        loop {
-            if id == bound {
-                return bound;
-            }
-
-            if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
-                return id;
-            }
-            let next = hir.get_parent_node(id);
-            if next == id {
-                bug!("lint traversal reached the root of the crate");
-            }
-            id = next;
-        }
-    }
-
-    pub fn lint_level_at_node(
-        self,
-        lint: &'static Lint,
-        mut id: hir::HirId,
-    ) -> (Level, LintLevelSource) {
-        let sets = self.lint_levels(());
-        loop {
-            if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
-                return pair;
-            }
-            let next = self.hir().get_parent_node(id);
-            if next == id {
-                bug!("lint traversal reached the root of the crate");
-            }
-            id = next;
-        }
-    }
-
     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
     /// typically generated by `#[derive(LintDiagnostic)]`).
     pub fn emit_spanned_lint(
@@ -2857,7 +2821,9 @@ impl<'tcx> TyCtxt<'tcx> {
         span: impl Into<MultiSpan>,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.struct_span_lint_hir(lint, hir_id, span, |diag| decorator.decorate_lint(diag))
+        self.struct_span_lint_hir(lint, hir_id, span, decorator.msg(), |diag| {
+            decorator.decorate_lint(diag)
+        })
     }
 
     pub fn struct_span_lint_hir(
@@ -2865,10 +2831,13 @@ impl<'tcx> TyCtxt<'tcx> {
         lint: &'static Lint,
         hir_id: HirId,
         span: impl Into<MultiSpan>,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
         let (level, src) = self.lint_level_at_node(lint, hir_id);
-        struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
+        struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
     }
 
     /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
@@ -2879,17 +2848,20 @@ impl<'tcx> TyCtxt<'tcx> {
         id: HirId,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.struct_lint_node(lint, id, |diag| decorator.decorate_lint(diag))
+        self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
     }
 
     pub fn struct_lint_node(
         self,
         lint: &'static Lint,
         id: HirId,
-        decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'b mut DiagnosticBuilder<'a, ()>,
+        ) -> &'b mut DiagnosticBuilder<'a, ()>,
     ) {
         let (level, src) = self.lint_level_at_node(lint, id);
-        struct_lint_level(self.sess, lint, level, src, None, decorate);
+        struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
     }
 
     pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 41bb3c71401..3be0bc4defc 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -132,7 +132,7 @@ pub fn simplify_type<'tcx>(
             // don't unify with anything else as long as they are fully normalized.
             //
             // We will have to be careful with lazy normalization here.
-            TreatParams::AsPlaceholder if !ty.has_infer_types_or_consts() => {
+            TreatParams::AsPlaceholder if !ty.has_non_region_infer() => {
                 debug!("treating `{}` as a placeholder", ty);
                 Some(PlaceholderSimplifiedType)
             }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index cc820d9eb2d..5f8729a8ddf 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1,40 +1,23 @@
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
 use crate::ty::normalize_erasing_regions::NormalizationError;
-use crate::ty::{
-    self, layout_sanity_check::sanity_check_layout, subst::SubstsRef, EarlyBinder, ReprOptions, Ty,
-    TyCtxt, TypeVisitable,
-};
+use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitable};
 use rustc_ast as ast;
 use rustc_attr as attr;
+use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_hir::lang_items::LangItem;
-use rustc_index::bit_set::BitSet;
-use rustc_index::vec::{Idx, IndexVec};
-use rustc_session::{config::OptLevel, DataTypeKind, FieldInfo, SizeKind, VariantInfo};
-use rustc_span::symbol::Symbol;
+use rustc_index::vec::Idx;
+use rustc_session::config::OptLevel;
 use rustc_span::{Span, DUMMY_SP};
-use rustc_target::abi::call::{
-    ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind,
-};
+use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::*;
 use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
 
-use std::cmp::{self, Ordering};
+use std::cmp::{self};
 use std::fmt;
-use std::iter;
 use std::num::NonZeroUsize;
 use std::ops::Bound;
 
-use rand::{seq::SliceRandom, SeedableRng};
-use rand_xoshiro::Xoshiro128StarStar;
-
-pub fn provide(providers: &mut ty::query::Providers) {
-    *providers =
-        ty::query::Providers { layout_of, fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers };
-}
-
 pub trait IntegerExt {
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
     fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
@@ -206,6 +189,12 @@ pub enum LayoutError<'tcx> {
     NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
 }
 
+impl<'a> IntoDiagnostic<'a, !> for LayoutError<'a> {
+    fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> {
+        handler.struct_fatal(self.to_string())
+    }
+}
+
 impl<'tcx> fmt::Display for LayoutError<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
@@ -223,1814 +212,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
     }
 }
 
-#[instrument(skip(tcx, query), level = "debug")]
-fn layout_of<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
-) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> {
-    let (param_env, ty) = query.into_parts();
-    debug!(?ty);
-
-    let param_env = param_env.with_reveal_all_normalized(tcx);
-    let unnormalized_ty = ty;
-
-    // FIXME: We might want to have two different versions of `layout_of`:
-    // One that can be called after typecheck has completed and can use
-    // `normalize_erasing_regions` here and another one that can be called
-    // before typecheck has completed and uses `try_normalize_erasing_regions`.
-    let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
-        Ok(t) => t,
-        Err(normalization_error) => {
-            return Err(LayoutError::NormalizationFailure(ty, normalization_error));
-        }
-    };
-
-    if ty != unnormalized_ty {
-        // Ensure this layout is also cached for the normalized type.
-        return tcx.layout_of(param_env.and(ty));
-    }
-
-    let cx = LayoutCx { tcx, param_env };
-
-    let layout = cx.layout_of_uncached(ty)?;
-    let layout = TyAndLayout { ty, layout };
-
-    cx.record_layout_for_printing(layout);
-
-    sanity_check_layout(&cx, &layout);
-
-    Ok(layout)
-}
-
 #[derive(Clone, Copy)]
 pub struct LayoutCx<'tcx, C> {
     pub tcx: C,
     pub param_env: ty::ParamEnv<'tcx>,
 }
 
-#[derive(Copy, Clone, Debug)]
-enum StructKind {
-    /// A tuple, closure, or univariant which cannot be coerced to unsized.
-    AlwaysSized,
-    /// A univariant, the last field of which may be coerced to unsized.
-    MaybeUnsized,
-    /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
-    Prefixed(Size, Align),
-}
-
-// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`.
-// This is used to go between `memory_index` (source field order to memory order)
-// and `inverse_memory_index` (memory order to source field order).
-// See also `FieldsShape::Arbitrary::memory_index` for more details.
-// FIXME(eddyb) build a better abstraction for permutations, if possible.
-fn invert_mapping(map: &[u32]) -> Vec<u32> {
-    let mut inverse = vec![0; map.len()];
-    for i in 0..map.len() {
-        inverse[map[i] as usize] = i as u32;
-    }
-    inverse
-}
-
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
-    fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutS<'tcx> {
-        let dl = self.data_layout();
-        let b_align = b.align(dl);
-        let align = a.align(dl).max(b_align).max(dl.aggregate_align);
-        let b_offset = a.size(dl).align_to(b_align.abi);
-        let size = (b_offset + b.size(dl)).align_to(align.abi);
-
-        // HACK(nox): We iter on `b` and then `a` because `max_by_key`
-        // returns the last maximum.
-        let largest_niche = Niche::from_scalar(dl, b_offset, b)
-            .into_iter()
-            .chain(Niche::from_scalar(dl, Size::ZERO, a))
-            .max_by_key(|niche| niche.available(dl));
-
-        LayoutS {
-            variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldsShape::Arbitrary {
-                offsets: vec![Size::ZERO, b_offset],
-                memory_index: vec![0, 1],
-            },
-            abi: Abi::ScalarPair(a, b),
-            largest_niche,
-            align,
-            size,
-        }
-    }
-
-    fn univariant_uninterned(
-        &self,
-        ty: Ty<'tcx>,
-        fields: &[TyAndLayout<'_>],
-        repr: &ReprOptions,
-        kind: StructKind,
-    ) -> Result<LayoutS<'tcx>, LayoutError<'tcx>> {
-        let dl = self.data_layout();
-        let pack = repr.pack;
-        if pack.is_some() && repr.align.is_some() {
-            self.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned");
-            return Err(LayoutError::Unknown(ty));
-        }
-
-        let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
-
-        let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
-
-        let optimize = !repr.inhibit_struct_field_reordering_opt();
-        if optimize {
-            let end =
-                if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
-            let optimizing = &mut inverse_memory_index[..end];
-            let field_align = |f: &TyAndLayout<'_>| {
-                if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi }
-            };
-
-            // If `-Z randomize-layout` was enabled for the type definition we can shuffle
-            // the field ordering to try and catch some code making assumptions about layouts
-            // we don't guarantee
-            if repr.can_randomize_type_layout() {
-                // `ReprOptions.layout_seed` is a deterministic seed that we can use to
-                // randomize field ordering with
-                let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
-
-                // Shuffle the ordering of the fields
-                optimizing.shuffle(&mut rng);
-
-            // Otherwise we just leave things alone and actually optimize the type's fields
-            } else {
-                match kind {
-                    StructKind::AlwaysSized | StructKind::MaybeUnsized => {
-                        optimizing.sort_by_key(|&x| {
-                            // Place ZSTs first to avoid "interesting offsets",
-                            // especially with only one or two non-ZST fields.
-                            let f = &fields[x as usize];
-                            (!f.is_zst(), cmp::Reverse(field_align(f)))
-                        });
-                    }
-
-                    StructKind::Prefixed(..) => {
-                        // Sort in ascending alignment so that the layout stays optimal
-                        // regardless of the prefix
-                        optimizing.sort_by_key(|&x| field_align(&fields[x as usize]));
-                    }
-                }
-
-                // FIXME(Kixiron): We can always shuffle fields within a given alignment class
-                //                 regardless of the status of `-Z randomize-layout`
-            }
-        }
-
-        // inverse_memory_index holds field indices by increasing memory offset.
-        // That is, if field 5 has offset 0, the first element of inverse_memory_index is 5.
-        // We now write field offsets to the corresponding offset slot;
-        // field 5 with offset 0 puts 0 in offsets[5].
-        // At the bottom of this function, we invert `inverse_memory_index` to
-        // produce `memory_index` (see `invert_mapping`).
-
-        let mut sized = true;
-        let mut offsets = vec![Size::ZERO; fields.len()];
-        let mut offset = Size::ZERO;
-        let mut largest_niche = None;
-        let mut largest_niche_available = 0;
-
-        if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
-            let prefix_align =
-                if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
-            align = align.max(AbiAndPrefAlign::new(prefix_align));
-            offset = prefix_size.align_to(prefix_align);
-        }
-
-        for &i in &inverse_memory_index {
-            let field = fields[i as usize];
-            if !sized {
-                self.tcx.sess.delay_span_bug(
-                    DUMMY_SP,
-                    &format!(
-                        "univariant: field #{} of `{}` comes after unsized field",
-                        offsets.len(),
-                        ty
-                    ),
-                );
-            }
-
-            if field.is_unsized() {
-                sized = false;
-            }
-
-            // Invariant: offset < dl.obj_size_bound() <= 1<<61
-            let field_align = if let Some(pack) = pack {
-                field.align.min(AbiAndPrefAlign::new(pack))
-            } else {
-                field.align
-            };
-            offset = offset.align_to(field_align.abi);
-            align = align.max(field_align);
-
-            debug!("univariant offset: {:?} field: {:#?}", offset, field);
-            offsets[i as usize] = offset;
-
-            if let Some(mut niche) = field.largest_niche {
-                let available = niche.available(dl);
-                if available > largest_niche_available {
-                    largest_niche_available = available;
-                    niche.offset += offset;
-                    largest_niche = Some(niche);
-                }
-            }
-
-            offset = offset.checked_add(field.size, dl).ok_or(LayoutError::SizeOverflow(ty))?;
-        }
-
-        if let Some(repr_align) = repr.align {
-            align = align.max(AbiAndPrefAlign::new(repr_align));
-        }
-
-        debug!("univariant min_size: {:?}", offset);
-        let min_size = offset;
-
-        // As stated above, inverse_memory_index holds field indices by increasing offset.
-        // This makes it an already-sorted view of the offsets vec.
-        // To invert it, consider:
-        // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
-        // Field 5 would be the first element, so memory_index is i:
-        // Note: if we didn't optimize, it's already right.
-
-        let memory_index =
-            if optimize { invert_mapping(&inverse_memory_index) } else { inverse_memory_index };
-
-        let size = min_size.align_to(align.abi);
-        let mut abi = Abi::Aggregate { sized };
-
-        // Unpack newtype ABIs and find scalar pairs.
-        if sized && size.bytes() > 0 {
-            // All other fields must be ZSTs.
-            let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst());
-
-            match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) {
-                // We have exactly one non-ZST field.
-                (Some((i, field)), None, None) => {
-                    // Field fills the struct and it has a scalar or scalar pair ABI.
-                    if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size
-                    {
-                        match field.abi {
-                            // For plain scalars, or vectors of them, we can't unpack
-                            // newtypes for `#[repr(C)]`, as that affects C ABIs.
-                            Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
-                                abi = field.abi;
-                            }
-                            // But scalar pairs are Rust-specific and get
-                            // treated as aggregates by C ABIs anyway.
-                            Abi::ScalarPair(..) => {
-                                abi = field.abi;
-                            }
-                            _ => {}
-                        }
-                    }
-                }
-
-                // Two non-ZST fields, and they're both scalars.
-                (Some((i, a)), Some((j, b)), None) => {
-                    match (a.abi, b.abi) {
-                        (Abi::Scalar(a), Abi::Scalar(b)) => {
-                            // Order by the memory placement, not source order.
-                            let ((i, a), (j, b)) = if offsets[i] < offsets[j] {
-                                ((i, a), (j, b))
-                            } else {
-                                ((j, b), (i, a))
-                            };
-                            let pair = self.scalar_pair(a, b);
-                            let pair_offsets = match pair.fields {
-                                FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
-                                    assert_eq!(memory_index, &[0, 1]);
-                                    offsets
-                                }
-                                _ => bug!(),
-                            };
-                            if offsets[i] == pair_offsets[0]
-                                && offsets[j] == pair_offsets[1]
-                                && align == pair.align
-                                && size == pair.size
-                            {
-                                // We can use `ScalarPair` only when it matches our
-                                // already computed layout (including `#[repr(C)]`).
-                                abi = pair.abi;
-                            }
-                        }
-                        _ => {}
-                    }
-                }
-
-                _ => {}
-            }
-        }
-
-        if fields.iter().any(|f| f.abi.is_uninhabited()) {
-            abi = Abi::Uninhabited;
-        }
-
-        Ok(LayoutS {
-            variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldsShape::Arbitrary { offsets, memory_index },
-            abi,
-            largest_niche,
-            align,
-            size,
-        })
-    }
-
-    fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
-        let tcx = self.tcx;
-        let param_env = self.param_env;
-        let dl = self.data_layout();
-        let scalar_unit = |value: Primitive| {
-            let size = value.size(dl);
-            assert!(size.bits() <= 128);
-            Scalar::Initialized { value, valid_range: WrappingRange::full(size) }
-        };
-        let scalar =
-            |value: Primitive| tcx.intern_layout(LayoutS::scalar(self, scalar_unit(value)));
-
-        let univariant = |fields: &[TyAndLayout<'_>], repr: &ReprOptions, kind| {
-            Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?))
-        };
-        debug_assert!(!ty.has_infer_types_or_consts());
-
-        Ok(match *ty.kind() {
-            // Basic scalars.
-            ty::Bool => tcx.intern_layout(LayoutS::scalar(
-                self,
-                Scalar::Initialized {
-                    value: Int(I8, false),
-                    valid_range: WrappingRange { start: 0, end: 1 },
-                },
-            )),
-            ty::Char => tcx.intern_layout(LayoutS::scalar(
-                self,
-                Scalar::Initialized {
-                    value: Int(I32, false),
-                    valid_range: WrappingRange { start: 0, end: 0x10FFFF },
-                },
-            )),
-            ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
-            ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
-            ty::Float(fty) => scalar(match fty {
-                ty::FloatTy::F32 => F32,
-                ty::FloatTy::F64 => F64,
-            }),
-            ty::FnPtr(_) => {
-                let mut ptr = scalar_unit(Pointer);
-                ptr.valid_range_mut().start = 1;
-                tcx.intern_layout(LayoutS::scalar(self, ptr))
-            }
-
-            // The never type.
-            ty::Never => tcx.intern_layout(LayoutS {
-                variants: Variants::Single { index: VariantIdx::new(0) },
-                fields: FieldsShape::Primitive,
-                abi: Abi::Uninhabited,
-                largest_niche: None,
-                align: dl.i8_align,
-                size: Size::ZERO,
-            }),
-
-            // Potentially-wide pointers.
-            ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                let mut data_ptr = scalar_unit(Pointer);
-                if !ty.is_unsafe_ptr() {
-                    data_ptr.valid_range_mut().start = 1;
-                }
-
-                let pointee = tcx.normalize_erasing_regions(param_env, pointee);
-                if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
-                    return Ok(tcx.intern_layout(LayoutS::scalar(self, data_ptr)));
-                }
-
-                let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
-                let metadata = match unsized_part.kind() {
-                    ty::Foreign(..) => {
-                        return Ok(tcx.intern_layout(LayoutS::scalar(self, data_ptr)));
-                    }
-                    ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
-                    ty::Dynamic(..) => {
-                        let mut vtable = scalar_unit(Pointer);
-                        vtable.valid_range_mut().start = 1;
-                        vtable
-                    }
-                    _ => return Err(LayoutError::Unknown(unsized_part)),
-                };
-
-                // Effectively a (ptr, meta) tuple.
-                tcx.intern_layout(self.scalar_pair(data_ptr, metadata))
-            }
-
-            ty::Dynamic(_, _, ty::DynStar) => {
-                let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false));
-                data.valid_range_mut().start = 0;
-                let mut vtable = scalar_unit(Pointer);
-                vtable.valid_range_mut().start = 1;
-                tcx.intern_layout(self.scalar_pair(data, vtable))
-            }
-
-            // Arrays and slices.
-            ty::Array(element, mut count) => {
-                if count.has_projections() {
-                    count = tcx.normalize_erasing_regions(param_env, count);
-                    if count.has_projections() {
-                        return Err(LayoutError::Unknown(ty));
-                    }
-                }
-
-                let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?;
-                let element = self.layout_of(element)?;
-                let size =
-                    element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
-
-                let abi =
-                    if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty)) {
-                        Abi::Uninhabited
-                    } else {
-                        Abi::Aggregate { sized: true }
-                    };
-
-                let largest_niche = if count != 0 { element.largest_niche } else { None };
-
-                tcx.intern_layout(LayoutS {
-                    variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldsShape::Array { stride: element.size, count },
-                    abi,
-                    largest_niche,
-                    align: element.align,
-                    size,
-                })
-            }
-            ty::Slice(element) => {
-                let element = self.layout_of(element)?;
-                tcx.intern_layout(LayoutS {
-                    variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields: FieldsShape::Array { stride: element.size, count: 0 },
-                    abi: Abi::Aggregate { sized: false },
-                    largest_niche: None,
-                    align: element.align,
-                    size: Size::ZERO,
-                })
-            }
-            ty::Str => tcx.intern_layout(LayoutS {
-                variants: Variants::Single { index: VariantIdx::new(0) },
-                fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
-                abi: Abi::Aggregate { sized: false },
-                largest_niche: None,
-                align: dl.i8_align,
-                size: Size::ZERO,
-            }),
-
-            // Odd unit types.
-            ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?,
-            ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => {
-                let mut unit = self.univariant_uninterned(
-                    ty,
-                    &[],
-                    &ReprOptions::default(),
-                    StructKind::AlwaysSized,
-                )?;
-                match unit.abi {
-                    Abi::Aggregate { ref mut sized } => *sized = false,
-                    _ => bug!(),
-                }
-                tcx.intern_layout(unit)
-            }
-
-            ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?,
-
-            ty::Closure(_, ref substs) => {
-                let tys = substs.as_closure().upvar_tys();
-                univariant(
-                    &tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
-                    &ReprOptions::default(),
-                    StructKind::AlwaysSized,
-                )?
-            }
-
-            ty::Tuple(tys) => {
-                let kind =
-                    if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
-
-                univariant(
-                    &tys.iter().map(|k| self.layout_of(k)).collect::<Result<Vec<_>, _>>()?,
-                    &ReprOptions::default(),
-                    kind,
-                )?
-            }
-
-            // SIMD vector types.
-            ty::Adt(def, substs) if def.repr().simd() => {
-                if !def.is_struct() {
-                    // Should have yielded E0517 by now.
-                    tcx.sess.delay_span_bug(
-                        DUMMY_SP,
-                        "#[repr(simd)] was applied to an ADT that is not a struct",
-                    );
-                    return Err(LayoutError::Unknown(ty));
-                }
-
-                // Supported SIMD vectors are homogeneous ADTs with at least one field:
-                //
-                // * #[repr(simd)] struct S(T, T, T, T);
-                // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
-                // * #[repr(simd)] struct S([T; 4])
-                //
-                // where T is a primitive scalar (integer/float/pointer).
-
-                // SIMD vectors with zero fields are not supported.
-                // (should be caught by typeck)
-                if def.non_enum_variant().fields.is_empty() {
-                    tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty));
-                }
-
-                // Type of the first ADT field:
-                let f0_ty = def.non_enum_variant().fields[0].ty(tcx, substs);
-
-                // Heterogeneous SIMD vectors are not supported:
-                // (should be caught by typeck)
-                for fi in &def.non_enum_variant().fields {
-                    if fi.ty(tcx, substs) != f0_ty {
-                        tcx.sess.fatal(&format!("monomorphising heterogeneous SIMD type `{}`", ty));
-                    }
-                }
-
-                // The element type and number of elements of the SIMD vector
-                // are obtained from:
-                //
-                // * the element type and length of the single array field, if
-                // the first field is of array type, or
-                //
-                // * the homogeneous field type and the number of fields.
-                let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() {
-                    // First ADT field is an array:
-
-                    // SIMD vectors with multiple array fields are not supported:
-                    // (should be caught by typeck)
-                    if def.non_enum_variant().fields.len() != 1 {
-                        tcx.sess.fatal(&format!(
-                            "monomorphising SIMD type `{}` with more than one array field",
-                            ty
-                        ));
-                    }
-
-                    // Extract the number of elements from the layout of the array field:
-                    let FieldsShape::Array { count, .. } = self.layout_of(f0_ty)?.layout.fields() else {
-                        return Err(LayoutError::Unknown(ty));
-                    };
-
-                    (*e_ty, *count, true)
-                } else {
-                    // First ADT field is not an array:
-                    (f0_ty, def.non_enum_variant().fields.len() as _, false)
-                };
-
-                // SIMD vectors of zero length are not supported.
-                // Additionally, lengths are capped at 2^16 as a fixed maximum backends must
-                // support.
-                //
-                // Can't be caught in typeck if the array length is generic.
-                if e_len == 0 {
-                    tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty));
-                } else if e_len > MAX_SIMD_LANES {
-                    tcx.sess.fatal(&format!(
-                        "monomorphising SIMD type `{}` of length greater than {}",
-                        ty, MAX_SIMD_LANES,
-                    ));
-                }
-
-                // Compute the ABI of the element type:
-                let e_ly = self.layout_of(e_ty)?;
-                let Abi::Scalar(e_abi) = e_ly.abi else {
-                    // This error isn't caught in typeck, e.g., if
-                    // the element type of the vector is generic.
-                    tcx.sess.fatal(&format!(
-                        "monomorphising SIMD type `{}` with a non-primitive-scalar \
-                        (integer/float/pointer) element type `{}`",
-                        ty, e_ty
-                    ))
-                };
-
-                // Compute the size and alignment of the vector:
-                let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?;
-                let align = dl.vector_align(size);
-                let size = size.align_to(align.abi);
-
-                // Compute the placement of the vector fields:
-                let fields = if is_array {
-                    FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] }
-                } else {
-                    FieldsShape::Array { stride: e_ly.size, count: e_len }
-                };
-
-                tcx.intern_layout(LayoutS {
-                    variants: Variants::Single { index: VariantIdx::new(0) },
-                    fields,
-                    abi: Abi::Vector { element: e_abi, count: e_len },
-                    largest_niche: e_ly.largest_niche,
-                    size,
-                    align,
-                })
-            }
-
-            // ADTs.
-            ty::Adt(def, substs) => {
-                // Cache the field layouts.
-                let variants = def
-                    .variants()
-                    .iter()
-                    .map(|v| {
-                        v.fields
-                            .iter()
-                            .map(|field| self.layout_of(field.ty(tcx, substs)))
-                            .collect::<Result<Vec<_>, _>>()
-                    })
-                    .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-                if def.is_union() {
-                    if def.repr().pack.is_some() && def.repr().align.is_some() {
-                        self.tcx.sess.delay_span_bug(
-                            tcx.def_span(def.did()),
-                            "union cannot be packed and aligned",
-                        );
-                        return Err(LayoutError::Unknown(ty));
-                    }
-
-                    let mut align =
-                        if def.repr().pack.is_some() { dl.i8_align } else { dl.aggregate_align };
-
-                    if let Some(repr_align) = def.repr().align {
-                        align = align.max(AbiAndPrefAlign::new(repr_align));
-                    }
-
-                    let optimize = !def.repr().inhibit_union_abi_opt();
-                    let mut size = Size::ZERO;
-                    let mut abi = Abi::Aggregate { sized: true };
-                    let index = VariantIdx::new(0);
-                    for field in &variants[index] {
-                        assert!(!field.is_unsized());
-                        align = align.max(field.align);
-
-                        // If all non-ZST fields have the same ABI, forward this ABI
-                        if optimize && !field.is_zst() {
-                            // Discard valid range information and allow undef
-                            let field_abi = match field.abi {
-                                Abi::Scalar(x) => Abi::Scalar(x.to_union()),
-                                Abi::ScalarPair(x, y) => {
-                                    Abi::ScalarPair(x.to_union(), y.to_union())
-                                }
-                                Abi::Vector { element: x, count } => {
-                                    Abi::Vector { element: x.to_union(), count }
-                                }
-                                Abi::Uninhabited | Abi::Aggregate { .. } => {
-                                    Abi::Aggregate { sized: true }
-                                }
-                            };
-
-                            if size == Size::ZERO {
-                                // first non ZST: initialize 'abi'
-                                abi = field_abi;
-                            } else if abi != field_abi {
-                                // different fields have different ABI: reset to Aggregate
-                                abi = Abi::Aggregate { sized: true };
-                            }
-                        }
-
-                        size = cmp::max(size, field.size);
-                    }
-
-                    if let Some(pack) = def.repr().pack {
-                        align = align.min(AbiAndPrefAlign::new(pack));
-                    }
-
-                    return Ok(tcx.intern_layout(LayoutS {
-                        variants: Variants::Single { index },
-                        fields: FieldsShape::Union(
-                            NonZeroUsize::new(variants[index].len())
-                                .ok_or(LayoutError::Unknown(ty))?,
-                        ),
-                        abi,
-                        largest_niche: None,
-                        align,
-                        size: size.align_to(align.abi),
-                    }));
-                }
-
-                // A variant is absent if it's uninhabited and only has ZST fields.
-                // Present uninhabited variants only require space for their fields,
-                // but *not* an encoding of the discriminant (e.g., a tag value).
-                // See issue #49298 for more details on the need to leave space
-                // for non-ZST uninhabited data (mostly partial initialization).
-                let absent = |fields: &[TyAndLayout<'_>]| {
-                    let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited());
-                    let is_zst = fields.iter().all(|f| f.is_zst());
-                    uninhabited && is_zst
-                };
-                let (present_first, present_second) = {
-                    let mut present_variants = variants
-                        .iter_enumerated()
-                        .filter_map(|(i, v)| if absent(v) { None } else { Some(i) });
-                    (present_variants.next(), present_variants.next())
-                };
-                let present_first = match present_first {
-                    Some(present_first) => present_first,
-                    // Uninhabited because it has no variants, or only absent ones.
-                    None if def.is_enum() => {
-                        return Ok(tcx.layout_of(param_env.and(tcx.types.never))?.layout);
-                    }
-                    // If it's a struct, still compute a layout so that we can still compute the
-                    // field offsets.
-                    None => VariantIdx::new(0),
-                };
-
-                let is_struct = !def.is_enum() ||
-                    // Only one variant is present.
-                    (present_second.is_none() &&
-                    // Representation optimizations are allowed.
-                    !def.repr().inhibit_enum_layout_opt());
-                if is_struct {
-                    // Struct, or univariant enum equivalent to a struct.
-                    // (Typechecking will reject discriminant-sizing attrs.)
-
-                    let v = present_first;
-                    let kind = if def.is_enum() || variants[v].is_empty() {
-                        StructKind::AlwaysSized
-                    } else {
-                        let param_env = tcx.param_env(def.did());
-                        let last_field = def.variant(v).fields.last().unwrap();
-                        let always_sized =
-                            tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
-                        if !always_sized {
-                            StructKind::MaybeUnsized
-                        } else {
-                            StructKind::AlwaysSized
-                        }
-                    };
-
-                    let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr(), kind)?;
-                    st.variants = Variants::Single { index: v };
-
-                    if def.is_unsafe_cell() {
-                        let hide_niches = |scalar: &mut _| match scalar {
-                            Scalar::Initialized { value, valid_range } => {
-                                *valid_range = WrappingRange::full(value.size(dl))
-                            }
-                            // Already doesn't have any niches
-                            Scalar::Union { .. } => {}
-                        };
-                        match &mut st.abi {
-                            Abi::Uninhabited => {}
-                            Abi::Scalar(scalar) => hide_niches(scalar),
-                            Abi::ScalarPair(a, b) => {
-                                hide_niches(a);
-                                hide_niches(b);
-                            }
-                            Abi::Vector { element, count: _ } => hide_niches(element),
-                            Abi::Aggregate { sized: _ } => {}
-                        }
-                        st.largest_niche = None;
-                        return Ok(tcx.intern_layout(st));
-                    }
-
-                    let (start, end) = self.tcx.layout_scalar_valid_range(def.did());
-                    match st.abi {
-                        Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
-                            // the asserts ensure that we are not using the
-                            // `#[rustc_layout_scalar_valid_range(n)]`
-                            // attribute to widen the range of anything as that would probably
-                            // result in UB somewhere
-                            // FIXME(eddyb) the asserts are probably not needed,
-                            // as larger validity ranges would result in missed
-                            // optimizations, *not* wrongly assuming the inner
-                            // value is valid. e.g. unions enlarge validity ranges,
-                            // because the values may be uninitialized.
-                            if let Bound::Included(start) = start {
-                                // FIXME(eddyb) this might be incorrect - it doesn't
-                                // account for wrap-around (end < start) ranges.
-                                let valid_range = scalar.valid_range_mut();
-                                assert!(valid_range.start <= start);
-                                valid_range.start = start;
-                            }
-                            if let Bound::Included(end) = end {
-                                // FIXME(eddyb) this might be incorrect - it doesn't
-                                // account for wrap-around (end < start) ranges.
-                                let valid_range = scalar.valid_range_mut();
-                                assert!(valid_range.end >= end);
-                                valid_range.end = end;
-                            }
-
-                            // Update `largest_niche` if we have introduced a larger niche.
-                            let niche = Niche::from_scalar(dl, Size::ZERO, *scalar);
-                            if let Some(niche) = niche {
-                                match st.largest_niche {
-                                    Some(largest_niche) => {
-                                        // Replace the existing niche even if they're equal,
-                                        // because this one is at a lower offset.
-                                        if largest_niche.available(dl) <= niche.available(dl) {
-                                            st.largest_niche = Some(niche);
-                                        }
-                                    }
-                                    None => st.largest_niche = Some(niche),
-                                }
-                            }
-                        }
-                        _ => assert!(
-                            start == Bound::Unbounded && end == Bound::Unbounded,
-                            "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}",
-                            def,
-                            st,
-                        ),
-                    }
-
-                    return Ok(tcx.intern_layout(st));
-                }
-
-                // At this point, we have handled all unions and
-                // structs. (We have also handled univariant enums
-                // that allow representation optimization.)
-                assert!(def.is_enum());
-
-                // Until we've decided whether to use the tagged or
-                // niche filling LayoutS, we don't want to intern the
-                // variant layouts, so we can't store them in the
-                // overall LayoutS. Store the overall LayoutS
-                // and the variant LayoutSs here until then.
-                struct TmpLayout<'tcx> {
-                    layout: LayoutS<'tcx>,
-                    variants: IndexVec<VariantIdx, LayoutS<'tcx>>,
-                }
-
-                let calculate_niche_filling_layout =
-                    || -> Result<Option<TmpLayout<'tcx>>, LayoutError<'tcx>> {
-                        // The current code for niche-filling relies on variant indices
-                        // instead of actual discriminants, so enums with
-                        // explicit discriminants (RFC #2363) would misbehave.
-                        if def.repr().inhibit_enum_layout_opt()
-                            || def
-                                .variants()
-                                .iter_enumerated()
-                                .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()))
-                        {
-                            return Ok(None);
-                        }
-
-                        if variants.len() < 2 {
-                            return Ok(None);
-                        }
-
-                        let mut align = dl.aggregate_align;
-                        let mut variant_layouts = variants
-                            .iter_enumerated()
-                            .map(|(j, v)| {
-                                let mut st = self.univariant_uninterned(
-                                    ty,
-                                    v,
-                                    &def.repr(),
-                                    StructKind::AlwaysSized,
-                                )?;
-                                st.variants = Variants::Single { index: j };
-
-                                align = align.max(st.align);
-
-                                Ok(st)
-                            })
-                            .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-                        let largest_variant_index = match variant_layouts
-                            .iter_enumerated()
-                            .max_by_key(|(_i, layout)| layout.size.bytes())
-                            .map(|(i, _layout)| i)
-                        {
-                            None => return Ok(None),
-                            Some(i) => i,
-                        };
-
-                        let all_indices = VariantIdx::new(0)..=VariantIdx::new(variants.len() - 1);
-                        let needs_disc = |index: VariantIdx| {
-                            index != largest_variant_index && !absent(&variants[index])
-                        };
-                        let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
-                            ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
-
-                        let count = niche_variants.size_hint().1.unwrap() as u128;
-
-                        // Find the field with the largest niche
-                        let (field_index, niche, (niche_start, niche_scalar)) = match variants
-                            [largest_variant_index]
-                            .iter()
-                            .enumerate()
-                            .filter_map(|(j, field)| Some((j, field.largest_niche?)))
-                            .max_by_key(|(_, niche)| niche.available(dl))
-                            .and_then(|(j, niche)| Some((j, niche, niche.reserve(self, count)?)))
-                        {
-                            None => return Ok(None),
-                            Some(x) => x,
-                        };
-
-                        let niche_offset = niche.offset
-                            + variant_layouts[largest_variant_index].fields.offset(field_index);
-                        let niche_size = niche.value.size(dl);
-                        let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
-
-                        let all_variants_fit =
-                            variant_layouts.iter_enumerated_mut().all(|(i, layout)| {
-                                if i == largest_variant_index {
-                                    return true;
-                                }
-
-                                layout.largest_niche = None;
-
-                                if layout.size <= niche_offset {
-                                    // This variant will fit before the niche.
-                                    return true;
-                                }
-
-                                // Determine if it'll fit after the niche.
-                                let this_align = layout.align.abi;
-                                let this_offset = (niche_offset + niche_size).align_to(this_align);
-
-                                if this_offset + layout.size > size {
-                                    return false;
-                                }
-
-                                // It'll fit, but we need to make some adjustments.
-                                match layout.fields {
-                                    FieldsShape::Arbitrary { ref mut offsets, .. } => {
-                                        for (j, offset) in offsets.iter_mut().enumerate() {
-                                            if !variants[i][j].is_zst() {
-                                                *offset += this_offset;
-                                            }
-                                        }
-                                    }
-                                    _ => {
-                                        panic!("Layout of fields should be Arbitrary for variants")
-                                    }
-                                }
-
-                                // It can't be a Scalar or ScalarPair because the offset isn't 0.
-                                if !layout.abi.is_uninhabited() {
-                                    layout.abi = Abi::Aggregate { sized: true };
-                                }
-                                layout.size += this_offset;
-
-                                true
-                            });
-
-                        if !all_variants_fit {
-                            return Ok(None);
-                        }
-
-                        let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar);
-
-                        let others_zst = variant_layouts.iter_enumerated().all(|(i, layout)| {
-                            i == largest_variant_index || layout.size == Size::ZERO
-                        });
-                        let same_size = size == variant_layouts[largest_variant_index].size;
-                        let same_align = align == variant_layouts[largest_variant_index].align;
-
-                        let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) {
-                            Abi::Uninhabited
-                        } else if same_size && same_align && others_zst {
-                            match variant_layouts[largest_variant_index].abi {
-                                // When the total alignment and size match, we can use the
-                                // same ABI as the scalar variant with the reserved niche.
-                                Abi::Scalar(_) => Abi::Scalar(niche_scalar),
-                                Abi::ScalarPair(first, second) => {
-                                    // Only the niche is guaranteed to be initialised,
-                                    // so use union layouts for the other primitive.
-                                    if niche_offset == Size::ZERO {
-                                        Abi::ScalarPair(niche_scalar, second.to_union())
-                                    } else {
-                                        Abi::ScalarPair(first.to_union(), niche_scalar)
-                                    }
-                                }
-                                _ => Abi::Aggregate { sized: true },
-                            }
-                        } else {
-                            Abi::Aggregate { sized: true }
-                        };
-
-                        let layout = LayoutS {
-                            variants: Variants::Multiple {
-                                tag: niche_scalar,
-                                tag_encoding: TagEncoding::Niche {
-                                    untagged_variant: largest_variant_index,
-                                    niche_variants,
-                                    niche_start,
-                                },
-                                tag_field: 0,
-                                variants: IndexVec::new(),
-                            },
-                            fields: FieldsShape::Arbitrary {
-                                offsets: vec![niche_offset],
-                                memory_index: vec![0],
-                            },
-                            abi,
-                            largest_niche,
-                            size,
-                            align,
-                        };
-
-                        Ok(Some(TmpLayout { layout, variants: variant_layouts }))
-                    };
-
-                let niche_filling_layout = calculate_niche_filling_layout()?;
-
-                let (mut min, mut max) = (i128::MAX, i128::MIN);
-                let discr_type = def.repr().discr_type();
-                let bits = Integer::from_attr(self, discr_type).size().bits();
-                for (i, discr) in def.discriminants(tcx) {
-                    if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
-                        continue;
-                    }
-                    let mut x = discr.val as i128;
-                    if discr_type.is_signed() {
-                        // sign extend the raw representation to be an i128
-                        x = (x << (128 - bits)) >> (128 - bits);
-                    }
-                    if x < min {
-                        min = x;
-                    }
-                    if x > max {
-                        max = x;
-                    }
-                }
-                // We might have no inhabited variants, so pretend there's at least one.
-                if (min, max) == (i128::MAX, i128::MIN) {
-                    min = 0;
-                    max = 0;
-                }
-                assert!(min <= max, "discriminant range is {}...{}", min, max);
-                let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr(), min, max);
-
-                let mut align = dl.aggregate_align;
-                let mut size = Size::ZERO;
-
-                // We're interested in the smallest alignment, so start large.
-                let mut start_align = Align::from_bytes(256).unwrap();
-                assert_eq!(Integer::for_align(dl, start_align), None);
-
-                // repr(C) on an enum tells us to make a (tag, union) layout,
-                // so we need to grow the prefix alignment to be at least
-                // the alignment of the union. (This value is used both for
-                // determining the alignment of the overall enum, and the
-                // determining the alignment of the payload after the tag.)
-                let mut prefix_align = min_ity.align(dl).abi;
-                if def.repr().c() {
-                    for fields in &variants {
-                        for field in fields {
-                            prefix_align = prefix_align.max(field.align.abi);
-                        }
-                    }
-                }
-
-                // Create the set of structs that represent each variant.
-                let mut layout_variants = variants
-                    .iter_enumerated()
-                    .map(|(i, field_layouts)| {
-                        let mut st = self.univariant_uninterned(
-                            ty,
-                            &field_layouts,
-                            &def.repr(),
-                            StructKind::Prefixed(min_ity.size(), prefix_align),
-                        )?;
-                        st.variants = Variants::Single { index: i };
-                        // Find the first field we can't move later
-                        // to make room for a larger discriminant.
-                        for field in
-                            st.fields.index_by_increasing_offset().map(|j| field_layouts[j])
-                        {
-                            if !field.is_zst() || field.align.abi.bytes() != 1 {
-                                start_align = start_align.min(field.align.abi);
-                                break;
-                            }
-                        }
-                        size = cmp::max(size, st.size);
-                        align = align.max(st.align);
-                        Ok(st)
-                    })
-                    .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-                // Align the maximum variant size to the largest alignment.
-                size = size.align_to(align.abi);
-
-                if size.bytes() >= dl.obj_size_bound() {
-                    return Err(LayoutError::SizeOverflow(ty));
-                }
-
-                let typeck_ity = Integer::from_attr(dl, def.repr().discr_type());
-                if typeck_ity < min_ity {
-                    // It is a bug if Layout decided on a greater discriminant size than typeck for
-                    // some reason at this point (based on values discriminant can take on). Mostly
-                    // because this discriminant will be loaded, and then stored into variable of
-                    // type calculated by typeck. Consider such case (a bug): typeck decided on
-                    // byte-sized discriminant, but layout thinks we need a 16-bit to store all
-                    // discriminant values. That would be a bug, because then, in codegen, in order
-                    // to store this 16-bit discriminant into 8-bit sized temporary some of the
-                    // space necessary to represent would have to be discarded (or layout is wrong
-                    // on thinking it needs 16 bits)
-                    bug!(
-                        "layout decided on a larger discriminant type ({:?}) than typeck ({:?})",
-                        min_ity,
-                        typeck_ity
-                    );
-                    // However, it is fine to make discr type however large (as an optimisation)
-                    // after this point – we’ll just truncate the value we load in codegen.
-                }
-
-                // Check to see if we should use a different type for the
-                // discriminant. We can safely use a type with the same size
-                // as the alignment of the first field of each variant.
-                // We increase the size of the discriminant to avoid LLVM copying
-                // padding when it doesn't need to. This normally causes unaligned
-                // load/stores and excessive memcpy/memset operations. By using a
-                // bigger integer size, LLVM can be sure about its contents and
-                // won't be so conservative.
-
-                // Use the initial field alignment
-                let mut ity = if def.repr().c() || def.repr().int.is_some() {
-                    min_ity
-                } else {
-                    Integer::for_align(dl, start_align).unwrap_or(min_ity)
-                };
-
-                // If the alignment is not larger than the chosen discriminant size,
-                // don't use the alignment as the final size.
-                if ity <= min_ity {
-                    ity = min_ity;
-                } else {
-                    // Patch up the variants' first few fields.
-                    let old_ity_size = min_ity.size();
-                    let new_ity_size = ity.size();
-                    for variant in &mut layout_variants {
-                        match variant.fields {
-                            FieldsShape::Arbitrary { ref mut offsets, .. } => {
-                                for i in offsets {
-                                    if *i <= old_ity_size {
-                                        assert_eq!(*i, old_ity_size);
-                                        *i = new_ity_size;
-                                    }
-                                }
-                                // We might be making the struct larger.
-                                if variant.size <= old_ity_size {
-                                    variant.size = new_ity_size;
-                                }
-                            }
-                            _ => bug!(),
-                        }
-                    }
-                }
-
-                let tag_mask = ity.size().unsigned_int_max();
-                let tag = Scalar::Initialized {
-                    value: Int(ity, signed),
-                    valid_range: WrappingRange {
-                        start: (min as u128 & tag_mask),
-                        end: (max as u128 & tag_mask),
-                    },
-                };
-                let mut abi = Abi::Aggregate { sized: true };
-
-                if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
-                    abi = Abi::Uninhabited;
-                } else if tag.size(dl) == size {
-                    // Make sure we only use scalar layout when the enum is entirely its
-                    // own tag (i.e. it has no padding nor any non-ZST variant fields).
-                    abi = Abi::Scalar(tag);
-                } else {
-                    // Try to use a ScalarPair for all tagged enums.
-                    let mut common_prim = None;
-                    let mut common_prim_initialized_in_all_variants = true;
-                    for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) {
-                        let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
-                            bug!();
-                        };
-                        let mut fields =
-                            iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
-                        let (field, offset) = match (fields.next(), fields.next()) {
-                            (None, None) => {
-                                common_prim_initialized_in_all_variants = false;
-                                continue;
-                            }
-                            (Some(pair), None) => pair,
-                            _ => {
-                                common_prim = None;
-                                break;
-                            }
-                        };
-                        let prim = match field.abi {
-                            Abi::Scalar(scalar) => {
-                                common_prim_initialized_in_all_variants &=
-                                    matches!(scalar, Scalar::Initialized { .. });
-                                scalar.primitive()
-                            }
-                            _ => {
-                                common_prim = None;
-                                break;
-                            }
-                        };
-                        if let Some(pair) = common_prim {
-                            // This is pretty conservative. We could go fancier
-                            // by conflating things like i32 and u32, or even
-                            // realising that (u8, u8) could just cohabit with
-                            // u16 or even u32.
-                            if pair != (prim, offset) {
-                                common_prim = None;
-                                break;
-                            }
-                        } else {
-                            common_prim = Some((prim, offset));
-                        }
-                    }
-                    if let Some((prim, offset)) = common_prim {
-                        let prim_scalar = if common_prim_initialized_in_all_variants {
-                            scalar_unit(prim)
-                        } else {
-                            // Common prim might be uninit.
-                            Scalar::Union { value: prim }
-                        };
-                        let pair = self.scalar_pair(tag, prim_scalar);
-                        let pair_offsets = match pair.fields {
-                            FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
-                                assert_eq!(memory_index, &[0, 1]);
-                                offsets
-                            }
-                            _ => bug!(),
-                        };
-                        if pair_offsets[0] == Size::ZERO
-                            && pair_offsets[1] == *offset
-                            && align == pair.align
-                            && size == pair.size
-                        {
-                            // We can use `ScalarPair` only when it matches our
-                            // already computed layout (including `#[repr(C)]`).
-                            abi = pair.abi;
-                        }
-                    }
-                }
-
-                // If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the
-                // variants to ensure they are consistent. This is because a downcast is
-                // semantically a NOP, and thus should not affect layout.
-                if matches!(abi, Abi::Scalar(..) | Abi::ScalarPair(..)) {
-                    for variant in &mut layout_variants {
-                        // We only do this for variants with fields; the others are not accessed anyway.
-                        // Also do not overwrite any already existing "clever" ABIs.
-                        if variant.fields.count() > 0
-                            && matches!(variant.abi, Abi::Aggregate { .. })
-                        {
-                            variant.abi = abi;
-                            // Also need to bump up the size and alignment, so that the entire value fits in here.
-                            variant.size = cmp::max(variant.size, size);
-                            variant.align.abi = cmp::max(variant.align.abi, align.abi);
-                        }
-                    }
-                }
-
-                let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
-
-                let tagged_layout = LayoutS {
-                    variants: Variants::Multiple {
-                        tag,
-                        tag_encoding: TagEncoding::Direct,
-                        tag_field: 0,
-                        variants: IndexVec::new(),
-                    },
-                    fields: FieldsShape::Arbitrary {
-                        offsets: vec![Size::ZERO],
-                        memory_index: vec![0],
-                    },
-                    largest_niche,
-                    abi,
-                    align,
-                    size,
-                };
-
-                let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants };
-
-                let mut best_layout = match (tagged_layout, niche_filling_layout) {
-                    (tl, Some(nl)) => {
-                        // Pick the smaller layout; otherwise,
-                        // pick the layout with the larger niche; otherwise,
-                        // pick tagged as it has simpler codegen.
-                        use Ordering::*;
-                        let niche_size = |tmp_l: &TmpLayout<'_>| {
-                            tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
-                        };
-                        match (
-                            tl.layout.size.cmp(&nl.layout.size),
-                            niche_size(&tl).cmp(&niche_size(&nl)),
-                        ) {
-                            (Greater, _) => nl,
-                            (Equal, Less) => nl,
-                            _ => tl,
-                        }
-                    }
-                    (tl, None) => tl,
-                };
-
-                // Now we can intern the variant layouts and store them in the enum layout.
-                best_layout.layout.variants = match best_layout.layout.variants {
-                    Variants::Multiple { tag, tag_encoding, tag_field, .. } => Variants::Multiple {
-                        tag,
-                        tag_encoding,
-                        tag_field,
-                        variants: best_layout
-                            .variants
-                            .into_iter()
-                            .map(|layout| tcx.intern_layout(layout))
-                            .collect(),
-                    },
-                    _ => bug!(),
-                };
-
-                tcx.intern_layout(best_layout.layout)
-            }
-
-            // Types with no meaningful known layout.
-            ty::Projection(_) | ty::Opaque(..) => {
-                // NOTE(eddyb) `layout_of` query should've normalized these away,
-                // if that was possible, so there's no reason to try again here.
-                return Err(LayoutError::Unknown(ty));
-            }
-
-            ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) => {
-                bug!("Layout::compute: unexpected type `{}`", ty)
-            }
-
-            ty::Bound(..) | ty::Param(_) | ty::Error(_) => {
-                return Err(LayoutError::Unknown(ty));
-            }
-        })
-    }
-}
-
-/// Overlap eligibility and variant assignment for each GeneratorSavedLocal.
-#[derive(Clone, Debug, PartialEq)]
-enum SavedLocalEligibility {
-    Unassigned,
-    Assigned(VariantIdx),
-    // FIXME: Use newtype_index so we aren't wasting bytes
-    Ineligible(Option<u32>),
-}
-
-// When laying out generators, we divide our saved local fields into two
-// categories: overlap-eligible and overlap-ineligible.
-//
-// Those fields which are ineligible for overlap go in a "prefix" at the
-// beginning of the layout, and always have space reserved for them.
-//
-// Overlap-eligible fields are only assigned to one variant, so we lay
-// those fields out for each variant and put them right after the
-// prefix.
-//
-// Finally, in the layout details, we point to the fields from the
-// variants they are assigned to. It is possible for some fields to be
-// included in multiple variants. No field ever "moves around" in the
-// layout; its offset is always the same.
-//
-// Also included in the layout are the upvars and the discriminant.
-// These are included as fields on the "outer" layout; they are not part
-// of any variant.
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
-    /// Compute the eligibility and assignment of each local.
-    fn generator_saved_local_eligibility(
-        &self,
-        info: &GeneratorLayout<'tcx>,
-    ) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) {
-        use SavedLocalEligibility::*;
-
-        let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> =
-            IndexVec::from_elem_n(Unassigned, info.field_tys.len());
-
-        // The saved locals not eligible for overlap. These will get
-        // "promoted" to the prefix of our generator.
-        let mut ineligible_locals = BitSet::new_empty(info.field_tys.len());
-
-        // Figure out which of our saved locals are fields in only
-        // one variant. The rest are deemed ineligible for overlap.
-        for (variant_index, fields) in info.variant_fields.iter_enumerated() {
-            for local in fields {
-                match assignments[*local] {
-                    Unassigned => {
-                        assignments[*local] = Assigned(variant_index);
-                    }
-                    Assigned(idx) => {
-                        // We've already seen this local at another suspension
-                        // point, so it is no longer a candidate.
-                        trace!(
-                            "removing local {:?} in >1 variant ({:?}, {:?})",
-                            local,
-                            variant_index,
-                            idx
-                        );
-                        ineligible_locals.insert(*local);
-                        assignments[*local] = Ineligible(None);
-                    }
-                    Ineligible(_) => {}
-                }
-            }
-        }
-
-        // Next, check every pair of eligible locals to see if they
-        // conflict.
-        for local_a in info.storage_conflicts.rows() {
-            let conflicts_a = info.storage_conflicts.count(local_a);
-            if ineligible_locals.contains(local_a) {
-                continue;
-            }
-
-            for local_b in info.storage_conflicts.iter(local_a) {
-                // local_a and local_b are storage live at the same time, therefore they
-                // cannot overlap in the generator layout. The only way to guarantee
-                // this is if they are in the same variant, or one is ineligible
-                // (which means it is stored in every variant).
-                if ineligible_locals.contains(local_b)
-                    || assignments[local_a] == assignments[local_b]
-                {
-                    continue;
-                }
-
-                // If they conflict, we will choose one to make ineligible.
-                // This is not always optimal; it's just a greedy heuristic that
-                // seems to produce good results most of the time.
-                let conflicts_b = info.storage_conflicts.count(local_b);
-                let (remove, other) =
-                    if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) };
-                ineligible_locals.insert(remove);
-                assignments[remove] = Ineligible(None);
-                trace!("removing local {:?} due to conflict with {:?}", remove, other);
-            }
-        }
-
-        // Count the number of variants in use. If only one of them, then it is
-        // impossible to overlap any locals in our layout. In this case it's
-        // always better to make the remaining locals ineligible, so we can
-        // lay them out with the other locals in the prefix and eliminate
-        // unnecessary padding bytes.
-        {
-            let mut used_variants = BitSet::new_empty(info.variant_fields.len());
-            for assignment in &assignments {
-                if let Assigned(idx) = assignment {
-                    used_variants.insert(*idx);
-                }
-            }
-            if used_variants.count() < 2 {
-                for assignment in assignments.iter_mut() {
-                    *assignment = Ineligible(None);
-                }
-                ineligible_locals.insert_all();
-            }
-        }
-
-        // Write down the order of our locals that will be promoted to the prefix.
-        {
-            for (idx, local) in ineligible_locals.iter().enumerate() {
-                assignments[local] = Ineligible(Some(idx as u32));
-            }
-        }
-        debug!("generator saved local assignments: {:?}", assignments);
-
-        (ineligible_locals, assignments)
-    }
-
-    /// Compute the full generator layout.
-    fn generator_layout(
-        &self,
-        ty: Ty<'tcx>,
-        def_id: hir::def_id::DefId,
-        substs: SubstsRef<'tcx>,
-    ) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
-        use SavedLocalEligibility::*;
-        let tcx = self.tcx;
-        let subst_field = |ty: Ty<'tcx>| EarlyBinder(ty).subst(tcx, substs);
-
-        let Some(info) = tcx.generator_layout(def_id) else {
-            return Err(LayoutError::Unknown(ty));
-        };
-        let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info);
-
-        // Build a prefix layout, including "promoting" all ineligible
-        // locals as part of the prefix. We compute the layout of all of
-        // these fields at once to get optimal packing.
-        let tag_index = substs.as_generator().prefix_tys().count();
-
-        // `info.variant_fields` already accounts for the reserved variants, so no need to add them.
-        let max_discr = (info.variant_fields.len() - 1) as u128;
-        let discr_int = Integer::fit_unsigned(max_discr);
-        let discr_int_ty = discr_int.to_ty(tcx, false);
-        let tag = Scalar::Initialized {
-            value: Primitive::Int(discr_int, false),
-            valid_range: WrappingRange { start: 0, end: max_discr },
-        };
-        let tag_layout = self.tcx.intern_layout(LayoutS::scalar(self, tag));
-        let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout };
-
-        let promoted_layouts = ineligible_locals
-            .iter()
-            .map(|local| subst_field(info.field_tys[local]))
-            .map(|ty| tcx.mk_maybe_uninit(ty))
-            .map(|ty| self.layout_of(ty));
-        let prefix_layouts = substs
-            .as_generator()
-            .prefix_tys()
-            .map(|ty| self.layout_of(ty))
-            .chain(iter::once(Ok(tag_layout)))
-            .chain(promoted_layouts)
-            .collect::<Result<Vec<_>, _>>()?;
-        let prefix = self.univariant_uninterned(
-            ty,
-            &prefix_layouts,
-            &ReprOptions::default(),
-            StructKind::AlwaysSized,
-        )?;
-
-        let (prefix_size, prefix_align) = (prefix.size, prefix.align);
-
-        // Split the prefix layout into the "outer" fields (upvars and
-        // discriminant) and the "promoted" fields. Promoted fields will
-        // get included in each variant that requested them in
-        // GeneratorLayout.
-        debug!("prefix = {:#?}", prefix);
-        let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
-            FieldsShape::Arbitrary { mut offsets, memory_index } => {
-                let mut inverse_memory_index = invert_mapping(&memory_index);
-
-                // "a" (`0..b_start`) and "b" (`b_start..`) correspond to
-                // "outer" and "promoted" fields respectively.
-                let b_start = (tag_index + 1) as u32;
-                let offsets_b = offsets.split_off(b_start as usize);
-                let offsets_a = offsets;
-
-                // Disentangle the "a" and "b" components of `inverse_memory_index`
-                // by preserving the order but keeping only one disjoint "half" each.
-                // FIXME(eddyb) build a better abstraction for permutations, if possible.
-                let inverse_memory_index_b: Vec<_> =
-                    inverse_memory_index.iter().filter_map(|&i| i.checked_sub(b_start)).collect();
-                inverse_memory_index.retain(|&i| i < b_start);
-                let inverse_memory_index_a = inverse_memory_index;
-
-                // Since `inverse_memory_index_{a,b}` each only refer to their
-                // respective fields, they can be safely inverted
-                let memory_index_a = invert_mapping(&inverse_memory_index_a);
-                let memory_index_b = invert_mapping(&inverse_memory_index_b);
-
-                let outer_fields =
-                    FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
-                (outer_fields, offsets_b, memory_index_b)
-            }
-            _ => bug!(),
-        };
-
-        let mut size = prefix.size;
-        let mut align = prefix.align;
-        let variants = info
-            .variant_fields
-            .iter_enumerated()
-            .map(|(index, variant_fields)| {
-                // Only include overlap-eligible fields when we compute our variant layout.
-                let variant_only_tys = variant_fields
-                    .iter()
-                    .filter(|local| match assignments[**local] {
-                        Unassigned => bug!(),
-                        Assigned(v) if v == index => true,
-                        Assigned(_) => bug!("assignment does not match variant"),
-                        Ineligible(_) => false,
-                    })
-                    .map(|local| subst_field(info.field_tys[*local]));
-
-                let mut variant = self.univariant_uninterned(
-                    ty,
-                    &variant_only_tys
-                        .map(|ty| self.layout_of(ty))
-                        .collect::<Result<Vec<_>, _>>()?,
-                    &ReprOptions::default(),
-                    StructKind::Prefixed(prefix_size, prefix_align.abi),
-                )?;
-                variant.variants = Variants::Single { index };
-
-                let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else {
-                    bug!();
-                };
-
-                // Now, stitch the promoted and variant-only fields back together in
-                // the order they are mentioned by our GeneratorLayout.
-                // Because we only use some subset (that can differ between variants)
-                // of the promoted fields, we can't just pick those elements of the
-                // `promoted_memory_index` (as we'd end up with gaps).
-                // So instead, we build an "inverse memory_index", as if all of the
-                // promoted fields were being used, but leave the elements not in the
-                // subset as `INVALID_FIELD_IDX`, which we can filter out later to
-                // obtain a valid (bijective) mapping.
-                const INVALID_FIELD_IDX: u32 = !0;
-                let mut combined_inverse_memory_index =
-                    vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()];
-                let mut offsets_and_memory_index = iter::zip(offsets, memory_index);
-                let combined_offsets = variant_fields
-                    .iter()
-                    .enumerate()
-                    .map(|(i, local)| {
-                        let (offset, memory_index) = match assignments[*local] {
-                            Unassigned => bug!(),
-                            Assigned(_) => {
-                                let (offset, memory_index) =
-                                    offsets_and_memory_index.next().unwrap();
-                                (offset, promoted_memory_index.len() as u32 + memory_index)
-                            }
-                            Ineligible(field_idx) => {
-                                let field_idx = field_idx.unwrap() as usize;
-                                (promoted_offsets[field_idx], promoted_memory_index[field_idx])
-                            }
-                        };
-                        combined_inverse_memory_index[memory_index as usize] = i as u32;
-                        offset
-                    })
-                    .collect();
-
-                // Remove the unused slots and invert the mapping to obtain the
-                // combined `memory_index` (also see previous comment).
-                combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX);
-                let combined_memory_index = invert_mapping(&combined_inverse_memory_index);
-
-                variant.fields = FieldsShape::Arbitrary {
-                    offsets: combined_offsets,
-                    memory_index: combined_memory_index,
-                };
-
-                size = size.max(variant.size);
-                align = align.max(variant.align);
-                Ok(tcx.intern_layout(variant))
-            })
-            .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
-
-        size = size.align_to(align.abi);
-
-        let abi =
-            if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi().is_uninhabited()) {
-                Abi::Uninhabited
-            } else {
-                Abi::Aggregate { sized: true }
-            };
-
-        let layout = tcx.intern_layout(LayoutS {
-            variants: Variants::Multiple {
-                tag,
-                tag_encoding: TagEncoding::Direct,
-                tag_field: tag_index,
-                variants,
-            },
-            fields: outer_fields,
-            abi,
-            largest_niche: prefix.largest_niche,
-            size,
-            align,
-        });
-        debug!("generator layout ({:?}): {:#?}", ty, layout);
-        Ok(layout)
-    }
-
-    /// This is invoked by the `layout_of` query to record the final
-    /// layout of each type.
-    #[inline(always)]
-    fn record_layout_for_printing(&self, layout: TyAndLayout<'tcx>) {
-        // If we are running with `-Zprint-type-sizes`, maybe record layouts
-        // for dumping later.
-        if self.tcx.sess.opts.unstable_opts.print_type_sizes {
-            self.record_layout_for_printing_outlined(layout)
-        }
-    }
-
-    fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) {
-        // Ignore layouts that are done with non-empty environments or
-        // non-monomorphic layouts, as the user only wants to see the stuff
-        // resulting from the final codegen session.
-        if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds().is_empty() {
-            return;
-        }
-
-        // (delay format until we actually need it)
-        let record = |kind, packed, opt_discr_size, variants| {
-            let type_desc = format!("{:?}", layout.ty);
-            self.tcx.sess.code_stats.record_type_size(
-                kind,
-                type_desc,
-                layout.align.abi,
-                layout.size,
-                packed,
-                opt_discr_size,
-                variants,
-            );
-        };
-
-        let adt_def = match *layout.ty.kind() {
-            ty::Adt(ref adt_def, _) => {
-                debug!("print-type-size t: `{:?}` process adt", layout.ty);
-                adt_def
-            }
-
-            ty::Closure(..) => {
-                debug!("print-type-size t: `{:?}` record closure", layout.ty);
-                record(DataTypeKind::Closure, false, None, vec![]);
-                return;
-            }
-
-            _ => {
-                debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
-                return;
-            }
-        };
-
-        let adt_kind = adt_def.adt_kind();
-        let adt_packed = adt_def.repr().pack.is_some();
-
-        let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
-            let mut min_size = Size::ZERO;
-            let field_info: Vec<_> = flds
-                .iter()
-                .enumerate()
-                .map(|(i, &name)| {
-                    let field_layout = layout.field(self, i);
-                    let offset = layout.fields.offset(i);
-                    let field_end = offset + field_layout.size;
-                    if min_size < field_end {
-                        min_size = field_end;
-                    }
-                    FieldInfo {
-                        name,
-                        offset: offset.bytes(),
-                        size: field_layout.size.bytes(),
-                        align: field_layout.align.abi.bytes(),
-                    }
-                })
-                .collect();
-
-            VariantInfo {
-                name: n,
-                kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact },
-                align: layout.align.abi.bytes(),
-                size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() },
-                fields: field_info,
-            }
-        };
-
-        match layout.variants {
-            Variants::Single { index } => {
-                if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive {
-                    debug!(
-                        "print-type-size `{:#?}` variant {}",
-                        layout,
-                        adt_def.variant(index).name
-                    );
-                    let variant_def = &adt_def.variant(index);
-                    let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
-                    record(
-                        adt_kind.into(),
-                        adt_packed,
-                        None,
-                        vec![build_variant_info(Some(variant_def.name), &fields, layout)],
-                    );
-                } else {
-                    // (This case arises for *empty* enums; so give it
-                    // zero variants.)
-                    record(adt_kind.into(), adt_packed, None, vec![]);
-                }
-            }
-
-            Variants::Multiple { tag, ref tag_encoding, .. } => {
-                debug!(
-                    "print-type-size `{:#?}` adt general variants def {}",
-                    layout.ty,
-                    adt_def.variants().len()
-                );
-                let variant_infos: Vec<_> = adt_def
-                    .variants()
-                    .iter_enumerated()
-                    .map(|(i, variant_def)| {
-                        let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
-                        build_variant_info(
-                            Some(variant_def.name),
-                            &fields,
-                            layout.for_variant(self, i),
-                        )
-                    })
-                    .collect();
-                record(
-                    adt_kind.into(),
-                    adt_packed,
-                    match tag_encoding {
-                        TagEncoding::Direct => Some(tag.size(self)),
-                        _ => None,
-                    },
-                    variant_infos,
-                );
-            }
-        }
-    }
-}
-
 /// Type size "skeleton", i.e., the only information determining a type's size.
 /// While this is conservative, (aside from constant sizes, only pointers,
 /// newtypes thereof and null pointer optimized enums are allowed), it is
@@ -2057,7 +244,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> {
-        debug_assert!(!ty.has_infer_types_or_consts());
+        debug_assert!(!ty.has_non_region_infer());
 
         // First try computing a static layout.
         let err = match tcx.layout_of(param_env.and(ty)) {
@@ -2073,7 +260,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
                 let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
                 match tail.kind() {
                     ty::Param(_) | ty::Projection(_) => {
-                        debug_assert!(tail.has_param_types_or_consts());
+                        debug_assert!(tail.has_non_region_param());
                         Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) })
                     }
                     _ => bug!(
@@ -2747,117 +934,6 @@ where
     }
 }
 
-impl<'tcx> ty::Instance<'tcx> {
-    // NOTE(eddyb) this is private to avoid using it from outside of
-    // `fn_abi_of_instance` - any other uses are either too high-level
-    // for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
-    // or should go through `FnAbi` instead, to avoid losing any
-    // adjustments `fn_abi_of_instance` might be performing.
-    #[tracing::instrument(level = "debug", skip(tcx, param_env))]
-    fn fn_sig_for_fn_abi(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> ty::PolyFnSig<'tcx> {
-        let ty = self.ty(tcx, param_env);
-        match *ty.kind() {
-            ty::FnDef(..) => {
-                // HACK(davidtwco,eddyb): This is a workaround for polymorphization considering
-                // parameters unused if they show up in the signature, but not in the `mir::Body`
-                // (i.e. due to being inside a projection that got normalized, see
-                // `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping
-                // track of a polymorphization `ParamEnv` to allow normalizing later.
-                //
-                // We normalize the `fn_sig` again after substituting at a later point.
-                let mut sig = match *ty.kind() {
-                    ty::FnDef(def_id, substs) => tcx
-                        .bound_fn_sig(def_id)
-                        .map_bound(|fn_sig| {
-                            tcx.normalize_erasing_regions(tcx.param_env(def_id), fn_sig)
-                        })
-                        .subst(tcx, substs),
-                    _ => unreachable!(),
-                };
-
-                if let ty::InstanceDef::VTableShim(..) = self.def {
-                    // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
-                    sig = sig.map_bound(|mut sig| {
-                        let mut inputs_and_output = sig.inputs_and_output.to_vec();
-                        inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]);
-                        sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
-                        sig
-                    });
-                }
-                sig
-            }
-            ty::Closure(def_id, substs) => {
-                let sig = substs.as_closure().sig();
-
-                let bound_vars = tcx.mk_bound_variable_kinds(
-                    sig.bound_vars()
-                        .iter()
-                        .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
-                );
-                let br = ty::BoundRegion {
-                    var: ty::BoundVar::from_usize(bound_vars.len() - 1),
-                    kind: ty::BoundRegionKind::BrEnv,
-                };
-                let env_region = ty::ReLateBound(ty::INNERMOST, br);
-                let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
-
-                let sig = sig.skip_binder();
-                ty::Binder::bind_with_vars(
-                    tcx.mk_fn_sig(
-                        iter::once(env_ty).chain(sig.inputs().iter().cloned()),
-                        sig.output(),
-                        sig.c_variadic,
-                        sig.unsafety,
-                        sig.abi,
-                    ),
-                    bound_vars,
-                )
-            }
-            ty::Generator(_, substs, _) => {
-                let sig = substs.as_generator().poly_sig();
-
-                let bound_vars = tcx.mk_bound_variable_kinds(
-                    sig.bound_vars()
-                        .iter()
-                        .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
-                );
-                let br = ty::BoundRegion {
-                    var: ty::BoundVar::from_usize(bound_vars.len() - 1),
-                    kind: ty::BoundRegionKind::BrEnv,
-                };
-                let env_region = ty::ReLateBound(ty::INNERMOST, br);
-                let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
-
-                let pin_did = tcx.require_lang_item(LangItem::Pin, None);
-                let pin_adt_ref = tcx.adt_def(pin_did);
-                let pin_substs = tcx.intern_substs(&[env_ty.into()]);
-                let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
-
-                let sig = sig.skip_binder();
-                let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
-                let state_adt_ref = tcx.adt_def(state_did);
-                let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
-                let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
-                ty::Binder::bind_with_vars(
-                    tcx.mk_fn_sig(
-                        [env_ty, sig.resume_ty].iter(),
-                        &ret_ty,
-                        false,
-                        hir::Unsafety::Normal,
-                        rustc_target::spec::abi::Abi::Rust,
-                    ),
-                    bound_vars,
-                )
-            }
-            _ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
-        }
-    }
-}
-
 /// Calculates whether a function's ABI can unwind or not.
 ///
 /// This takes two primary parameters:
@@ -3000,40 +1076,6 @@ pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: Spe
     }
 }
 
-#[inline]
-pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
-    use rustc_target::spec::abi::Abi::*;
-    match tcx.sess.target.adjust_abi(abi) {
-        RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
-        RustCold => Conv::RustCold,
-
-        // It's the ABI's job to select this, not ours.
-        System { .. } => bug!("system abi should be selected elsewhere"),
-        EfiApi => bug!("eficall abi should be selected elsewhere"),
-
-        Stdcall { .. } => Conv::X86Stdcall,
-        Fastcall { .. } => Conv::X86Fastcall,
-        Vectorcall { .. } => Conv::X86VectorCall,
-        Thiscall { .. } => Conv::X86ThisCall,
-        C { .. } => Conv::C,
-        Unadjusted => Conv::C,
-        Win64 { .. } => Conv::X86_64Win64,
-        SysV64 { .. } => Conv::X86_64SysV,
-        Aapcs { .. } => Conv::ArmAapcs,
-        CCmseNonSecureCall => Conv::CCmseNonSecureCall,
-        PtxKernel => Conv::PtxKernel,
-        Msp430Interrupt => Conv::Msp430Intr,
-        X86Interrupt => Conv::X86Intr,
-        AmdGpuKernel => Conv::AmdGpuKernel,
-        AvrInterrupt => Conv::AvrInterrupt,
-        AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
-        Wasm => Conv::C,
-
-        // These API constants ought to be more specific...
-        Cdecl { .. } => Conv::C,
-    }
-}
-
 /// Error produced by attempting to compute or adjust a `FnAbi`.
 #[derive(Copy, Clone, Debug, HashStable)]
 pub enum FnAbiError<'tcx> {
@@ -3065,6 +1107,12 @@ impl<'tcx> fmt::Display for FnAbiError<'tcx> {
     }
 }
 
+impl<'tcx> IntoDiagnostic<'tcx, !> for FnAbiError<'tcx> {
+    fn into_diagnostic(self, handler: &'tcx Handler) -> DiagnosticBuilder<'tcx, !> {
+        handler.struct_fatal(self.to_string())
+    }
+}
+
 // FIXME(eddyb) maybe use something like this for an unified `fn_abi_of`, not
 // just for error handling.
 #[derive(Debug)]
@@ -3146,367 +1194,3 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
 }
 
 impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {}
-
-fn fn_abi_of_fn_ptr<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
-) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
-    let (param_env, (sig, extra_args)) = query.into_parts();
-
-    LayoutCx { tcx, param_env }.fn_abi_new_uncached(sig, extra_args, None, None, false)
-}
-
-fn fn_abi_of_instance<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
-) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
-    let (param_env, (instance, extra_args)) = query.into_parts();
-
-    let sig = instance.fn_sig_for_fn_abi(tcx, param_env);
-
-    let caller_location = if instance.def.requires_caller_location(tcx) {
-        Some(tcx.caller_location_ty())
-    } else {
-        None
-    };
-
-    LayoutCx { tcx, param_env }.fn_abi_new_uncached(
-        sig,
-        extra_args,
-        caller_location,
-        Some(instance.def_id()),
-        matches!(instance.def, ty::InstanceDef::Virtual(..)),
-    )
-}
-
-// Handle safe Rust thin and fat pointers.
-pub fn adjust_for_rust_scalar<'tcx>(
-    cx: LayoutCx<'tcx, TyCtxt<'tcx>>,
-    attrs: &mut ArgAttributes,
-    scalar: Scalar,
-    layout: TyAndLayout<'tcx>,
-    offset: Size,
-    is_return: bool,
-) {
-    // Booleans are always a noundef i1 that needs to be zero-extended.
-    if scalar.is_bool() {
-        attrs.ext(ArgExtension::Zext);
-        attrs.set(ArgAttribute::NoUndef);
-        return;
-    }
-
-    // Scalars which have invalid values cannot be undef.
-    if !scalar.is_always_valid(&cx) {
-        attrs.set(ArgAttribute::NoUndef);
-    }
-
-    // Only pointer types handled below.
-    let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return };
-
-    if !valid_range.contains(0) {
-        attrs.set(ArgAttribute::NonNull);
-    }
-
-    if let Some(pointee) = layout.pointee_info_at(&cx, offset) {
-        if let Some(kind) = pointee.safe {
-            attrs.pointee_align = Some(pointee.align);
-
-            // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable
-            // for the entire duration of the function as they can be deallocated
-            // at any time. Same for shared mutable references. If LLVM had a
-            // way to say "dereferenceable on entry" we could use it here.
-            attrs.pointee_size = match kind {
-                PointerKind::UniqueBorrowed
-                | PointerKind::UniqueBorrowedPinned
-                | PointerKind::Frozen => pointee.size,
-                PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO,
-            };
-
-            // `Box`, `&T`, and `&mut T` cannot be undef.
-            // Note that this only applies to the value of the pointer itself;
-            // this attribute doesn't make it UB for the pointed-to data to be undef.
-            attrs.set(ArgAttribute::NoUndef);
-
-            // The aliasing rules for `Box<T>` are still not decided, but currently we emit
-            // `noalias` for it. This can be turned off using an unstable flag.
-            // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
-            let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true);
-
-            // `&mut` pointer parameters never alias other parameters,
-            // or mutable global data
-            //
-            // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
-            // and can be marked as both `readonly` and `noalias`, as
-            // LLVM's definition of `noalias` is based solely on memory
-            // dependencies rather than pointer equality
-            //
-            // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute
-            // for UniqueBorrowed arguments, so that the codegen backend can decide whether
-            // or not to actually emit the attribute. It can also be controlled with the
-            // `-Zmutable-noalias` debugging option.
-            let no_alias = match kind {
-                PointerKind::SharedMutable
-                | PointerKind::UniqueBorrowed
-                | PointerKind::UniqueBorrowedPinned => false,
-                PointerKind::UniqueOwned => noalias_for_box,
-                PointerKind::Frozen => !is_return,
-            };
-            if no_alias {
-                attrs.set(ArgAttribute::NoAlias);
-            }
-
-            if kind == PointerKind::Frozen && !is_return {
-                attrs.set(ArgAttribute::ReadOnly);
-            }
-
-            if kind == PointerKind::UniqueBorrowed && !is_return {
-                attrs.set(ArgAttribute::NoAliasMutRef);
-            }
-        }
-    }
-}
-
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
-    // FIXME(eddyb) perhaps group the signature/type-containing (or all of them?)
-    // arguments of this method, into a separate `struct`.
-    #[tracing::instrument(
-        level = "debug",
-        skip(self, caller_location, fn_def_id, force_thin_self_ptr)
-    )]
-    fn fn_abi_new_uncached(
-        &self,
-        sig: ty::PolyFnSig<'tcx>,
-        extra_args: &[Ty<'tcx>],
-        caller_location: Option<Ty<'tcx>>,
-        fn_def_id: Option<DefId>,
-        // FIXME(eddyb) replace this with something typed, like an `enum`.
-        force_thin_self_ptr: bool,
-    ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
-        let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig);
-
-        let conv = conv_from_spec_abi(self.tcx(), sig.abi);
-
-        let mut inputs = sig.inputs();
-        let extra_args = if sig.abi == RustCall {
-            assert!(!sig.c_variadic && extra_args.is_empty());
-
-            if let Some(input) = sig.inputs().last() {
-                if let ty::Tuple(tupled_arguments) = input.kind() {
-                    inputs = &sig.inputs()[0..sig.inputs().len() - 1];
-                    tupled_arguments
-                } else {
-                    bug!(
-                        "argument to function with \"rust-call\" ABI \
-                            is not a tuple"
-                    );
-                }
-            } else {
-                bug!(
-                    "argument to function with \"rust-call\" ABI \
-                        is not a tuple"
-                );
-            }
-        } else {
-            assert!(sig.c_variadic || extra_args.is_empty());
-            extra_args
-        };
-
-        let target = &self.tcx.sess.target;
-        let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
-        let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
-        let linux_s390x_gnu_like =
-            target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
-        let linux_sparc64_gnu_like =
-            target.os == "linux" && target.arch == "sparc64" && target_env_gnu_like;
-        let linux_powerpc_gnu_like =
-            target.os == "linux" && target.arch == "powerpc" && target_env_gnu_like;
-        use SpecAbi::*;
-        let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall);
-
-        let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
-            let span = tracing::debug_span!("arg_of");
-            let _entered = span.enter();
-            let is_return = arg_idx.is_none();
-
-            let layout = self.layout_of(ty)?;
-            let layout = if force_thin_self_ptr && arg_idx == Some(0) {
-                // Don't pass the vtable, it's not an argument of the virtual fn.
-                // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
-                // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
-                make_thin_self_ptr(self, layout)
-            } else {
-                layout
-            };
-
-            let mut arg = ArgAbi::new(self, layout, |layout, scalar, offset| {
-                let mut attrs = ArgAttributes::new();
-                adjust_for_rust_scalar(*self, &mut attrs, scalar, *layout, offset, is_return);
-                attrs
-            });
-
-            if arg.layout.is_zst() {
-                // For some forsaken reason, x86_64-pc-windows-gnu
-                // doesn't ignore zero-sized struct arguments.
-                // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}.
-                if is_return
-                    || rust_abi
-                    || (!win_x64_gnu
-                        && !linux_s390x_gnu_like
-                        && !linux_sparc64_gnu_like
-                        && !linux_powerpc_gnu_like)
-                {
-                    arg.mode = PassMode::Ignore;
-                }
-            }
-
-            Ok(arg)
-        };
-
-        let mut fn_abi = FnAbi {
-            ret: arg_of(sig.output(), None)?,
-            args: inputs
-                .iter()
-                .copied()
-                .chain(extra_args.iter().copied())
-                .chain(caller_location)
-                .enumerate()
-                .map(|(i, ty)| arg_of(ty, Some(i)))
-                .collect::<Result<_, _>>()?,
-            c_variadic: sig.c_variadic,
-            fixed_count: inputs.len() as u32,
-            conv,
-            can_unwind: fn_can_unwind(self.tcx(), fn_def_id, sig.abi),
-        };
-        self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?;
-        debug!("fn_abi_new_uncached = {:?}", fn_abi);
-        Ok(self.tcx.arena.alloc(fn_abi))
-    }
-
-    #[tracing::instrument(level = "trace", skip(self))]
-    fn fn_abi_adjust_for_abi(
-        &self,
-        fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
-        abi: SpecAbi,
-    ) -> Result<(), FnAbiError<'tcx>> {
-        if abi == SpecAbi::Unadjusted {
-            return Ok(());
-        }
-
-        if abi == SpecAbi::Rust
-            || abi == SpecAbi::RustCall
-            || abi == SpecAbi::RustIntrinsic
-            || abi == SpecAbi::PlatformIntrinsic
-        {
-            let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| {
-                if arg.is_ignore() {
-                    return;
-                }
-
-                match arg.layout.abi {
-                    Abi::Aggregate { .. } => {}
-
-                    // This is a fun case! The gist of what this is doing is
-                    // that we want callers and callees to always agree on the
-                    // ABI of how they pass SIMD arguments. If we were to *not*
-                    // make these arguments indirect then they'd be immediates
-                    // in LLVM, which means that they'd used whatever the
-                    // appropriate ABI is for the callee and the caller. That
-                    // means, for example, if the caller doesn't have AVX
-                    // enabled but the callee does, then passing an AVX argument
-                    // across this boundary would cause corrupt data to show up.
-                    //
-                    // This problem is fixed by unconditionally passing SIMD
-                    // arguments through memory between callers and callees
-                    // which should get them all to agree on ABI regardless of
-                    // target feature sets. Some more information about this
-                    // issue can be found in #44367.
-                    //
-                    // Note that the platform intrinsic ABI is exempt here as
-                    // that's how we connect up to LLVM and it's unstable
-                    // anyway, we control all calls to it in libstd.
-                    Abi::Vector { .. }
-                        if abi != SpecAbi::PlatformIntrinsic
-                            && self.tcx.sess.target.simd_types_indirect =>
-                    {
-                        arg.make_indirect();
-                        return;
-                    }
-
-                    _ => return,
-                }
-
-                let size = arg.layout.size;
-                if arg.layout.is_unsized() || size > Pointer.size(self) {
-                    arg.make_indirect();
-                } else {
-                    // We want to pass small aggregates as immediates, but using
-                    // a LLVM aggregate type for this leads to bad optimizations,
-                    // so we pick an appropriately sized integer type instead.
-                    arg.cast_to(Reg { kind: RegKind::Integer, size });
-                }
-            };
-            fixup(&mut fn_abi.ret);
-            for arg in fn_abi.args.iter_mut() {
-                fixup(arg);
-            }
-        } else {
-            fn_abi.adjust_for_foreign_abi(self, abi)?;
-        }
-
-        Ok(())
-    }
-}
-
-#[tracing::instrument(level = "debug", skip(cx))]
-fn make_thin_self_ptr<'tcx>(
-    cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
-    layout: TyAndLayout<'tcx>,
-) -> TyAndLayout<'tcx> {
-    let tcx = cx.tcx();
-    let fat_pointer_ty = if layout.is_unsized() {
-        // unsized `self` is passed as a pointer to `self`
-        // FIXME (mikeyhew) change this to use &own if it is ever added to the language
-        tcx.mk_mut_ptr(layout.ty)
-    } else {
-        match layout.abi {
-            Abi::ScalarPair(..) | Abi::Scalar(..) => (),
-            _ => bug!("receiver type has unsupported layout: {:?}", layout),
-        }
-
-        // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
-        // with a Scalar (not ScalarPair) ABI. This is a hack that is understood
-        // elsewhere in the compiler as a method on a `dyn Trait`.
-        // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
-        // get a built-in pointer type
-        let mut fat_pointer_layout = layout;
-        'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
-            && !fat_pointer_layout.ty.is_region_ptr()
-        {
-            for i in 0..fat_pointer_layout.fields.count() {
-                let field_layout = fat_pointer_layout.field(cx, i);
-
-                if !field_layout.is_zst() {
-                    fat_pointer_layout = field_layout;
-                    continue 'descend_newtypes;
-                }
-            }
-
-            bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
-        }
-
-        fat_pointer_layout.ty
-    };
-
-    // we now have a type like `*mut RcBox<dyn Trait>`
-    // change its layout to that of `*mut ()`, a thin pointer, but keep the same type
-    // this is understood as a special case elsewhere in the compiler
-    let unit_ptr_ty = tcx.mk_mut_ptr(tcx.mk_unit());
-
-    TyAndLayout {
-        ty: fat_pointer_ty,
-
-        // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result`
-        // should always work because the type is always `*mut ()`.
-        ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap()
-    }
-}
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 63dd213a085..753d7bffe84 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -130,7 +130,6 @@ mod erase_regions;
 mod generics;
 mod impls_ty;
 mod instance;
-mod layout_sanity_check;
 mod list;
 mod parameterized;
 mod rvalue_scopes;
@@ -2593,7 +2592,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
     closure::provide(providers);
     context::provide(providers);
     erase_regions::provide(providers);
-    layout::provide(providers);
     util::provide(providers);
     print::provide(providers);
     super::util::bug::provide(providers);
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 9c8dc30e2db..0257ca7b29c 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -1,3 +1,4 @@
+use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{DefId, DefIndex};
 use rustc_index::vec::{Idx, IndexVec};
 
@@ -29,6 +30,10 @@ impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVe
     type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
 }
 
+impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for FxHashMap<I, T> {
+    type Value<'tcx> = FxHashMap<I, T::Value<'tcx>>;
+}
+
 impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
     type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
 }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 70efa748846..82d7c0a97cb 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -927,7 +927,7 @@ pub trait PrettyPrinter<'tcx>:
                         // unless we can find out what generator return type it comes from.
                         let term = if let Some(ty) = term.skip_binder().ty()
                             && let ty::Projection(proj) = ty.kind()
-                            && let assoc = tcx.associated_item(proj.item_def_id)
+                            && let Some(assoc) = tcx.opt_associated_item(proj.item_def_id)
                             && assoc.trait_container(tcx) == tcx.lang_items().gen_trait()
                             && assoc.name == rustc_span::sym::Return
                         {
@@ -2173,10 +2173,16 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
 
         let mut region_index = self.region_index;
         let mut next_name = |this: &Self| {
-            let name = name_by_region_index(region_index, &mut available_names, num_available);
-            debug!(?name);
-            region_index += 1;
-            assert!(!this.used_region_names.contains(&name));
+            let mut name;
+
+            loop {
+                name = name_by_region_index(region_index, &mut available_names, num_available);
+                region_index += 1;
+
+                if !this.used_region_names.contains(&name) {
+                    break;
+                }
+            }
 
             name
         };
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 169da348a29..b6cda34c51f 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -1,6 +1,6 @@
 use crate::dep_graph;
 use crate::infer::canonical::{self, Canonical};
-use crate::lint::LintLevelMap;
+use crate::lint::LintExpectation;
 use crate::metadata::ModChild;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
@@ -51,6 +51,7 @@ use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
 use rustc_session::cstore::{CrateDepKind, CrateSource};
 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
+use rustc_session::lint::LintExpectationId;
 use rustc_session::utils::NativeLibKind;
 use rustc_session::Limits;
 use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index a939be32fff..36eb2ab5157 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -492,6 +492,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
 }
 
 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> {
+    #[inline]
     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         self.iter().try_for_each(|t| t.visit_with(visitor))
     }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index d93aab04e99..713f9067a85 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1289,12 +1289,24 @@ pub fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         .any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
 }
 
+/// Determines whether an item is annotated with `doc(notable_trait)`.
+pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+    tcx.get_attrs(def_id, sym::doc)
+        .filter_map(|attr| attr.meta_item_list())
+        .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait)))
+}
+
 /// Determines whether an item is an intrinsic by Abi.
 pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     matches!(tcx.fn_sig(def_id).abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
 }
 
 pub fn provide(providers: &mut ty::query::Providers) {
-    *providers =
-        ty::query::Providers { normalize_opaque_types, is_doc_hidden, is_intrinsic, ..*providers }
+    *providers = ty::query::Providers {
+        normalize_opaque_types,
+        is_doc_hidden,
+        is_doc_notable_trait,
+        is_intrinsic,
+        ..*providers
+    }
 }
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 9c3b6a794e1..44efb93a53b 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -104,8 +104,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone {
             None
         }
     }
-    fn has_param_types_or_consts(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
+    fn has_non_region_param(&self) -> bool {
+        self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM)
     }
     fn has_infer_regions(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_RE_INFER)
@@ -113,8 +113,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone {
     fn has_infer_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_INFER)
     }
-    fn has_infer_types_or_consts(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_CT_INFER)
+    fn has_non_region_infer(&self) -> bool {
+        self.has_type_flags(TypeFlags::NEEDS_INFER - TypeFlags::HAS_RE_INFER)
     }
     fn needs_infer(&self) -> bool {
         self.has_type_flags(TypeFlags::NEEDS_INFER)
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 495738ebe1c..5e8ce65daf0 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -89,15 +89,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
                     UNSAFE_OP_IN_UNSAFE_FN,
                     self.hir_context,
                     span,
-                    |lint| {
-                        lint.build(&format!(
-                            "{} is unsafe and requires unsafe block (error E0133)",
-                            description,
-                        ))
-                        .span_label(span, kind.simple_description())
-                        .note(note)
-                        .emit();
-                    },
+                    format!("{} is unsafe and requires unsafe block (error E0133)", description,),
+                    |lint| lint.span_label(span, kind.simple_description()).note(note),
                 )
             }
             SafetyContext::Safe => {
@@ -125,14 +118,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
         enclosing_unsafe: Option<(Span, &'static str)>,
     ) {
         let block_span = self.tcx.sess.source_map().guess_head_span(block_span);
-        self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, |lint| {
-            let msg = "unnecessary `unsafe` block";
-            let mut db = lint.build(msg);
-            db.span_label(block_span, msg);
+        let msg = "unnecessary `unsafe` block";
+        self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, msg, |lint| {
+            lint.span_label(block_span, msg);
             if let Some((span, kind)) = enclosing_unsafe {
-                db.span_label(span, format!("because it's nested under this `unsafe` {}", kind));
+                lint.span_label(span, format!("because it's nested under this `unsafe` {}", kind));
             }
-            db.emit();
+            lint
         });
     }
 
@@ -364,7 +356,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     // If the called function has target features the calling function hasn't,
                     // the call requires `unsafe`. Don't check this on wasm
                     // targets, though. For more information on wasm see the
-                    // is_like_wasm check in typeck/src/collect.rs
+                    // is_like_wasm check in hir_analysis/src/collect.rs
                     if !self.tcx.sess.target.options.is_like_wasm
                         && !self
                             .tcx
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index 54d549fd66c..b21f30efce8 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -36,16 +36,20 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
 
         let sp = tcx.def_span(def_id);
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-        tcx.struct_span_lint_hir(UNCONDITIONAL_RECURSION, hir_id, sp, |lint| {
-            let mut db = lint.build("function cannot return without recursing");
-            db.span_label(sp, "cannot return without recursing");
-            // offer some help to the programmer.
-            for call_span in vis.reachable_recursive_calls {
-                db.span_label(call_span, "recursive call site");
-            }
-            db.help("a `loop` may express intention better if this is on purpose");
-            db.emit();
-        });
+        tcx.struct_span_lint_hir(
+            UNCONDITIONAL_RECURSION,
+            hir_id,
+            sp,
+            "function cannot return without recursing",
+            |lint| {
+                lint.span_label(sp, "cannot return without recursing");
+                // offer some help to the programmer.
+                for call_span in vis.reachable_recursive_calls {
+                    lint.span_label(call_span, "recursive call site");
+                }
+                lint.help("a `loop` may express intention better if this is on purpose")
+            },
+        );
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index d45b886903b..8fca94119c2 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -7,7 +7,7 @@ use super::{PatCtxt, PatternError};
 use rustc_arena::TypedArena;
 use rustc_ast::Mutability;
 use rustc_errors::{
-    error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder,
+    error_code, pluralize, struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder,
     ErrorGuaranteed, MultiSpan,
 };
 use rustc_hir as hir;
@@ -347,19 +347,23 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
             let span_end = affix.last().unwrap().unwrap().0;
             let span = span_start.to(span_end);
             let cnt = affix.len();
-            cx.tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, top, span, |lint| {
-                let s = pluralize!(cnt);
-                let mut diag = lint.build(&format!("{kind} irrefutable pattern{s} in let chain"));
-                diag.note(&format!(
-                    "{these} pattern{s} will always match",
-                    these = pluralize!("this", cnt),
-                ));
-                diag.help(&format!(
-                    "consider moving {} {suggestion}",
-                    if cnt > 1 { "them" } else { "it" }
-                ));
-                diag.emit()
-            });
+            let s = pluralize!(cnt);
+            cx.tcx.struct_span_lint_hir(
+                IRREFUTABLE_LET_PATTERNS,
+                top,
+                span,
+                format!("{kind} irrefutable pattern{s} in let chain"),
+                |lint| {
+                    lint.note(format!(
+                        "{these} pattern{s} will always match",
+                        these = pluralize!("this", cnt),
+                    ))
+                    .help(format!(
+                        "consider moving {} {suggestion}",
+                        if cnt > 1 { "them" } else { "it" }
+                    ))
+                },
+            );
         };
         if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 {
             // The chain has a non-zero prefix of irrefutable `let` statements.
@@ -561,26 +565,28 @@ fn check_for_bindings_named_same_as_variants(
                 BINDINGS_WITH_VARIANT_NAME,
                 p.hir_id,
                 p.span,
+                DelayDm(|| format!(
+                    "pattern binding `{}` is named the same as one \
+                        of the variants of the type `{}`",
+                    ident, cx.tcx.def_path_str(edef.did())
+                )),
                 |lint| {
                     let ty_path = cx.tcx.def_path_str(edef.did());
-                    let mut err = lint.build(&format!(
-                        "pattern binding `{}` is named the same as one \
-                         of the variants of the type `{}`",
-                        ident, ty_path
-                    ));
-                    err.code(error_code!(E0170));
+                    lint.code(error_code!(E0170));
+
                     // If this is an irrefutable pattern, and there's > 1 variant,
                     // then we can't actually match on this. Applying the below
                     // suggestion would produce code that breaks on `check_irrefutable`.
                     if rf == Refutable || variant_count == 1 {
-                        err.span_suggestion(
+                        lint.span_suggestion(
                             p.span,
                             "to match on the variant, qualify the path",
                             format!("{}::{}", ty_path, ident),
                             Applicability::MachineApplicable,
                         );
                     }
-                    err.emit();
+
+                    lint
                 },
             )
         }
@@ -598,14 +604,13 @@ fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool {
 }
 
 fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<Span>) {
-    tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, |lint| {
-        let mut err = lint.build("unreachable pattern");
+    tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, "unreachable pattern", |lint| {
         if let Some(catchall) = catchall {
             // We had a catchall pattern, hint at that.
-            err.span_label(span, "unreachable pattern");
-            err.span_label(catchall, "matches any value");
+            lint.span_label(span, "unreachable pattern");
+            lint.span_label(catchall, "matches any value");
         }
-        err.emit();
+        lint
     });
 }
 
@@ -621,6 +626,11 @@ fn irrefutable_let_patterns(
     count: usize,
     span: Span,
 ) {
+    let span = match source {
+        LetSource::LetElse(span) => span,
+        _ => span,
+    };
+
     macro_rules! emit_diag {
         (
             $lint:expr,
@@ -630,18 +640,23 @@ fn irrefutable_let_patterns(
         ) => {{
             let s = pluralize!(count);
             let these = pluralize!("this", count);
-            let mut diag = $lint.build(&format!("irrefutable {} pattern{s}", $source_name));
-            diag.note(&format!("{these} pattern{s} will always match, so the {}", $note_sufix));
-            diag.help(concat!("consider ", $help_sufix));
-            diag.emit()
+            tcx.struct_span_lint_hir(
+                IRREFUTABLE_LET_PATTERNS,
+                id,
+                span,
+                format!("irrefutable {} pattern{s}", $source_name),
+                |lint| {
+                    lint.note(&format!(
+                        "{these} pattern{s} will always match, so the {}",
+                        $note_sufix
+                    ))
+                    .help(concat!("consider ", $help_sufix))
+                },
+            )
         }};
     }
 
-    let span = match source {
-        LetSource::LetElse(span) => span,
-        _ => span,
-    };
-    tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source {
+    match source {
         LetSource::GenericLet => {
             emit_diag!(lint, "`let`", "`let` is useless", "removing `let`");
         }
@@ -677,7 +692,7 @@ fn irrefutable_let_patterns(
                 "instead using a `loop { ... }` with a `let` inside it"
             );
         }
-    });
+    };
 }
 
 fn is_let_irrefutable<'p, 'tcx>(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index b58685e8958..f2935ca0e3a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -1,3 +1,4 @@
+use rustc_errors::DelayDm;
 use rustc_hir as hir;
 use rustc_index::vec::Idx;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -205,9 +206,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                         lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                         self.id,
                         self.span,
-                        |lint| {
-                            lint.build(&msg).emit();
-                        },
+                        msg,
+                        |lint| lint,
                     );
                 } else {
                     debug!(
@@ -286,9 +286,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                         lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
                         id,
                         span,
-                        |lint| {
-                            lint.build("floating-point types cannot be used in patterns").emit();
-                        },
+                        "floating-point types cannot be used in patterns",
+                        |lint| lint,
                     );
                 }
                 PatKind::Constant { value: cv }
@@ -340,15 +339,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                         lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                         id,
                         span,
-                        |lint| {
-                            let msg = format!(
+                        DelayDm(|| {
+                            format!(
                                 "to use a constant of type `{}` in a pattern, \
                                  `{}` must be annotated with `#[derive(PartialEq, Eq)]`",
                                 cv.ty(),
                                 cv.ty(),
-                            );
-                            lint.build(&msg).emit();
-                        },
+                            )
+                        }),
+                        |lint| lint,
                     );
                 }
                 // Since we are behind a reference, we can just bubble the error up so we get a
@@ -488,7 +487,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                                 lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                                 self.id,
                                 self.span,
-                                |lint| {lint.build(&msg).emit();},
+                                msg,
+                                |lint| lint,
                             );
                         }
                         PatKind::Constant { value: cv }
@@ -556,9 +556,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                         lint::builtin::POINTER_STRUCTURAL_MATCH,
                         id,
                         span,
-                        |lint| {
-                            lint.build(msg).emit();
-                        },
+                        msg,
+                        |lint| lint,
                     );
                 }
                 PatKind::Constant { value: cv }
@@ -594,9 +593,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
                 lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH,
                 id,
                 span,
-                |lint| {
-                    lint.build(&msg).emit();
-                },
+                msg,
+                |lint| lint,
             );
         }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 5105f059f9b..91ecfccdb5f 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -299,10 +299,10 @@ impl IntRange {
                 lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
                 hir_id,
                 pcx.span,
+                "multiple patterns overlap on their endpoints",
                 |lint| {
-                    let mut err = lint.build("multiple patterns overlap on their endpoints");
                     for (int_range, span) in overlaps {
-                        err.span_label(
+                        lint.span_label(
                             span,
                             &format!(
                                 "this range overlaps on `{}`...",
@@ -310,9 +310,9 @@ impl IntRange {
                             ),
                         );
                     }
-                    err.span_label(pcx.span, "... with this range");
-                    err.note("you likely meant to write mutually exclusive ranges");
-                    err.emit();
+                    lint.span_label(pcx.span, "... with this range");
+                    lint.note("you likely meant to write mutually exclusive ranges");
+                    lint
                 },
             );
         }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index cd186421bb1..895af80bd7f 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -433,7 +433,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 | DefKind::AssocTy,
                 _,
             )
-            | Res::SelfTy { .. }
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
             | Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
             _ => {
                 let pattern_error = match res {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 22b58837148..f1279072844 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -754,9 +754,8 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
     hir_id: HirId,
     witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
 ) {
-    cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, |build| {
+    cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, "some variants are not matched explicitly", |lint| {
         let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
-        let mut lint = build.build("some variants are not matched explicitly");
         lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
         lint.help(
             "ensure that all variants are matched explicitly by adding the suggested match arms",
@@ -765,7 +764,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
             "the matched value is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found",
             scrut_ty,
         ));
-        lint.emit();
+        lint
     });
 }
 
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index 8838b14c53a..fa5f392fa74 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{DiagnosticBuilder, LintDiagnosticBuilder};
+use rustc_errors::{DiagnosticBuilder, DiagnosticMessage};
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
@@ -63,7 +63,10 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> {
         place: &Place<'tcx>,
         const_item: DefId,
         location: Location,
-        decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) -> DiagnosticBuilder<'b, ()>,
+        msg: impl Into<DiagnosticMessage>,
+        decorate: impl for<'a, 'b> FnOnce(
+            &'a mut DiagnosticBuilder<'b, ()>,
+        ) -> &'a mut DiagnosticBuilder<'b, ()>,
     ) {
         // Don't lint on borrowing/assigning when a dereference is involved.
         // If we 'leave' the temporary via a dereference, we must
@@ -84,10 +87,10 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> {
                 CONST_ITEM_MUTATION,
                 lint_root,
                 source_info.span,
+                msg,
                 |lint| {
                     decorate(lint)
                         .span_note(self.tcx.def_span(const_item), "`const` item defined here")
-                        .emit();
                 },
             );
         }
@@ -102,10 +105,8 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
             // so emitting a lint would be redundant.
             if !lhs.projection.is_empty() {
                 if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) {
-                    self.lint_const_item_usage(&lhs, def_id, loc, |lint| {
-                        let mut lint = lint.build("attempting to modify a `const` item");
-                        lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified");
-                        lint
+                    self.lint_const_item_usage(&lhs, def_id, loc, "attempting to modify a `const` item",|lint| {
+                        lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified")
                     })
                 }
             }
@@ -137,8 +138,7 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
                 });
                 let lint_loc =
                     if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
-                self.lint_const_item_usage(place, def_id, lint_loc, |lint| {
-                    let mut lint = lint.build("taking a mutable reference to a `const` item");
+                self.lint_const_item_usage(place, def_id, lint_loc, "taking a mutable reference to a `const` item", |lint| {
                     lint
                         .note("each usage of a `const` item creates a new temporary")
                         .note("the mutable reference will refer to this temporary, not the original `const` item");
diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs
index 3b7ba3f9a67..51abcf51189 100644
--- a/compiler/rustc_mir_transform/src/check_packed_ref.rs
+++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs
@@ -33,21 +33,27 @@ struct PackedRefChecker<'a, 'tcx> {
 fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     let lint_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
-    tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| {
-        // FIXME: when we make this a hard error, this should have its
-        // own error code.
-        let extra = if tcx.generics_of(def_id).own_requires_monomorphization() {
-            "with type or const parameters"
-        } else {
-            "that does not derive `Copy`"
-        };
-        let message = format!(
-            "`{}` can't be derived on this `#[repr(packed)]` struct {}",
-            tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")),
-            extra
-        );
-        lint.build(message).emit();
-    });
+    // FIXME: when we make this a hard error, this should have its
+    // own error code.
+
+    let extra = if tcx.generics_of(def_id).own_requires_monomorphization() {
+        "with type or const parameters"
+    } else {
+        "that does not derive `Copy`"
+    };
+    let message = format!(
+        "`{}` can't be derived on this `#[repr(packed)]` struct {}",
+        tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")),
+        extra
+    );
+
+    tcx.struct_span_lint_hir(
+        UNALIGNED_REFERENCES,
+        lint_hir_id,
+        tcx.def_span(def_id),
+        message,
+        |lint| lint,
+    );
 }
 
 impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
@@ -86,8 +92,9 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
                         UNALIGNED_REFERENCES,
                         lint_root,
                         source_info.span,
+                        "reference to packed field is unaligned",
                         |lint| {
-                            lint.build("reference to packed field is unaligned")
+                            lint
                                 .note(
                                     "fields of packed structs are not properly aligned, and creating \
                                     a misaligned reference is undefined behavior (even if that \
@@ -98,7 +105,6 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
                                     reference with a raw pointer and use `read_unaligned`/`write_unaligned` \
                                     (loads and stores via `*p` must be properly aligned even when using raw pointers)"
                                 )
-                                .emit();
                         },
                     );
                 }
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index beff19a3ab2..4730be1244b 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -489,21 +489,20 @@ fn unsafety_check_result<'tcx>(
 
 fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
     let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id));
-    tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, |lint| {
-        let msg = "unnecessary `unsafe` block";
-        let mut db = lint.build(msg);
-        db.span_label(span, msg);
+    let msg = "unnecessary `unsafe` block";
+    tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, msg, |lint| {
+        lint.span_label(span, msg);
         match kind {
             UnusedUnsafe::Unused => {}
             UnusedUnsafe::InUnsafeBlock(id) => {
-                db.span_label(
+                lint.span_label(
                     tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
                     "because it's nested under this `unsafe` block",
                 );
             }
         }
 
-        db.emit();
+        lint
     });
 }
 
@@ -543,15 +542,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                 UNSAFE_OP_IN_UNSAFE_FN,
                 lint_root,
                 source_info.span,
-                |lint| {
-                    lint.build(&format!(
-                        "{} is unsafe and requires unsafe block (error E0133)",
-                        description,
-                    ))
-                    .span_label(source_info.span, description)
-                    .note(note)
-                    .emit();
-                },
+                format!("{} is unsafe and requires unsafe block (error E0133)", description,),
+                |lint| lint.span_label(source_info.span, description).note(note),
             ),
         }
     }
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 973f55437ee..cda3702c83d 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -347,10 +347,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         panic: AssertKind<impl std::fmt::Debug>,
     ) {
         if let Some(lint_root) = self.lint_root(source_info) {
-            self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| {
-                let mut err = lint.build(message);
-                err.span_label(source_info.span, format!("{:?}", panic));
-                err.emit();
+            self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, message, |lint| {
+                lint.span_label(source_info.span, format!("{:?}", panic))
             });
         }
     }
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 7522a50a8c6..1244c18020d 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -106,14 +106,12 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
                 .lint_root;
             let span = terminator.source_info.span;
 
-            tcx.struct_span_lint_hir(FFI_UNWIND_CALLS, lint_root, span, |lint| {
-                let msg = match fn_def_id {
-                    Some(_) => "call to foreign function with FFI-unwind ABI",
-                    None => "call to function pointer with FFI-unwind ABI",
-                };
-                let mut db = lint.build(msg);
-                db.span_label(span, msg);
-                db.emit();
+            let msg = match fn_def_id {
+                Some(_) => "call to foreign function with FFI-unwind ABI",
+                None => "call to function pointer with FFI-unwind ABI",
+            };
+            tcx.struct_span_lint_hir(FFI_UNWIND_CALLS, lint_root, span, msg, |lint| {
+                lint.span_label(span, msg)
             });
 
             tainted = true;
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index 0568eb2ffa6..469566694a3 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -179,11 +179,15 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
         let num_args = fn_sig.inputs().map_bound(|inputs| inputs.len()).skip_binder();
         let variadic = if fn_sig.c_variadic() { ", ..." } else { "" };
         let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" };
-        self.tcx.struct_span_lint_hir(FUNCTION_ITEM_REFERENCES, lint_root, span, |lint| {
-            lint.build("taking a reference to a function item does not give a function pointer")
-                .span_suggestion(
+        self.tcx.struct_span_lint_hir(
+            FUNCTION_ITEM_REFERENCES,
+            lint_root,
+            span,
+            "taking a reference to a function item does not give a function pointer",
+            |lint| {
+                lint.span_suggestion(
                     span,
-                    &format!("cast `{}` to obtain a function pointer", ident),
+                    format!("cast `{}` to obtain a function pointer", ident),
                     format!(
                         "{} as {}{}fn({}{}){}",
                         if params.is_empty() { ident } else { format!("{}::<{}>", ident, params) },
@@ -195,7 +199,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
                     ),
                     Applicability::Unspecified,
                 )
-                .emit();
-        });
+            },
+        );
     }
 }
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index b7e3ca571e1..a93f6a60114 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -290,7 +290,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
 impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
-        if !c.has_param_types_or_consts() {
+        if !c.has_non_region_param() {
             return ControlFlow::CONTINUE;
         }
 
@@ -311,7 +311,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
     }
 
     fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow<Self::BreakTy> {
-        if !constant.has_param_types_or_consts() {
+        if !constant.has_non_region_param() {
             return ControlFlow::CONTINUE;
         }
 
@@ -336,7 +336,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-        if !ty.has_param_types_or_consts() {
+        if !ty.has_non_region_param() {
             return ControlFlow::CONTINUE;
         }
 
@@ -373,7 +373,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
-        if !c.has_param_types_or_consts() {
+        if !c.has_non_region_param() {
             return ControlFlow::CONTINUE;
         }
 
@@ -391,7 +391,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> {
 
     #[instrument(level = "debug", skip(self))]
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-        if !ty.has_param_types_or_consts() {
+        if !ty.has_non_region_param() {
             return ControlFlow::CONTINUE;
         }
 
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index bcd078a8967..88540e13ef2 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -52,7 +52,7 @@ pub(crate) fn parse_token_trees<'a>(
     let cursor = Cursor::new(src);
     let string_reader =
         StringReader { sess, start_pos, pos: start_pos, src, cursor, override_span };
-    tokentrees::TokenTreesReader::parse_token_trees(string_reader)
+    tokentrees::TokenTreesReader::parse_all_token_trees(string_reader)
 }
 
 struct StringReader<'a> {
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index 364753154db..b2701817d48 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -27,7 +27,7 @@ pub(super) struct TokenTreesReader<'a> {
 }
 
 impl<'a> TokenTreesReader<'a> {
-    pub(super) fn parse_token_trees(
+    pub(super) fn parse_all_token_trees(
         string_reader: StringReader<'a>,
     ) -> (PResult<'a, TokenStream>, Vec<UnmatchedBrace>) {
         let mut tt_reader = TokenTreesReader {
@@ -40,36 +40,51 @@ impl<'a> TokenTreesReader<'a> {
             last_delim_empty_block_spans: FxHashMap::default(),
             matching_block_spans: Vec::new(),
         };
-        let res = tt_reader.parse_all_token_trees();
+        let res = tt_reader.parse_token_trees(/* is_delimited */ false);
         (res, tt_reader.unmatched_braces)
     }
 
-    // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
-    fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> {
+    // Parse a stream of tokens into a list of `TokenTree`s.
+    fn parse_token_trees(&mut self, is_delimited: bool) -> PResult<'a, TokenStream> {
         self.token = self.string_reader.next_token().0;
-        let mut buf = TokenStreamBuilder::default();
+        let mut buf = Vec::new();
         loop {
             match self.token.kind {
                 token::OpenDelim(delim) => buf.push(self.parse_token_tree_open_delim(delim)),
-                token::CloseDelim(delim) => return Err(self.close_delim_err(delim)),
-                token::Eof => return Ok(buf.into_token_stream()),
-                _ => buf.push(self.parse_token_tree_non_delim_non_eof()),
-            }
-        }
-    }
-
-    // Parse a stream of tokens into a list of `TokenTree`s, up to a `CloseDelim`.
-    fn parse_token_trees_until_close_delim(&mut self) -> TokenStream {
-        let mut buf = TokenStreamBuilder::default();
-        loop {
-            match self.token.kind {
-                token::OpenDelim(delim) => buf.push(self.parse_token_tree_open_delim(delim)),
-                token::CloseDelim(..) => return buf.into_token_stream(),
+                token::CloseDelim(delim) => {
+                    return if is_delimited {
+                        Ok(TokenStream::new(buf))
+                    } else {
+                        Err(self.close_delim_err(delim))
+                    };
+                }
                 token::Eof => {
-                    self.eof_err().emit();
-                    return buf.into_token_stream();
+                    if is_delimited {
+                        self.eof_err().emit();
+                    }
+                    return Ok(TokenStream::new(buf));
+                }
+                _ => {
+                    // Get the next normal token. This might require getting multiple adjacent
+                    // single-char tokens and joining them together.
+                    let (this_spacing, next_tok) = loop {
+                        let (next_tok, is_next_tok_preceded_by_whitespace) =
+                            self.string_reader.next_token();
+                        if !is_next_tok_preceded_by_whitespace {
+                            if let Some(glued) = self.token.glue(&next_tok) {
+                                self.token = glued;
+                            } else {
+                                let this_spacing =
+                                    if next_tok.is_op() { Spacing::Joint } else { Spacing::Alone };
+                                break (this_spacing, next_tok);
+                            }
+                        } else {
+                            break (Spacing::Alone, next_tok);
+                        }
+                    };
+                    let this_tok = std::mem::replace(&mut self.token, next_tok);
+                    buf.push(TokenTree::Token(this_tok, this_spacing));
                 }
-                _ => buf.push(self.parse_token_tree_non_delim_non_eof()),
             }
         }
     }
@@ -113,14 +128,12 @@ impl<'a> TokenTreesReader<'a> {
         // The span for beginning of the delimited section
         let pre_span = self.token.span;
 
-        // Move past the open delimiter.
         self.open_braces.push((open_delim, self.token.span));
-        self.token = self.string_reader.next_token().0;
 
         // Parse the token trees within the delimiters.
         // We stop at any delimiter so we can try to recover if the user
         // uses an incorrect delimiter.
-        let tts = self.parse_token_trees_until_close_delim();
+        let tts = self.parse_token_trees(/* is_delimited */ true).unwrap();
 
         // Expand to cover the entire delimited token tree
         let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
@@ -242,43 +255,4 @@ impl<'a> TokenTreesReader<'a> {
         err.span_label(self.token.span, "unexpected closing delimiter");
         err
     }
-
-    #[inline]
-    fn parse_token_tree_non_delim_non_eof(&mut self) -> TokenTree {
-        // `this_spacing` for the returned token refers to whether the token is
-        // immediately followed by another op token. It is determined by the
-        // next token: its kind and its `preceded_by_whitespace` status.
-        let (next_tok, is_next_tok_preceded_by_whitespace) = self.string_reader.next_token();
-        let this_spacing = if is_next_tok_preceded_by_whitespace || !next_tok.is_op() {
-            Spacing::Alone
-        } else {
-            Spacing::Joint
-        };
-        let this_tok = std::mem::replace(&mut self.token, next_tok);
-        TokenTree::Token(this_tok, this_spacing)
-    }
-}
-
-#[derive(Default)]
-struct TokenStreamBuilder {
-    buf: Vec<TokenTree>,
-}
-
-impl TokenStreamBuilder {
-    #[inline(always)]
-    fn push(&mut self, tree: TokenTree) {
-        if let Some(TokenTree::Token(prev_token, Spacing::Joint)) = self.buf.last()
-            && let TokenTree::Token(token, joint) = &tree
-            && let Some(glued) = prev_token.glue(token)
-        {
-            self.buf.pop();
-            self.buf.push(TokenTree::Token(glued, *joint));
-        } else {
-            self.buf.push(tree)
-        }
-    }
-
-    fn into_token_stream(self) -> TokenStream {
-        TokenStream::new(self.buf)
-    }
 }
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 86c386b94c8..0dc05475ce9 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -32,11 +32,6 @@ pub struct AttrWrapper {
     start_pos: usize,
 }
 
-// This struct is passed around very frequently,
-// so make sure it doesn't accidentally get larger
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(AttrWrapper, 16);
-
 impl AttrWrapper {
     pub(super) fn new(attrs: AttrVec, start_pos: usize) -> AttrWrapper {
         AttrWrapper { attrs, start_pos }
@@ -96,9 +91,6 @@ struct LazyAttrTokenStreamImpl {
     replace_ranges: Box<[ReplaceRange]>,
 }
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(LazyAttrTokenStreamImpl, 144);
-
 impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
     fn to_attr_token_stream(&self) -> AttrTokenStream {
         // The token produced by the final call to `{,inlined_}next` was not
@@ -461,3 +453,13 @@ fn make_token_stream(
     }
     AttrTokenStream::new(final_buf.inner)
 }
+
+// Some types are used a lot. Make sure they don't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+mod size_asserts {
+    use super::*;
+    use rustc_data_structures::static_assert_size;
+    // These are in alphabetical order, which is easy to maintain.
+    static_assert_size!(AttrWrapper, 16);
+    static_assert_size!(LazyAttrTokenStreamImpl, 144);
+}
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index b512f26335f..f57bd9cec19 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -33,6 +33,7 @@ use rustc_errors::{
     fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
 };
 use rustc_errors::{pluralize, Diagnostic, ErrorGuaranteed, IntoDiagnostic};
+use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
@@ -2049,7 +2050,7 @@ impl<'a> Parser<'a> {
         let mut err = self.struct_span_err(span, &msg);
         let sp = self.sess.source_map().start_point(self.token.span);
         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
-            self.sess.expr_parentheses_needed(&mut err, *sp);
+            err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
         }
         err.span_label(span, "expected expression");
         err
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 8b328e593ae..11301f03e48 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> {
                 // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
                 // then suggest parens around the lhs.
                 if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
-                    self.sess.expr_parentheses_needed(&mut err, *sp);
+                    err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
                 }
                 err
             })
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index b7454d7bfc1..25425fbb2c6 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -760,8 +760,8 @@ impl<'a> Parser<'a> {
                 )
                 .span_label(self.token.span, "this doc comment doesn't document anything")
                 .help(
-                    "doc comments must come before what they document, maybe a \
-                    comment was intended with `//`?",
+                    "doc comments must come before what they document, if a comment was \
+                    intended use `//`",
                 )
                 .emit();
                 self.bump();
@@ -1753,18 +1753,24 @@ impl<'a> Parser<'a> {
                 };
                 // We use `parse_fn` to get a span for the function
                 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
-                if let Err(mut db) =
-                    self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis)
-                {
-                    db.delay_as_bug();
+                match self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) {
+                    Ok(_) => {
+                        let mut err = self.struct_span_err(
+                            lo.to(self.prev_token.span),
+                            &format!("functions are not allowed in {adt_ty} definitions"),
+                        );
+                        err.help(
+                            "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
+                        );
+                        err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
+                        err
+                    }
+                    Err(err) => {
+                        err.cancel();
+                        self.restore_snapshot(snapshot);
+                        self.expected_ident_found()
+                    }
                 }
-                let mut err = self.struct_span_err(
-                    lo.to(self.prev_token.span),
-                    &format!("functions are not allowed in {adt_ty} definitions"),
-                );
-                err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
-                err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
-                err
             } else if self.eat_keyword(kw::Struct) {
                 match self.parse_item_struct() {
                     Ok((ident, _)) => {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 2aebaf7c3af..b934e087608 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -302,7 +302,10 @@ impl TokenCursor {
 
     fn desugar(&mut self, attr_style: AttrStyle, data: Symbol, span: Span) -> (Token, Spacing) {
         // Searches for the occurrences of `"#*` and returns the minimum number of `#`s
-        // required to wrap the text.
+        // required to wrap the text. E.g.
+        // - `abc d` is wrapped as `r"abc d"` (num_of_hashes = 0)
+        // - `abc "d"` is wrapped as `r#"abc "d""#` (num_of_hashes = 1)
+        // - `abc "##d##"` is wrapped as `r###"abc "d""###` (num_of_hashes = 3)
         let mut num_of_hashes = 0;
         let mut count = 0;
         for ch in data.as_str().chars() {
@@ -314,6 +317,7 @@ impl TokenCursor {
             num_of_hashes = cmp::max(num_of_hashes, count);
         }
 
+        // `/// foo` becomes `doc = r"foo".
         let delim_span = DelimSpan::from_single(span);
         let body = TokenTree::Delimited(
             delim_span,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 542a1ac5dc6..0250b518243 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -10,6 +10,7 @@ use rustc_ast::{
 };
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
+use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::{respan, Span, Spanned};
 use rustc_span::symbol::{kw, sym, Ident};
 
@@ -693,7 +694,7 @@ impl<'a> Parser<'a> {
 
         let sp = self.sess.source_map().start_point(self.token.span);
         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
-            self.sess.expr_parentheses_needed(&mut err, *sp);
+            err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
         }
 
         Err(err)
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index a9e502016aa..df22d79f82e 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -224,7 +224,7 @@ impl<'a> Iterator for Parser<'a> {
                 '{' => {
                     let curr_last_brace = self.last_opening_brace;
                     let byte_pos = self.to_span_index(pos);
-                    let lbrace_end = InnerOffset(byte_pos.0 + 1);
+                    let lbrace_end = self.to_span_index(pos + 1);
                     self.last_opening_brace = Some(byte_pos.to(lbrace_end));
                     self.cur.next();
                     if self.consume('{') {
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 897a0db930c..87433538512 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -370,10 +370,13 @@ impl CheckAttrVisitor<'_> {
                 b.push_str(&(allowed_target.to_string() + "s"));
                 b
             });
-            self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
-                lint.build(&format!("`#[{name}]` only has an effect on {}", supported_names))
-                    .emit();
-            });
+            self.tcx.struct_span_lint_hir(
+                UNUSED_ATTRIBUTES,
+                hir_id,
+                attr.span,
+                &format!("`#[{name}]` only has an effect on {}", supported_names),
+                |lint| lint,
+            );
         }
     }
 
@@ -877,25 +880,31 @@ impl CheckAttrVisitor<'_> {
         hir_id: HirId,
     ) -> bool {
         if hir_id != CRATE_HIR_ID {
-            self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| {
-                let mut err = lint.build(fluent::passes::attr_crate_level);
-                if attr.style == AttrStyle::Outer
-                    && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID
-                {
-                    if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) {
-                        src.insert(1, '!');
-                        err.span_suggestion_verbose(
-                            attr.span,
-                            fluent::passes::suggestion,
-                            src,
-                            Applicability::MaybeIncorrect,
-                        );
-                    } else {
-                        err.span_help(attr.span, fluent::passes::help);
+            self.tcx.struct_span_lint_hir(
+                INVALID_DOC_ATTRIBUTES,
+                hir_id,
+                meta.span(),
+                fluent::passes::attr_crate_level,
+                |err| {
+                    if attr.style == AttrStyle::Outer
+                        && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID
+                    {
+                        if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) {
+                            src.insert(1, '!');
+                            err.span_suggestion_verbose(
+                                attr.span,
+                                fluent::passes::suggestion,
+                                src,
+                                Applicability::MaybeIncorrect,
+                            );
+                        } else {
+                            err.span_help(attr.span, fluent::passes::help);
+                        }
                     }
-                }
-                err.note(fluent::passes::note).emit();
-            });
+                    err.note(fluent::passes::note);
+                    err
+                },
+            );
             return false;
         }
         true
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 4062862ad74..e502b9b54e3 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -191,32 +191,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
         self.tcx.hir()
     }
 
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        let tcx = self.tcx;
-        if let hir::ItemKind::Impl(hir::Impl {
-            constness: hir::Constness::Const,
-            of_trait: Some(trait_ref),
-            ..
-        }) = item.kind
-        {
-            let def_id = trait_ref.trait_def_id().unwrap();
-            let source_map = tcx.sess.source_map();
-            if !tcx.has_attr(def_id, sym::const_trait) {
-                tcx.sess
-                    .struct_span_err(
-                        source_map.guess_head_span(item.span),
-                        "const `impl`s must be for traits marked with `#[const_trait]`",
-                    )
-                    .span_note(
-                        source_map.guess_head_span(tcx.def_span(def_id)),
-                        "this trait must be annotated with `#[const_trait]`",
-                    )
-                    .emit();
-            }
-        }
-        intravisit::walk_item(self, item);
-    }
-
     fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
         let kind = Some(hir::ConstContext::Const);
         self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index e9d71bc93ac..08f704da62c 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -4,7 +4,7 @@
 
 use itertools::Itertools;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{pluralize, Applicability, MultiSpan};
+use rustc_errors::{pluralize, Applicability, DelayDm, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -102,14 +102,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 }
             }
             Res::Def(_, def_id) => self.check_def_id(def_id),
-            Res::SelfTy { trait_: t, alias_to: i } => {
-                if let Some(t) = t {
-                    self.check_def_id(t);
-                }
-                if let Some((i, _)) = i {
-                    self.check_def_id(i);
-                }
-            }
+            Res::SelfTyParam { trait_: t } => self.check_def_id(t),
+            Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i),
             Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {}
         }
     }
@@ -190,13 +184,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                     lint::builtin::DEAD_CODE,
                     assign.hir_id,
                     assign.span,
-                    |lint| {
-                        lint.build(&format!(
+                    DelayDm(|| format!(
                             "useless assignment of {} of type `{}` to itself",
                             if is_field_assign { "field" } else { "variable" },
                             self.typeck_results().expr_ty(lhs),
-                        ))
-                        .emit();
+                        )),
+                    |lint| {
+                        lint
+
                     },
                 )
         }
@@ -723,6 +718,26 @@ impl<'tcx> DeadVisitor<'tcx> {
                 })
                 .collect();
 
+            let descr = tcx.def_kind(first_id).descr(first_id.to_def_id());
+            let span_len = dead_codes.len();
+            let names = match &names[..] {
+                _ if span_len > 6 => String::new(),
+                [name] => format!("`{name}` "),
+                [names @ .., last] => {
+                    format!(
+                        "{} and `{last}` ",
+                        names.iter().map(|name| format!("`{name}`")).join(", ")
+                    )
+                }
+                [] => unreachable!(),
+            };
+            let msg = format!(
+                "{these}{descr}{s} {names}{are} never {participle}",
+                these = if span_len > 6 { "multiple " } else { "" },
+                s = pluralize!(span_len),
+                are = pluralize!("is", span_len),
+            );
+
             tcx.struct_span_lint_hir(
                 if is_positional {
                     lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS
@@ -731,27 +746,8 @@ impl<'tcx> DeadVisitor<'tcx> {
                 },
                 tcx.hir().local_def_id_to_hir_id(first_id),
                 MultiSpan::from_spans(spans.clone()),
-                |lint| {
-                    let descr = tcx.def_kind(first_id).descr(first_id.to_def_id());
-                    let span_len = dead_codes.len();
-                    let names = match &names[..] {
-                        _ if span_len > 6 => String::new(),
-                        [name] => format!("`{name}` "),
-                        [names @ .., last] => {
-                            format!(
-                                "{} and `{last}` ",
-                                names.iter().map(|name| format!("`{name}`")).join(", ")
-                            )
-                        }
-                        [] => unreachable!(),
-                    };
-                    let mut err = lint.build(&format!(
-                        "{these}{descr}{s} {names}{are} never {participle}",
-                        these = if span_len > 6 { "multiple " } else { "" },
-                        s = pluralize!(span_len),
-                        are = pluralize!("is", span_len),
-                    ));
-
+                msg,
+                |err| {
                     if is_positional {
                         err.multipart_suggestion(
                             &format!(
@@ -797,7 +793,7 @@ impl<'tcx> DeadVisitor<'tcx> {
                         );
                         err.note(&msg);
                     }
-                    err.emit();
+                    err
                 },
             );
         }
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 6a4cd79cde7..c6fe40f72fc 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1319,14 +1319,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             // that we do not emit the same warning twice if the uninhabited type
             // is indeed `!`.
 
+            let msg = format!("unreachable {}", descr);
             self.ir.tcx.struct_span_lint_hir(
                 lint::builtin::UNREACHABLE_CODE,
                 expr_id,
                 expr_span,
-                |lint| {
-                    let msg = format!("unreachable {}", descr);
-                    lint.build(&msg)
-                        .span_label(expr_span, &msg)
+                &msg,
+                |diag| {
+                    diag.span_label(expr_span, &msg)
                         .span_label(orig_span, "any code following this expression is unreachable")
                         .span_note(
                             orig_span,
@@ -1335,7 +1335,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                                 orig_ty
                             ),
                         )
-                        .emit();
                 },
             );
         }
@@ -1491,14 +1490,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
                                 lint::builtin::UNUSED_ASSIGNMENTS,
                                 var_hir_id,
                                 vec![span],
-                                |lint| {
-                                    lint.build(&format!(
-                                        "value captured by `{}` is never read",
-                                        name
-                                    ))
-                                    .help("did you mean to capture by reference instead?")
-                                    .emit();
-                                },
+                                format!("value captured by `{}` is never read", name),
+                                |lint| lint.help("did you mean to capture by reference instead?"),
                             );
                         }
                     }
@@ -1508,11 +1501,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
                             lint::builtin::UNUSED_VARIABLES,
                             var_hir_id,
                             vec![span],
-                            |lint| {
-                                lint.build(&format!("unused variable: `{}`", name))
-                                    .help("did you mean to capture by reference instead?")
-                                    .emit();
-                            },
+                            format!("unused variable: `{}`", name),
+                            |lint| lint.help("did you mean to capture by reference instead?"),
                         );
                     }
                 }
@@ -1601,20 +1591,17 @@ impl<'tcx> Liveness<'_, 'tcx> {
                         .into_iter()
                         .map(|(_, _, ident_span)| ident_span)
                         .collect::<Vec<_>>(),
-                    |lint| {
-                        lint.build(&format!("variable `{}` is assigned to, but never used", name))
-                            .note(&format!("consider using `_{}` instead", name))
-                            .emit();
-                    },
+                    format!("variable `{}` is assigned to, but never used", name),
+                    |lint| lint.note(&format!("consider using `_{}` instead", name)),
                 )
             } else if can_remove {
                 self.ir.tcx.struct_span_lint_hir(
                     lint::builtin::UNUSED_VARIABLES,
                     first_hir_id,
                     hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(),
+                    format!("unused variable: `{}`", name),
                     |lint| {
-                        let mut err = lint.build(&format!("unused variable: `{}`", name));
-                        err.multipart_suggestion(
+                        lint.multipart_suggestion(
                             "try removing the field",
                             hir_ids_and_spans
                                 .iter()
@@ -1629,8 +1616,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
                                 })
                                 .collect(),
                             Applicability::MachineApplicable,
-                        );
-                        err.emit();
+                        )
                     },
                 );
             } else {
@@ -1661,14 +1647,13 @@ impl<'tcx> Liveness<'_, 'tcx> {
                             .iter()
                             .map(|(_, pat_span, _)| *pat_span)
                             .collect::<Vec<_>>(),
+                        format!("unused variable: `{}`", name),
                         |lint| {
-                            let mut err = lint.build(&format!("unused variable: `{}`", name));
-                            err.multipart_suggestion(
+                            lint.multipart_suggestion(
                                 "try ignoring the field",
                                 shorthands,
                                 Applicability::MachineApplicable,
-                            );
-                            err.emit();
+                            )
                         },
                     );
                 } else {
@@ -1684,17 +1669,16 @@ impl<'tcx> Liveness<'_, 'tcx> {
                             .iter()
                             .map(|(_, _, ident_span)| *ident_span)
                             .collect::<Vec<_>>(),
+                        format!("unused variable: `{}`", name),
                         |lint| {
-                            let mut err = lint.build(&format!("unused variable: `{}`", name));
-                            if self.has_added_lit_match_name_span(&name, opt_body, &mut err) {
-                                err.span_label(pat.span, "unused variable");
+                            if self.has_added_lit_match_name_span(&name, opt_body, lint) {
+                                lint.span_label(pat.span, "unused variable");
                             }
-                            err.multipart_suggestion(
+                            lint.multipart_suggestion(
                                 "if this is intentional, prefix it with an underscore",
                                 non_shorthands,
                                 Applicability::MachineApplicable,
-                            );
-                            err.emit();
+                            )
                         },
                     );
                 }
@@ -1758,11 +1742,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
                 lint::builtin::UNUSED_ASSIGNMENTS,
                 hir_id,
                 spans,
-                |lint| {
-                    lint.build(&message(&name))
-                        .help("maybe it is overwritten before being read?")
-                        .emit();
-                },
+                message(&name),
+                |lint| lint.help("maybe it is overwritten before being read?"),
             )
         }
     }
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 607973446fc..2690be66c21 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -65,9 +65,13 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) {
     if abi == Abi::Rust {
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
         let span = tcx.def_span(def_id);
-        tcx.struct_span_lint_hir(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, span, |lint| {
-            lint.build("Rust ABI is unsupported in naked functions").emit();
-        });
+        tcx.struct_span_lint_hir(
+            UNDEFINED_NAKED_FUNCTION_ABI,
+            hir_id,
+            span,
+            "Rust ABI is unsupported in naked functions",
+            |lint| lint,
+        );
     }
 }
 
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index e50beb27d2a..34fa80228df 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -752,10 +752,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                                 INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
                                 item.hir_id(),
                                 span,
-                                |lint| {lint
-                                    .build("an `#[unstable]` annotation here has no effect")
-                                    .note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information")
-                                    .emit();}
+                                "an `#[unstable]` annotation here has no effect",
+                                |lint| lint.note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information")
                             );
                         }
                     }
@@ -1081,11 +1079,16 @@ fn unnecessary_partially_stable_feature_lint(
     implies: Symbol,
     since: Symbol,
 ) {
-    tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| {
-        lint.build(&format!(
+    tcx.struct_span_lint_hir(
+        lint::builtin::STABLE_FEATURES,
+        hir::CRATE_HIR_ID,
+        span,
+        format!(
             "the feature `{feature}` has been partially stabilized since {since} and is succeeded \
              by the feature `{implies}`"
-        ))
+        ),
+        |lint| {
+            lint
         .span_suggestion(
             span,
             &format!(
@@ -1100,8 +1103,8 @@ fn unnecessary_partially_stable_feature_lint(
             "",
             Applicability::MaybeIncorrect,
         )
-        .emit();
-    });
+        },
+    );
 }
 
 fn unnecessary_stable_feature_lint(
@@ -1113,12 +1116,8 @@ fn unnecessary_stable_feature_lint(
     if since.as_str() == VERSION_PLACEHOLDER {
         since = rust_version_symbol();
     }
-    tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| {
-        lint.build(&format!(
-            "the feature `{feature}` has been stable since {since} and no longer requires an \
-             attribute to enable",
-        ))
-        .emit();
+    tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, format!("the feature `{feature}` has been stable since {since} and no longer requires an attribute to enable"), |lint| {
+        lint
     });
 }
 
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 7ab07a671c4..841e3ebb2a1 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1422,7 +1422,9 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
 impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool {
         let did = match path.res {
-            Res::PrimTy(..) | Res::SelfTy { .. } | Res::Err => return false,
+            Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => {
+                return false;
+            }
             res => res.def_id(),
         };
 
diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
index 47762440e29..cdbf734cdbe 100644
--- a/compiler/rustc_query_impl/src/keys.rs
+++ b/compiler/rustc_query_impl/src/keys.rs
@@ -1,7 +1,7 @@
 //! Defines the set of legal keys that can be used in queries.
 
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
-use rustc_hir::hir_id::OwnerId;
+use rustc_hir::hir_id::{HirId, OwnerId};
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::mir;
 use rustc_middle::traits;
@@ -557,3 +557,19 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) {
         DUMMY_SP
     }
 }
+
+impl Key for HirId {
+    #[inline(always)]
+    fn query_crate_is_local(&self) -> bool {
+        true
+    }
+
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+        tcx.hir().span(*self)
+    }
+
+    #[inline(always)]
+    fn key_as_def_id(&self) -> Option<DefId> {
+        None
+    }
+}
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 5003a14b910..da2075fd5aa 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -94,6 +94,8 @@ impl<T: DepContext> HasDepContext for T {
 pub enum FingerprintStyle {
     /// The fingerprint is actually a DefPathHash.
     DefPathHash,
+    /// The fingerprint is actually a HirId.
+    HirId,
     /// Query key was `()` or equivalent, so fingerprint is just zero.
     Unit,
     /// Some opaque hash.
@@ -104,7 +106,9 @@ impl FingerprintStyle {
     #[inline]
     pub fn reconstructible(self) -> bool {
         match self {
-            FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true,
+            FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => {
+                true
+            }
             FingerprintStyle::Opaque => false,
         }
     }
diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs
index 8140c243453..148eabb38e2 100644
--- a/compiler/rustc_query_system/src/ich/hcx.rs
+++ b/compiler/rustc_query_system/src/ich/hcx.rs
@@ -12,7 +12,7 @@ use rustc_session::cstore::CrateStore;
 use rustc_session::Session;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Symbol;
-use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
+use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData, DUMMY_SP};
 
 /// This is the context state available during incr. comp. hashing. It contains
 /// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e.,
@@ -185,7 +185,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
 
     #[inline]
     fn def_span(&self, def_id: LocalDefId) -> Span {
-        self.source_span[def_id]
+        *self.source_span.get(def_id).unwrap_or(&DUMMY_SP)
     }
 
     #[inline]
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 81b67b758f7..29aab416ae9 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1010,7 +1010,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 _,
             )
             | Res::Local(..)
-            | Res::SelfTy { .. }
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
             | Res::SelfCtor(..)
             | Res::Err => bug!("unexpected resolution: {:?}", res),
         }
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 7e83f2a7221..38a3c9dd71a 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -285,21 +285,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
     fn visit_ty(&mut self, ty: &'a Ty) {
         match ty.kind {
             TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
-            TyKind::ImplTrait(node_id, _) => {
-                let parent_def = match self.impl_trait_context {
-                    ImplTraitContext::Universal(item_def) => self.resolver.create_def(
-                        item_def,
-                        node_id,
-                        DefPathData::ImplTrait,
-                        self.expansion.to_expn_id(),
-                        ty.span,
-                    ),
-                    ImplTraitContext::Existential => {
-                        self.create_def(node_id, DefPathData::ImplTrait, ty.span)
-                    }
-                };
-                self.with_parent(parent_def, |this| visit::walk_ty(this, ty))
-            }
             _ => visit::walk_ty(self, ty),
         }
     }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index ab71fa0bc1d..b6778804a99 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -511,24 +511,18 @@ impl<'a> Resolver<'a> {
 
                 let sm = self.session.source_map();
                 let def_id = match outer_res {
-                    Res::SelfTy { trait_: maybe_trait_defid, alias_to: maybe_impl_defid } => {
-                        if let Some(impl_span) =
-                            maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id))
-                        {
+                    Res::SelfTyParam { .. } => {
+                        err.span_label(span, "can't use `Self` here");
+                        return err;
+                    }
+                    Res::SelfTyAlias { alias_to: def_id, .. } => {
+                        if let Some(impl_span) = self.opt_span(def_id) {
                             err.span_label(
                                 reduce_impl_span_to_impl_keyword(sm, impl_span),
                                 "`Self` type implicitly declared here, by this `impl`",
                             );
                         }
-                        match (maybe_trait_defid, maybe_impl_defid) {
-                            (Some(_), None) => {
-                                err.span_label(span, "can't use `Self` here");
-                            }
-                            (_, Some(_)) => {
-                                err.span_label(span, "use a type here instead");
-                            }
-                            (None, None) => bug!("`impl` without trait nor type?"),
-                        }
+                        err.span_label(span, "use a type here instead");
                         return err;
                     }
                     Res::Def(DefKind::TyParam, def_id) => {
@@ -545,8 +539,9 @@ impl<'a> Resolver<'a> {
                     }
                     _ => {
                         bug!(
-                            "GenericParamsFromOuterFunction should only be used with Res::SelfTy, \
-                            DefKind::TyParam or DefKind::ConstParam"
+                            "GenericParamsFromOuterFunction should only be used with \
+                            Res::SelfTyParam, Res::SelfTyAlias, DefKind::TyParam or \
+                            DefKind::ConstParam"
                         );
                     }
                 };
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 2287aa1eb25..e0542d5479f 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1162,7 +1162,7 @@ impl<'a> Resolver<'a> {
                     return Res::Err;
                 }
             }
-            Res::Def(DefKind::TyParam, _) | Res::SelfTy { .. } => {
+            Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
                 for rib in ribs {
                     let has_generic_params: HasGenericParams = match rib.kind {
                         NormalRibKind
@@ -1182,11 +1182,21 @@ impl<'a> Resolver<'a> {
                             if !(trivial == ConstantHasGenerics::Yes
                                 || features.generic_const_exprs)
                             {
-                                // HACK(min_const_generics): If we encounter `Self` in an anonymous constant
-                                // we can't easily tell if it's generic at this stage, so we instead remember
-                                // this and then enforce the self type to be concrete later on.
-                                if let Res::SelfTy { trait_, alias_to: Some((def, _)) } = res {
-                                    res = Res::SelfTy { trait_, alias_to: Some((def, true)) }
+                                // HACK(min_const_generics): If we encounter `Self` in an anonymous
+                                // constant we can't easily tell if it's generic at this stage, so
+                                // we instead remember this and then enforce the self type to be
+                                // concrete later on.
+                                if let Res::SelfTyAlias {
+                                    alias_to: def,
+                                    forbid_generic: _,
+                                    is_trait_impl,
+                                } = res
+                                {
+                                    res = Res::SelfTyAlias {
+                                        alias_to: def,
+                                        forbid_generic: true,
+                                        is_trait_impl,
+                                    }
                                 } else {
                                     if let Some(span) = finalize {
                                         self.report_error(
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 558db003867..72029488cb1 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -19,7 +19,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_errors::DiagnosticId;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
 use rustc_middle::middle::resolve_lifetime::Set1;
 use rustc_middle::ty::DefIdTree;
@@ -414,7 +414,8 @@ impl<'a> PathSource<'a> {
                         | DefKind::ForeignTy,
                     _,
                 ) | Res::PrimTy(..)
-                    | Res::SelfTy { .. }
+                    | Res::SelfTyParam { .. }
+                    | Res::SelfTyAlias { .. }
             ),
             PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
             PathSource::Trait(AliasPossibility::Maybe) => {
@@ -448,7 +449,8 @@ impl<'a> PathSource<'a> {
                         | DefKind::TyAlias
                         | DefKind::AssocTy,
                     _,
-                ) | Res::SelfTy { .. }
+                ) | Res::SelfTyParam { .. }
+                    | Res::SelfTyAlias { .. }
             ),
             PathSource::TraitItem(ns) => match res {
                 Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
@@ -1929,7 +1931,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     TyKind::ImplicitSelf => true,
                     TyKind::Path(None, _) => {
                         let path_res = self.r.partial_res_map[&ty.id].base_res();
-                        if let Res::SelfTy { .. } = path_res {
+                        if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path_res {
                             return true;
                         }
                         Some(path_res) == self.impl_self
@@ -2050,7 +2052,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 |this| {
                     let item_def_id = this.r.local_def_id(item.id).to_def_id();
                     this.with_self_rib(
-                        Res::SelfTy { trait_: None, alias_to: Some((item_def_id, false)) },
+                        Res::SelfTyAlias {
+                            alias_to: item_def_id,
+                            forbid_generic: false,
+                            is_trait_impl: false,
+                        },
                         |this| {
                             visit::walk_item(this, item);
                         },
@@ -2164,14 +2170,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     },
                     |this| {
                         let local_def_id = this.r.local_def_id(item.id).to_def_id();
-                        this.with_self_rib(
-                            Res::SelfTy { trait_: Some(local_def_id), alias_to: None },
-                            |this| {
-                                this.visit_generics(generics);
-                                walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits);
-                                this.resolve_trait_items(items);
-                            },
-                        );
+                        this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| {
+                            this.visit_generics(generics);
+                            walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits);
+                            this.resolve_trait_items(items);
+                        });
                     },
                 );
             }
@@ -2188,13 +2191,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     },
                     |this| {
                         let local_def_id = this.r.local_def_id(item.id).to_def_id();
-                        this.with_self_rib(
-                            Res::SelfTy { trait_: Some(local_def_id), alias_to: None },
-                            |this| {
-                                this.visit_generics(generics);
-                                walk_list!(this, visit_param_bound, bounds, BoundKind::Bound);
-                            },
-                        );
+                        this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| {
+                            this.visit_generics(generics);
+                            walk_list!(this, visit_param_bound, bounds, BoundKind::Bound);
+                        });
                     },
                 );
             }
@@ -2576,7 +2576,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             },
             |this| {
                 // Dummy self type for better errors if `Self` is used in the trait path.
-                this.with_self_rib(Res::SelfTy { trait_: None, alias_to: None }, |this| {
+                this.with_self_rib(Res::SelfTyParam { trait_: LOCAL_CRATE.as_def_id() }, |this| {
                     this.with_lifetime_rib(
                         LifetimeRibKind::AnonymousCreateParameter {
                             binder: item_id,
@@ -2600,9 +2600,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                     }
 
                                     let item_def_id = item_def_id.to_def_id();
-                                    let res = Res::SelfTy {
-                                        trait_: trait_id,
-                                        alias_to: Some((item_def_id, false)),
+                                    let res = Res::SelfTyAlias {
+                                        alias_to: item_def_id,
+                                        forbid_generic: false,
+                                        is_trait_impl: trait_id.is_some()
                                     };
                                     this.with_self_rib(res, |this| {
                                         if let Some(trait_ref) = opt_trait_reference.as_ref() {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 3c276a9ada9..2d339a4d070 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -130,6 +130,16 @@ pub(super) enum LifetimeElisionCandidate {
     Missing(MissingLifetime),
 }
 
+/// Only used for diagnostics.
+struct BaseError {
+    msg: String,
+    fallback_label: String,
+    span: Span,
+    span_label: Option<(Span, &'static str)>,
+    could_be_expr: bool,
+    suggestion: Option<(Span, &'static str, String)>,
+}
+
 impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
     fn def_span(&self, def_id: DefId) -> Option<Span> {
         match def_id.krate {
@@ -138,35 +148,18 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
 
-    /// Handles error reporting for `smart_resolve_path_fragment` function.
-    /// Creates base error and amends it with one short label and possibly some longer helps/notes.
-    pub(crate) fn smart_resolve_report_errors(
+    fn make_base_error(
         &mut self,
         path: &[Segment],
         span: Span,
         source: PathSource<'_>,
         res: Option<Res>,
-    ) -> (DiagnosticBuilder<'a, ErrorGuaranteed>, Vec<ImportSuggestion>) {
-        let ident_span = path.last().map_or(span, |ident| ident.ident.span);
-        let ns = source.namespace();
-        let is_expected = &|res| source.is_expected(res);
-        let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _));
-
-        debug!(?res, ?source);
-
+    ) -> BaseError {
         // Make the base error.
-        struct BaseError<'a> {
-            msg: String,
-            fallback_label: String,
-            span: Span,
-            span_label: Option<(Span, &'a str)>,
-            could_be_expr: bool,
-            suggestion: Option<(Span, &'a str, String)>,
-        }
         let mut expected = source.descr_expected();
         let path_str = Segment::names_to_string(path);
         let item_str = path.last().unwrap().ident;
-        let base_error = if let Some(res) = res {
+        if let Some(res) = res {
             BaseError {
                 msg: format!("expected {}, found {} `{}`", expected, res.descr(), path_str),
                 fallback_label: format!("not a {expected}"),
@@ -277,8 +270,20 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 could_be_expr: false,
                 suggestion,
             }
-        };
+        }
+    }
 
+    /// Handles error reporting for `smart_resolve_path_fragment` function.
+    /// Creates base error and amends it with one short label and possibly some longer helps/notes.
+    pub(crate) fn smart_resolve_report_errors(
+        &mut self,
+        path: &[Segment],
+        span: Span,
+        source: PathSource<'_>,
+        res: Option<Res>,
+    ) -> (DiagnosticBuilder<'a, ErrorGuaranteed>, Vec<ImportSuggestion>) {
+        debug!(?res, ?source);
+        let base_error = self.make_base_error(path, span, source, res);
         let code = source.error_code(res.is_some());
         let mut err =
             self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code);
@@ -289,41 +294,79 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
             err.span_label(span, label);
         }
 
-        if let Some(sugg) = base_error.suggestion {
-            err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
+        if let Some(ref sugg) = base_error.suggestion {
+            err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect);
         }
 
-        if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal {
-            err.multipart_suggestion(
-                "you might have meant to write a `struct` literal",
-                vec![
-                    (span.shrink_to_lo(), "{ SomeStruct ".to_string()),
-                    (span.shrink_to_hi(), "}".to_string()),
-                ],
-                Applicability::HasPlaceholders,
-            );
+        self.suggest_bare_struct_literal(&mut err);
+        self.suggest_pattern_match_with_let(&mut err, source, span);
+
+        self.suggest_self_or_self_ref(&mut err, path, span);
+        self.detect_assoct_type_constraint_meant_as_path(&mut err, &base_error);
+        if self.suggest_self_ty(&mut err, source, path, span)
+            || self.suggest_self_value(&mut err, source, path, span)
+        {
+            return (err, Vec::new());
         }
-        match (source, self.diagnostic_metadata.in_if_condition) {
-            (
-                PathSource::Expr(_),
-                Some(Expr { span: expr_span, kind: ExprKind::Assign(lhs, _, _), .. }),
-            ) => {
-                // Icky heuristic so we don't suggest:
-                // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern)
-                // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span)
-                if lhs.is_approximately_pattern() && lhs.span.contains(span) {
-                    err.span_suggestion_verbose(
-                        expr_span.shrink_to_lo(),
-                        "you might have meant to use pattern matching",
-                        "let ",
-                        Applicability::MaybeIncorrect,
-                    );
+
+        let (found, candidates) =
+            self.try_lookup_name_relaxed(&mut err, source, path, span, res, &base_error);
+        if found {
+            return (err, candidates);
+        }
+
+        if !self.type_ascription_suggestion(&mut err, base_error.span) {
+            let mut fallback =
+                self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
+            fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
+            if fallback {
+                // Fallback label.
+                err.span_label(base_error.span, &base_error.fallback_label);
+            }
+        }
+        self.err_code_special_cases(&mut err, source, path, span);
+
+        (err, candidates)
+    }
+
+    fn detect_assoct_type_constraint_meant_as_path(
+        &self,
+        err: &mut Diagnostic,
+        base_error: &BaseError,
+    ) {
+        let Some(ty) = self.diagnostic_metadata.current_type_path else { return; };
+        let TyKind::Path(_, path) = &ty.kind else { return; };
+        for segment in &path.segments {
+            let Some(params) = &segment.args else { continue; };
+            let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; };
+            for param in &params.args {
+                let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; };
+                let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else {
+                    continue;
+                };
+                for bound in bounds {
+                    let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None)
+                        = bound else
+                    {
+                        continue;
+                    };
+                    if base_error.span == trait_ref.span {
+                        err.span_suggestion_verbose(
+                            constraint.ident.span.between(trait_ref.span),
+                            "you might have meant to write a path instead of an associated type bound",
+                            "::",
+                            Applicability::MachineApplicable,
+                        );
+                    }
                 }
             }
-            _ => {}
         }
+    }
 
+    fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) {
         let is_assoc_fn = self.self_type_is_available();
+        let Some(path_last_segment) = path.last() else { return };
+        let item_str = path_last_segment.ident;
         // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
         if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn {
             err.span_suggestion_short(
@@ -358,96 +401,25 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 }
             }
         }
+    }
 
-        self.detect_assoct_type_constraint_meant_as_path(base_error.span, &mut err);
-
-        // Emit special messages for unresolved `Self` and `self`.
-        if is_self_type(path, ns) {
-            err.code(rustc_errors::error_code!(E0411));
-            err.span_label(
-                span,
-                "`Self` is only available in impls, traits, and type definitions".to_string(),
-            );
-            if let Some(item_kind) = self.diagnostic_metadata.current_item {
-                err.span_label(
-                    item_kind.ident.span,
-                    format!(
-                        "`Self` not allowed in {} {}",
-                        item_kind.kind.article(),
-                        item_kind.kind.descr()
-                    ),
-                );
-            }
-            return (err, Vec::new());
-        }
-        if is_self_value(path, ns) {
-            debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
-
-            err.code(rustc_errors::error_code!(E0424));
-            err.span_label(span, match source {
-                PathSource::Pat => "`self` value is a keyword and may not be bound to variables or shadowed",
-                _ => "`self` value is a keyword only available in methods with a `self` parameter",
-            });
-            if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function {
-                // The current function has a `self' parameter, but we were unable to resolve
-                // a reference to `self`. This can only happen if the `self` identifier we
-                // are resolving came from a different hygiene context.
-                if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) {
-                    err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
-                } else {
-                    let doesnt = if is_assoc_fn {
-                        let (span, sugg) = fn_kind
-                            .decl()
-                            .inputs
-                            .get(0)
-                            .map(|p| (p.span.shrink_to_lo(), "&self, "))
-                            .unwrap_or_else(|| {
-                                // Try to look for the "(" after the function name, if possible.
-                                // This avoids placing the suggestion into the visibility specifier.
-                                let span = fn_kind
-                                    .ident()
-                                    .map_or(*span, |ident| span.with_lo(ident.span.hi()));
-                                (
-                                    self.r
-                                        .session
-                                        .source_map()
-                                        .span_through_char(span, '(')
-                                        .shrink_to_hi(),
-                                    "&self",
-                                )
-                            });
-                        err.span_suggestion_verbose(
-                            span,
-                            "add a `self` receiver parameter to make the associated `fn` a method",
-                            sugg,
-                            Applicability::MaybeIncorrect,
-                        );
-                        "doesn't"
-                    } else {
-                        "can't"
-                    };
-                    if let Some(ident) = fn_kind.ident() {
-                        err.span_label(
-                            ident.span,
-                            &format!("this function {} have a `self` parameter", doesnt),
-                        );
-                    }
-                }
-            } else if let Some(item_kind) = self.diagnostic_metadata.current_item {
-                err.span_label(
-                    item_kind.ident.span,
-                    format!(
-                        "`self` not allowed in {} {}",
-                        item_kind.kind.article(),
-                        item_kind.kind.descr()
-                    ),
-                );
-            }
-            return (err, Vec::new());
-        }
-
+    fn try_lookup_name_relaxed(
+        &mut self,
+        err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+        source: PathSource<'_>,
+        path: &[Segment],
+        span: Span,
+        res: Option<Res>,
+        base_error: &BaseError,
+    ) -> (bool, Vec<ImportSuggestion>) {
         // Try to lookup name in more relaxed fashion for better error reporting.
         let ident = path.last().unwrap().ident;
+        let is_expected = &|res| source.is_expected(res);
+        let ns = source.namespace();
+        let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _));
+        let path_str = Segment::names_to_string(path);
+        let ident_span = path.last().map_or(span, |ident| ident.ident.span);
+
         let mut candidates = self
             .r
             .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected)
@@ -494,7 +466,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     {
                         // Already reported this issue on the lhs of the type ascription.
                         err.delay_as_bug();
-                        return (err, candidates);
+                        return (true, candidates);
                     }
                 }
 
@@ -522,8 +494,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 );
             }
         }
+
         // Try Levenshtein algorithm.
-        let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected);
+        let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
         if path.len() == 1 && self.self_type_is_available() {
             if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) {
                 let self_is_available = self.self_value_is_available(path[0].ident.span);
@@ -560,8 +533,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         );
                     }
                 }
-                self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span);
-                return (err, candidates);
+                self.r.add_typo_suggestion(err, typo_sugg, ident_span);
+                return (true, candidates);
             }
 
             // If the first argument in call is `self` suggest calling a method.
@@ -579,14 +552,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     format!("self.{path_str}({args_snippet})"),
                     Applicability::MachineApplicable,
                 );
-                return (err, candidates);
+                return (true, candidates);
             }
         }
 
         // Try context-dependent help if relaxed lookup didn't work.
         if let Some(res) = res {
             if self.smart_resolve_context_dependent_help(
-                &mut err,
+                err,
                 span,
                 source,
                 res,
@@ -594,106 +567,135 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 &base_error.fallback_label,
             ) {
                 // We do this to avoid losing a secondary span when we override the main error span.
-                self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span);
-                return (err, candidates);
+                self.r.add_typo_suggestion(err, typo_sugg, ident_span);
+                return (true, candidates);
             }
         }
+        return (false, candidates);
+    }
 
+    fn suggest_trait_and_bounds(
+        &mut self,
+        err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+        source: PathSource<'_>,
+        res: Option<Res>,
+        span: Span,
+        base_error: &BaseError,
+    ) -> bool {
         let is_macro =
             base_error.span.from_expansion() && base_error.span.desugaring_kind().is_none();
-        if !self.type_ascription_suggestion(&mut err, base_error.span) {
-            let mut fallback = false;
-            if let (
-                PathSource::Trait(AliasPossibility::Maybe),
-                Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)),
-                false,
-            ) = (source, res, is_macro)
-            {
-                if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object {
-                    fallback = true;
-                    let spans: Vec<Span> = bounds
-                        .iter()
-                        .map(|bound| bound.span())
-                        .filter(|&sp| sp != base_error.span)
-                        .collect();
+        let mut fallback = false;
 
-                    let start_span = bounds[0].span();
-                    // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
-                    let end_span = bounds.last().unwrap().span();
-                    // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
-                    let last_bound_span = spans.last().cloned().unwrap();
-                    let mut multi_span: MultiSpan = spans.clone().into();
-                    for sp in spans {
-                        let msg = if sp == last_bound_span {
-                            format!(
-                                "...because of {these} bound{s}",
-                                these = pluralize!("this", bounds.len() - 1),
-                                s = pluralize!(bounds.len() - 1),
-                            )
-                        } else {
-                            String::new()
-                        };
-                        multi_span.push_span_label(sp, msg);
-                    }
-                    multi_span
-                        .push_span_label(base_error.span, "expected this type to be a trait...");
-                    err.span_help(
-                        multi_span,
-                        "`+` is used to constrain a \"trait object\" type with lifetimes or \
-                         auto-traits; structs and enums can't be bound in that way",
-                    );
-                    if bounds.iter().all(|bound| match bound {
-                        ast::GenericBound::Outlives(_) => true,
-                        ast::GenericBound::Trait(tr, _) => tr.span == base_error.span,
-                    }) {
-                        let mut sugg = vec![];
-                        if base_error.span != start_span {
-                            sugg.push((start_span.until(base_error.span), String::new()));
-                        }
-                        if base_error.span != end_span {
-                            sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new()));
-                        }
+        if let (
+            PathSource::Trait(AliasPossibility::Maybe),
+            Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)),
+            false,
+        ) = (source, res, is_macro)
+        {
+            if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object {
+                fallback = true;
+                let spans: Vec<Span> = bounds
+                    .iter()
+                    .map(|bound| bound.span())
+                    .filter(|&sp| sp != base_error.span)
+                    .collect();
 
-                        err.multipart_suggestion(
-                            "if you meant to use a type and not a trait here, remove the bounds",
-                            sugg,
-                            Applicability::MaybeIncorrect,
-                        );
+                let start_span = bounds[0].span();
+                // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
+                let end_span = bounds.last().unwrap().span();
+                // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
+                let last_bound_span = spans.last().cloned().unwrap();
+                let mut multi_span: MultiSpan = spans.clone().into();
+                for sp in spans {
+                    let msg = if sp == last_bound_span {
+                        format!(
+                            "...because of {these} bound{s}",
+                            these = pluralize!("this", bounds.len() - 1),
+                            s = pluralize!(bounds.len() - 1),
+                        )
+                    } else {
+                        String::new()
+                    };
+                    multi_span.push_span_label(sp, msg);
+                }
+                multi_span.push_span_label(base_error.span, "expected this type to be a trait...");
+                err.span_help(
+                    multi_span,
+                    "`+` is used to constrain a \"trait object\" type with lifetimes or \
+                        auto-traits; structs and enums can't be bound in that way",
+                );
+                if bounds.iter().all(|bound| match bound {
+                    ast::GenericBound::Outlives(_) => true,
+                    ast::GenericBound::Trait(tr, _) => tr.span == base_error.span,
+                }) {
+                    let mut sugg = vec![];
+                    if base_error.span != start_span {
+                        sugg.push((start_span.until(base_error.span), String::new()));
                     }
+                    if base_error.span != end_span {
+                        sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new()));
+                    }
+
+                    err.multipart_suggestion(
+                        "if you meant to use a type and not a trait here, remove the bounds",
+                        sugg,
+                        Applicability::MaybeIncorrect,
+                    );
                 }
             }
+        }
 
-            fallback |= self.restrict_assoc_type_in_where_clause(span, &mut err);
+        fallback |= self.restrict_assoc_type_in_where_clause(span, err);
+        fallback
+    }
 
-            if !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span) {
-                fallback = true;
-                match self.diagnostic_metadata.current_let_binding {
-                    Some((pat_sp, Some(ty_sp), None))
-                        if ty_sp.contains(base_error.span) && base_error.could_be_expr =>
-                    {
-                        err.span_suggestion_short(
-                            pat_sp.between(ty_sp),
-                            "use `=` if you meant to assign",
-                            " = ",
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                    _ => {}
+    fn suggest_typo(
+        &mut self,
+        err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+        source: PathSource<'_>,
+        path: &[Segment],
+        span: Span,
+        base_error: &BaseError,
+    ) -> bool {
+        let is_expected = &|res| source.is_expected(res);
+        let ident_span = path.last().map_or(span, |ident| ident.ident.span);
+        let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
+        let mut fallback = false;
+        if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) {
+            fallback = true;
+            match self.diagnostic_metadata.current_let_binding {
+                Some((pat_sp, Some(ty_sp), None))
+                    if ty_sp.contains(base_error.span) && base_error.could_be_expr =>
+                {
+                    err.span_suggestion_short(
+                        pat_sp.between(ty_sp),
+                        "use `=` if you meant to assign",
+                        " = ",
+                        Applicability::MaybeIncorrect,
+                    );
                 }
-
-                // If the trait has a single item (which wasn't matched by Levenshtein), suggest it
-                let suggestion = self.get_single_associated_item(&path, &source, is_expected);
-                self.r.add_typo_suggestion(&mut err, suggestion, ident_span);
-            }
-            if fallback {
-                // Fallback label.
-                err.span_label(base_error.span, base_error.fallback_label);
+                _ => {}
             }
+
+            // If the trait has a single item (which wasn't matched by Levenshtein), suggest it
+            let suggestion = self.get_single_associated_item(&path, &source, is_expected);
+            self.r.add_typo_suggestion(err, suggestion, ident_span);
         }
+        fallback
+    }
+
+    fn err_code_special_cases(
+        &mut self,
+        err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+        source: PathSource<'_>,
+        path: &[Segment],
+        span: Span,
+    ) {
         if let Some(err_code) = &err.code {
             if err_code == &rustc_errors::error_code!(E0425) {
                 for label_rib in &self.label_ribs {
                     for (label_ident, node_id) in &label_rib.bindings {
+                        let ident = path.last().unwrap().ident;
                         if format!("'{}", ident) == label_ident.to_string() {
                             err.span_label(label_ident.span, "a label with a similar name exists");
                             if let PathSource::Expr(Some(Expr {
@@ -724,38 +726,116 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 }
             }
         }
+    }
 
-        (err, candidates)
+    /// Emit special messages for unresolved `Self` and `self`.
+    fn suggest_self_ty(
+        &mut self,
+        err: &mut Diagnostic,
+        source: PathSource<'_>,
+        path: &[Segment],
+        span: Span,
+    ) -> bool {
+        if !is_self_type(path, source.namespace()) {
+            return false;
+        }
+        err.code(rustc_errors::error_code!(E0411));
+        err.span_label(
+            span,
+            "`Self` is only available in impls, traits, and type definitions".to_string(),
+        );
+        if let Some(item_kind) = self.diagnostic_metadata.current_item {
+            err.span_label(
+                item_kind.ident.span,
+                format!(
+                    "`Self` not allowed in {} {}",
+                    item_kind.kind.article(),
+                    item_kind.kind.descr()
+                ),
+            );
+        }
+        true
     }
 
-    fn detect_assoct_type_constraint_meant_as_path(&self, base_span: Span, err: &mut Diagnostic) {
-        let Some(ty) = self.diagnostic_metadata.current_type_path else { return; };
-        let TyKind::Path(_, path) = &ty.kind else { return; };
-        for segment in &path.segments {
-            let Some(params) = &segment.args else { continue; };
-            let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; };
-            for param in &params.args {
-                let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; };
-                let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else {
-                    continue;
+    fn suggest_self_value(
+        &mut self,
+        err: &mut Diagnostic,
+        source: PathSource<'_>,
+        path: &[Segment],
+        span: Span,
+    ) -> bool {
+        if !is_self_value(path, source.namespace()) {
+            return false;
+        }
+
+        debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
+        err.code(rustc_errors::error_code!(E0424));
+        err.span_label(
+            span,
+            match source {
+                PathSource::Pat => {
+                    "`self` value is a keyword and may not be bound to variables or shadowed"
+                }
+                _ => "`self` value is a keyword only available in methods with a `self` parameter",
+            },
+        );
+        let is_assoc_fn = self.self_type_is_available();
+        if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function {
+            // The current function has a `self' parameter, but we were unable to resolve
+            // a reference to `self`. This can only happen if the `self` identifier we
+            // are resolving came from a different hygiene context.
+            if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) {
+                err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
+            } else {
+                let doesnt = if is_assoc_fn {
+                    let (span, sugg) = fn_kind
+                        .decl()
+                        .inputs
+                        .get(0)
+                        .map(|p| (p.span.shrink_to_lo(), "&self, "))
+                        .unwrap_or_else(|| {
+                            // Try to look for the "(" after the function name, if possible.
+                            // This avoids placing the suggestion into the visibility specifier.
+                            let span = fn_kind
+                                .ident()
+                                .map_or(*span, |ident| span.with_lo(ident.span.hi()));
+                            (
+                                self.r
+                                    .session
+                                    .source_map()
+                                    .span_through_char(span, '(')
+                                    .shrink_to_hi(),
+                                "&self",
+                            )
+                        });
+                    err.span_suggestion_verbose(
+                        span,
+                        "add a `self` receiver parameter to make the associated `fn` a method",
+                        sugg,
+                        Applicability::MaybeIncorrect,
+                    );
+                    "doesn't"
+                } else {
+                    "can't"
                 };
-                for bound in bounds {
-                    let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None)
-                        = bound else
-                    {
-                        continue;
-                    };
-                    if base_span == trait_ref.span {
-                        err.span_suggestion_verbose(
-                            constraint.ident.span.between(trait_ref.span),
-                            "you might have meant to write a path instead of an associated type bound",
-                            "::",
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                if let Some(ident) = fn_kind.ident() {
+                    err.span_label(
+                        ident.span,
+                        &format!("this function {} have a `self` parameter", doesnt),
+                    );
                 }
             }
+        } else if let Some(item_kind) = self.diagnostic_metadata.current_item {
+            err.span_label(
+                item_kind.ident.span,
+                format!(
+                    "`self` not allowed in {} {}",
+                    item_kind.kind.article(),
+                    item_kind.kind.descr()
+                ),
+            );
         }
+        true
     }
 
     fn suggest_swapping_misplaced_self_ty_and_trait(
@@ -787,6 +867,45 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
 
+    fn suggest_bare_struct_literal(&mut self, err: &mut Diagnostic) {
+        if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal {
+            err.multipart_suggestion(
+                "you might have meant to write a `struct` literal",
+                vec![
+                    (span.shrink_to_lo(), "{ SomeStruct ".to_string()),
+                    (span.shrink_to_hi(), "}".to_string()),
+                ],
+                Applicability::HasPlaceholders,
+            );
+        }
+    }
+
+    fn suggest_pattern_match_with_let(
+        &mut self,
+        err: &mut Diagnostic,
+        source: PathSource<'_>,
+        span: Span,
+    ) {
+        if let PathSource::Expr(_) = source &&
+        let Some(Expr {
+                    span: expr_span,
+                    kind: ExprKind::Assign(lhs, _, _),
+                    ..
+                })  = self.diagnostic_metadata.in_if_condition {
+            // Icky heuristic so we don't suggest:
+            // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern)
+            // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span)
+            if lhs.is_approximately_pattern() && lhs.span.contains(span) {
+                err.span_suggestion_verbose(
+                    expr_span.shrink_to_lo(),
+                    "you might have meant to use pattern matching",
+                    "let ",
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        }
+    }
+
     fn get_single_associated_item(
         &mut self,
         path: &[Segment],
@@ -1330,7 +1449,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                     Applicability::HasPlaceholders,
                 );
             }
-            (Res::SelfTy { .. }, _) if ns == ValueNS => {
+            (Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }, _) if ns == ValueNS => {
                 err.span_label(span, fallback_label);
                 err.note("can't use `Self` as a constructor, you must use the implemented struct");
             }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 9fb1af20ac9..0c29ff364dc 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -326,6 +326,7 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime
     }
 
     debug!(?rl.defs);
+    debug!(?rl.late_bound_vars);
     rl
 }
 
@@ -507,7 +508,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     })
                     .unzip();
 
-            self.map.late_bound_vars.insert(e.hir_id, binders);
+            self.record_late_bound_vars(e.hir_id, binders);
             let scope = Scope::Binder {
                 hir_id: e.hir_id,
                 lifetimes,
@@ -531,7 +532,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         match &item.kind {
             hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => {
                 if let Some(of_trait) = of_trait {
-                    self.map.late_bound_vars.insert(of_trait.hir_ref_id, Vec::default());
+                    self.record_late_bound_vars(of_trait.hir_ref_id, Vec::default());
                 }
             }
             _ => {}
@@ -583,7 +584,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                                 resolved_lifetimes.late_bound_vars.iter()
                             {
                                 late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| {
-                                    self.map.late_bound_vars.insert(
+                                    self.record_late_bound_vars(
                                         hir::HirId { owner, local_id },
                                         late_bound_vars.clone(),
                                     );
@@ -614,7 +615,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
                     })
                     .collect();
-                self.map.late_bound_vars.insert(item.hir_id(), vec![]);
+                self.record_late_bound_vars(item.hir_id(), vec![]);
                 let scope = Scope::Binder {
                     hir_id: item.hir_id(),
                     lifetimes,
@@ -663,7 +664,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         (pair, r)
                     })
                     .unzip();
-                self.map.late_bound_vars.insert(ty.hir_id, binders);
+                self.record_late_bound_vars(ty.hir_id, binders);
                 let scope = Scope::Binder {
                     hir_id: ty.hir_id,
                     lifetimes,
@@ -817,7 +818,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {}
                     }
                 }
-                self.map.late_bound_vars.insert(ty.hir_id, vec![]);
+                self.record_late_bound_vars(ty.hir_id, vec![]);
 
                 let scope = Scope::Binder {
                     hir_id: ty.hir_id,
@@ -861,7 +862,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
                     })
                     .collect();
-                self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]);
+                self.record_late_bound_vars(trait_item.hir_id(), vec![]);
                 let scope = Scope::Binder {
                     hir_id: trait_item.hir_id(),
                     lifetimes,
@@ -909,9 +910,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                         GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None,
                     })
                     .collect();
-                self.map.late_bound_vars.insert(ty.hir_id, vec![]);
+                self.record_late_bound_vars(impl_item.hir_id(), vec![]);
                 let scope = Scope::Binder {
-                    hir_id: ty.hir_id,
+                    hir_id: impl_item.hir_id(),
                     lifetimes,
                     s: self.scope,
                     scope_type: BinderScopeType::Normal,
@@ -995,13 +996,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             for predicate in generics.predicates {
                 match predicate {
                     &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+                        hir_id,
                         ref bounded_ty,
                         bounds,
                         ref bound_generic_params,
                         origin,
                         ..
                     }) => {
-                        let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) =
+                        let lifetimes: FxIndexMap<LocalDefId, Region> =
                             bound_generic_params
                                 .iter()
                                 .filter(|param| {
@@ -1009,19 +1011,23 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                                 })
                                 .enumerate()
                                 .map(|(late_bound_idx, param)| {
-                                    let pair =
-                                        Region::late(late_bound_idx as u32, this.tcx.hir(), param);
-                                    let r = late_region_as_bound_region(this.tcx, &pair.1);
-                                    (pair, r)
+                                        Region::late(late_bound_idx as u32, this.tcx.hir(), param)
+                                })
+                                .collect();
+                        let binders: Vec<_> =
+                            lifetimes
+                                .iter()
+                                .map(|(_, region)| {
+                                     late_region_as_bound_region(this.tcx, region)
                                 })
-                                .unzip();
-                        this.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone());
+                                .collect();
+                        this.record_late_bound_vars(hir_id, binders.clone());
                         // Even if there are no lifetimes defined here, we still wrap it in a binder
                         // scope. If there happens to be a nested poly trait ref (an error), that
                         // will be `Concatenating` anyways, so we don't have to worry about the depth
                         // being wrong.
                         let scope = Scope::Binder {
-                            hir_id: bounded_ty.hir_id,
+                            hir_id,
                             lifetimes,
                             s: this.scope,
                             scope_type: BinderScopeType::Normal,
@@ -1089,7 +1095,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 // imagine there's a better way to go about this.
                 let (binders, scope_type) = self.poly_trait_ref_binder_info();
 
-                self.map.late_bound_vars.insert(*hir_id, binders);
+                self.record_late_bound_vars(*hir_id, binders);
                 let scope = Scope::Binder {
                     hir_id: *hir_id,
                     lifetimes: FxIndexMap::default(),
@@ -1127,7 +1133,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         binders.extend(binders_iter);
 
         debug!(?binders);
-        self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders);
+        self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders);
 
         // Always introduce a scope here, even if this is in a where clause and
         // we introduced the binders around the bounded Ty. In that case, we
@@ -1211,6 +1217,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         }
     }
 
+    fn record_late_bound_vars(&mut self, hir_id: hir::HirId, binder: Vec<ty::BoundVariableKind>) {
+        if let Some(old) = self.map.late_bound_vars.insert(hir_id, binder) {
+            bug!(
+                "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}",
+                self.map.late_bound_vars[&hir_id]
+            )
+        }
+    }
+
     /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
     ///
     /// Handles visiting fns and methods. These are a bit complicated because we must distinguish
@@ -1268,7 +1283,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 late_region_as_bound_region(self.tcx, &pair.1)
             })
             .collect();
-        self.map.late_bound_vars.insert(hir_id, binders);
+        self.record_late_bound_vars(hir_id, binders);
         let scope = Scope::Binder {
             hir_id,
             lifetimes,
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index adbc119387d..ecb09f0c4b7 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -913,7 +913,8 @@ impl<'tcx> DumpVisitor<'tcx> {
                     | HirDefKind::AssocTy,
                     _,
                 )
-                | Res::SelfTy { .. } => {
+                | Res::SelfTyParam { .. }
+                | Res::SelfTyAlias { .. } => {
                     self.dump_path_segment_ref(
                         id,
                         &hir::PathSegment::new(ident, hir::HirId::INVALID, Res::Err),
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index ad7aca3cb94..aa000b7067b 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -740,7 +740,8 @@ impl<'tcx> SaveContext<'tcx> {
                 _,
             )
             | Res::PrimTy(..)
-            | Res::SelfTy { .. }
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
             | Res::ToolMod
             | Res::NonMacroAttr(..)
             | Res::SelfCtor(..)
@@ -805,7 +806,7 @@ impl<'tcx> SaveContext<'tcx> {
 
     fn lookup_def_id(&self, ref_id: hir::HirId) -> Option<DefId> {
         match self.get_path_res(ref_id) {
-            Res::PrimTy(_) | Res::SelfTy { .. } | Res::Err => None,
+            Res::PrimTy(_) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => None,
             def => def.opt_def_id(),
         }
     }
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index bae1828cd18..62e9f6520fb 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -579,7 +579,7 @@ impl<'hir> Sig for hir::Path<'hir> {
         let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
 
         let (name, start, end) = match res {
-            Res::PrimTy(..) | Res::SelfTy { .. } | Res::Err => {
+            Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => {
                 return Ok(Signature { text: path_to_string(self), defs: vec![], refs: vec![] });
             }
             Res::Def(DefKind::AssocConst | DefKind::Variant | DefKind::Ctor(..), _) => {
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index d97e1df2a16..2c3d8d5283b 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -2,9 +2,7 @@
 //! It also serves as an input to the parser itself.
 
 use crate::config::CheckCfg;
-use crate::errors::{
-    ExprParenthesesNeeded, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError,
-};
+use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError};
 use crate::lint::{
     builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
 };
@@ -13,8 +11,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
 use rustc_errors::{
-    fallback_fluent_bundle, AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticId,
-    DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
+    fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
+    EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
 };
 use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
 use rustc_span::edition::Edition;
@@ -324,12 +322,6 @@ impl ParseSess {
         });
     }
 
-    /// Extend an error with a suggestion to wrap an expression with parentheses to allow the
-    /// parser to continue parsing the following operation as part of the same expression.
-    pub fn expr_parentheses_needed(&self, err: &mut Diagnostic, span: Span) {
-        ExprParenthesesNeeded::surrounding(span).add_to_diagnostic(err);
-    }
-
     pub fn save_proc_macro_span(&self, span: Span) -> usize {
         let mut spans = self.proc_macro_quoted_spans.lock();
         spans.push(span);
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 37b8371a8fe..bbeabdb55a7 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -218,7 +218,9 @@ impl<D: Decoder> Decodable<D> for DefIndex {
 /// index and a def index.
 ///
 /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)]
+#[derive(Clone, PartialEq, Eq, Copy)]
+// Don't derive order on 64-bit big-endian, so we can be consistent regardless of field order.
+#[cfg_attr(not(all(target_pointer_width = "64", target_endian = "big")), derive(PartialOrd, Ord))]
 // On below-64 bit systems we can simply use the derived `Hash` impl
 #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))]
 #[repr(C)]
@@ -260,6 +262,22 @@ impl Hash for DefId {
     }
 }
 
+// Implement the same comparison as derived with the other field order.
+#[cfg(all(target_pointer_width = "64", target_endian = "big"))]
+impl Ord for DefId {
+    #[inline]
+    fn cmp(&self, other: &DefId) -> std::cmp::Ordering {
+        Ord::cmp(&(self.index, self.krate), &(other.index, other.krate))
+    }
+}
+#[cfg(all(target_pointer_width = "64", target_endian = "big"))]
+impl PartialOrd for DefId {
+    #[inline]
+    fn partial_cmp(&self, other: &DefId) -> Option<std::cmp::Ordering> {
+        Some(Ord::cmp(self, other))
+    }
+}
+
 impl DefId {
     /// Makes a local `DefId` from the given `DefIndex`.
     #[inline]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 07f3656d086..8cb7d147d02 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1296,6 +1296,7 @@ symbols! {
         rustc_reallocator,
         rustc_regions,
         rustc_reservation_impl,
+        rustc_safe_intrinsic,
         rustc_serialize,
         rustc_skip_array_during_method_dispatch,
         rustc_specialization_trait,
@@ -1703,6 +1704,7 @@ impl Ident {
     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
     /// non-transparent macros.
     /// Technically, this operation strips all transparent marks from ident's syntactic context.
+    #[inline]
     pub fn normalize_to_macro_rules(self) -> Ident {
         Ident::new(self.name, self.span.normalize_to_macro_rules())
     }
@@ -1718,6 +1720,7 @@ impl Ident {
 }
 
 impl PartialEq for Ident {
+    #[inline]
     fn eq(&self, rhs: &Self) -> bool {
         self.name == rhs.name && self.span.eq_ctxt(rhs.span)
     }
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 18e7e74741a..ecfe6861e84 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -301,7 +301,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
 
         // Encode impl generic params if the substitutions contain parameters (implying
         // polymorphization is enabled) and this isn't an inherent impl.
-        if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_param_types_or_consts()) {
+        if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_non_region_param()) {
             self = self.path_generic_args(
                 |this| {
                     this.path_append_ns(
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index ec334e5887a..7171ca7bf89 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -1392,7 +1392,7 @@ pub struct PointeeInfo {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum InitKind {
     Zero,
-    Uninit,
+    UninitMitigated0x01Fill,
 }
 
 /// Trait that needs to be implemented by the higher-level type representation
@@ -1498,72 +1498,4 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
             Abi::Aggregate { sized } => sized && self.size.bytes() == 0,
         }
     }
-
-    /// Determines if this type permits "raw" initialization by just transmuting some
-    /// memory into an instance of `T`.
-    ///
-    /// `init_kind` indicates if the memory is zero-initialized or left uninitialized.
-    ///
-    /// This code is intentionally conservative, and will not detect
-    /// * zero init of an enum whose 0 variant does not allow zero initialization
-    /// * making uninitialized types who have a full valid range (ints, floats, raw pointers)
-    /// * Any form of invalid value being made inside an array (unless the value is uninhabited)
-    ///
-    /// A strict form of these checks that uses const evaluation exists in
-    /// `rustc_const_eval::might_permit_raw_init`, and a tracking issue for making these checks
-    /// stricter is <https://github.com/rust-lang/rust/issues/66151>.
-    ///
-    /// FIXME: Once all the conservatism is removed from here, and the checks are ran by default,
-    /// we can use the const evaluation checks always instead.
-    pub fn might_permit_raw_init<C>(self, cx: &C, init_kind: InitKind) -> bool
-    where
-        Self: Copy,
-        Ty: TyAbiInterface<'a, C>,
-        C: HasDataLayout,
-    {
-        let scalar_allows_raw_init = move |s: Scalar| -> bool {
-            match init_kind {
-                InitKind::Zero => {
-                    // The range must contain 0.
-                    s.valid_range(cx).contains(0)
-                }
-                InitKind::Uninit => {
-                    // The range must include all values.
-                    s.is_always_valid(cx)
-                }
-            }
-        };
-
-        // Check the ABI.
-        let valid = match self.abi {
-            Abi::Uninhabited => false, // definitely UB
-            Abi::Scalar(s) => scalar_allows_raw_init(s),
-            Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2),
-            Abi::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s),
-            Abi::Aggregate { .. } => true, // Fields are checked below.
-        };
-        if !valid {
-            // This is definitely not okay.
-            return false;
-        }
-
-        // If we have not found an error yet, we need to recursively descend into fields.
-        match &self.fields {
-            FieldsShape::Primitive | FieldsShape::Union { .. } => {}
-            FieldsShape::Array { .. } => {
-                // FIXME(#66151): For now, we are conservative and do not check arrays by default.
-            }
-            FieldsShape::Arbitrary { offsets, .. } => {
-                for idx in 0..offsets.len() {
-                    if !self.field(cx, idx).might_permit_raw_init(cx, init_kind) {
-                        // We found a field that is unhappy with this kind of initialization.
-                        return false;
-                    }
-                }
-            }
-        }
-
-        // FIXME(#66151): For now, we are conservative and do not check `self.variants`.
-        true
-    }
 }
diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs
index 8b6266c5800..b85214a9c6b 100644
--- a/compiler/rustc_target/src/spec/i386_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs
@@ -14,8 +14,7 @@ pub fn target() -> Target {
         arch: "x86".into(),
         options: TargetOptions {
             max_atomic_width: Some(64),
-            // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-            stack_probes: StackProbeType::Call,
+            stack_probes: StackProbeType::X86,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
index 5e9ceb844f7..99b9d88e642 100644
--- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
@@ -7,8 +7,7 @@ pub fn target() -> Target {
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
     base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.frame_pointer = FramePointer::Always;
 
     // Clang automatically chooses a more specific target based on
diff --git a/compiler/rustc_target/src/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs
index bdaf5c99069..c7c30c23901 100644
--- a/compiler/rustc_target/src/spec/i686_linux_android.rs
+++ b/compiler/rustc_target/src/spec/i686_linux_android.rs
@@ -11,8 +11,7 @@ pub fn target() -> Target {
     // https://developer.android.com/ndk/guides/abis.html#x86
     base.cpu = "pentiumpro".into();
     base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into();
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-linux-android".into(),
diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
index aff284bf2bc..7d201245006 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-unknown-freebsd".into(),
diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
index 87aa74e406c..357cc547fa0 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-unknown-haiku".into(),
diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
index f62029c9067..bb7b5680298 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
@@ -6,8 +6,7 @@ pub fn target() -> Target {
     base.max_atomic_width = Some(64);
     base.supported_sanitizers = SanitizerSet::ADDRESS;
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
index d9492804349..f6047919674 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind
     // implementation, apparently relies on frame pointers existing... somehow.
diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
index 8de698b51f0..0fd2d1231df 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-unknown-netbsdelf".into(),
diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
index 7f25a1a16c1..2952c043daa 100644
--- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-unknown-openbsd".into(),
diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
index f62404e8279..4a0d98efd82 100644
--- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "pentium4".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "i686-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs
index 0f5d85205f8..f41533a9548 100644
--- a/compiler/rustc_target/src/spec/linux_kernel_base.rs
+++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs
@@ -6,8 +6,7 @@ pub fn opts() -> TargetOptions {
         env: "gnu".into(),
         disable_redzone: true,
         panic_strategy: PanicStrategy::Abort,
-        // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-        stack_probes: StackProbeType::Call,
+        stack_probes: StackProbeType::X86,
         frame_pointer: FramePointer::Always,
         position_independent_executables: true,
         needs_plt: true,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 35b4cce50a0..af85e2f4feb 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -635,6 +635,10 @@ pub enum StackProbeType {
 }
 
 impl StackProbeType {
+    // LLVM X86 targets (ix86 and x86_64) can use inline-asm stack probes starting with LLVM 16.
+    // Notable past issues were rust#83139 (fixed in 14) and rust#84667 (fixed in 16).
+    const X86: Self = Self::InlineOrCall { min_llvm_version_for_inline: (16, 0, 0) };
+
     fn from_json(json: &Json) -> Result<Self, String> {
         let object = json.as_object().ok_or_else(|| "expected a JSON object")?;
         let kind = object
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
index 803453c4ac4..9f4cc3d80f1 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs
@@ -1,11 +1,12 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::freebsd_base::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64-unknown-freebsd".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
index 1cb9ce40cb1..21955a616c2 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
@@ -1,11 +1,12 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
index 159335eb607..bbf86e4ff41 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
@@ -1,11 +1,12 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_musl_base::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs
index 9cb3a67dc58..bfa61a21fb3 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs
@@ -1,11 +1,12 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::openbsd_base::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64-unknown-openbsd".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
index b7420d232ca..4ebf342ad22 100644
--- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
@@ -1,11 +1,12 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::vxworks_base::opts();
     base.cpu = "ppc64".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs
index a3d18004371..a7ab9078531 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs
@@ -1,10 +1,11 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::freebsd_base::opts();
     base.cpu = "ppc64le".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64le-unknown-freebsd".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
index e18ff3be448..69fd6be6dc0 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
@@ -1,10 +1,11 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.cpu = "ppc64le".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64le-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
index b84943d23a9..ae3a8b54519 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
@@ -1,10 +1,11 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_musl_base::opts();
     base.cpu = "ppc64le".into();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc64le-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
index 75ac66c276d..b5d4e5de05e 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
@@ -1,11 +1,12 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::freebsd_base::opts();
     // Extra hint to linker that we are generating secure-PLT code.
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-freebsd13.0".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
index 6686a0bbf04..0ceb66c327b 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
index 6a250f4b51c..716090f39ca 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-linux-gnuspe".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
index 34200c67906..d8cd158584a 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_musl_base::opts();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
index 60661ef9b5d..7053e4b9c26 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::netbsd_base::opts();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-netbsd".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs
index ad2c3d40f35..dec85f9961b 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::Target;
+use crate::spec::{StackProbeType, Target};
 
 pub fn target() -> Target {
     let mut base = super::openbsd_base::opts();
     base.endian = Endian::Big;
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-openbsd".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
index 3f24966e06e..e0c5db6eacf 100644
--- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::vxworks_base::opts();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-linux-gnu".into(),
diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
index 0f04f41f9e5..c7f41b1da87 100644
--- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
@@ -1,10 +1,11 @@
 use crate::abi::Endian;
-use crate::spec::{LinkerFlavor, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::vxworks_base::opts();
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]);
     base.max_atomic_width = Some(32);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "powerpc-unknown-linux-gnuspe".into(),
diff --git a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs
index 8757bbed8ad..cda88de0ea4 100644
--- a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs
@@ -1,22 +1,23 @@
 use crate::abi::Endian;
-use crate::spec::Target;
+use crate::spec::{StackProbeType, Target};
 
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.endian = Endian::Big;
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
-    // FIXME: The data_layout string below and the ABI implementation in
-    // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
-    // Pass the -vector feature string to LLVM to respect this assumption.
+    // FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector
+    // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
+    // also strip v128 from the data_layout below to match the older LLVM's expectation.
     base.features = "-vector".into();
     base.max_atomic_width = Some(64);
     base.min_global_align = Some(16);
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "s390x-unknown-linux-gnu".into(),
         pointer_width: 64,
-        data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".into(),
+        data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(),
         arch: "s390x".into(),
         options: base,
     }
diff --git a/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs
index 4c855271a2a..91e63aee5e4 100644
--- a/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs
@@ -1,23 +1,24 @@
 use crate::abi::Endian;
-use crate::spec::Target;
+use crate::spec::{StackProbeType, Target};
 
 pub fn target() -> Target {
     let mut base = super::linux_musl_base::opts();
     base.endian = Endian::Big;
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
-    // FIXME: The data_layout string below and the ABI implementation in
-    // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
-    // Pass the -vector feature string to LLVM to respect this assumption.
+    // FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector
+    // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
+    // also strip v128 from the data_layout below to match the older LLVM's expectation.
     base.features = "-vector".into();
     base.max_atomic_width = Some(64);
     base.min_global_align = Some(16);
     base.static_position_independent_executables = true;
+    base.stack_probes = StackProbeType::Inline;
 
     Target {
         llvm_target: "s390x-unknown-linux-musl".into(),
         pointer_width: 64,
-        data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".into(),
+        data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(),
         arch: "s390x".into(),
         options: base,
     }
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index 176c9dd6b76..ad96923320c 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -9,8 +9,7 @@ pub fn target() -> Target {
     base.frame_pointer = FramePointer::Always;
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
     base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
 
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
index 5e64ed0cff6..e6143025d6d 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
@@ -13,8 +13,7 @@ pub fn target() -> Target {
         arch: "x86_64".into(),
         options: TargetOptions {
             max_atomic_width: Some(64),
-            // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-            stack_probes: StackProbeType::Call,
+            stack_probes: StackProbeType::X86,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
index 2122bcd37fc..61591dacf45 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
@@ -15,8 +15,7 @@ pub fn target() -> Target {
         arch: "x86_64".into(),
         options: TargetOptions {
             max_atomic_width: Some(64),
-            // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-            stack_probes: StackProbeType::Call,
+            stack_probes: StackProbeType::X86,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
index a848c5a0aff..3d54da0867c 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
@@ -10,8 +10,7 @@ pub fn target() -> Target {
         arch: "x86_64".into(),
         options: TargetOptions {
             max_atomic_width: Some(64),
-            // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-            stack_probes: StackProbeType::Call,
+            stack_probes: StackProbeType::X86,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
index 4dff3c2f209..e499b1985e7 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
@@ -15,8 +15,7 @@ pub fn target() -> Target {
         arch: "x86_64".into(),
         options: TargetOptions {
             max_atomic_width: Some(64),
-            // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-            stack_probes: StackProbeType::Call,
+            stack_probes: StackProbeType::X86,
             forces_embed_bitcode: true,
             // Taken from a clang build on Xcode 11.4.1.
             // These arguments are not actually invoked - they just have
diff --git a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs
index 4f88fc3500b..532dd6d0742 100644
--- a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs
@@ -4,8 +4,7 @@ pub fn target() -> Target {
     let mut base = super::fuchsia_base::opts();
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
 
     Target {
diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs
index 6d19cf26574..4db5ec7fd28 100644
--- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs
@@ -7,8 +7,7 @@ pub fn target() -> Target {
     base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "x86_64-linux-android".into(),
diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
index 0550b221fd9..974359a138b 100644
--- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
@@ -6,8 +6,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.vendor = "pc".into();
     base.max_atomic_width = Some(64);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
 
     Target {
diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
index cbe87589a70..a2fe371a2b8 100644
--- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs
@@ -6,8 +6,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.vendor = "sun".into();
     base.max_atomic_width = Some(64);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "x86_64-pc-solaris".into(),
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
index 746f6478178..989e6432b66 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "x86_64-unknown-dragonfly".into(),
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
index b30784ed692..24b5b4beebc 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD;
 
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
index d6d03362982..e3f14aeeea9 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     // This option is required to build executables on Haiku x86_64
     base.position_independent_executables = true;
 
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs
index d315301615b..fb1af33f80a 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.features = "+rdrnd,+rdseed".into();
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "x86_64-unknown-hermit".into(),
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
index 956be0353fa..34e20544da6 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.static_position_independent_executables = true;
     base.supported_sanitizers = SanitizerSet::ADDRESS
         | SanitizerSet::CFI
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
index 140882747c2..23a1f5d80f2 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
@@ -6,8 +6,7 @@ pub fn target() -> Target {
     base.abi = "x32".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-mx32"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.has_thread_local = false;
     // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
     // breaks code gen. See LLVM bug 36743
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
index 87e7784d1f9..179f0995456 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.static_position_independent_executables = true;
     base.supported_sanitizers = SanitizerSet::ADDRESS
         | SanitizerSet::CFI
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
index d3a67619aa8..ac77dfb6415 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.supported_sanitizers = SanitizerSet::ADDRESS
         | SanitizerSet::CFI
         | SanitizerSet::LEAK
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
index b9a345127e3..871cdd02078 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs
@@ -11,8 +11,7 @@ pub fn target() -> Target {
     let opts = TargetOptions {
         cpu: "x86-64".into(),
         max_atomic_width: Some(64),
-        // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-        stack_probes: StackProbeType::Call,
+        stack_probes: StackProbeType::X86,
         position_independent_executables: true,
         static_position_independent_executables: true,
         relro_level: RelroLevel::Full,
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
index f50c6bceec9..b8084d513f7 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "x86_64-unknown-openbsd".into(),
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
index 668ae905417..a2a143f856d 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
 
     Target {
         llvm_target: "x86_64-unknown-redox".into(),
diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
index 1298974952f..187027d3889 100644
--- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs
@@ -5,8 +5,7 @@ pub fn target() -> Target {
     base.cpu = "x86-64".into();
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
-    // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
-    base.stack_probes = StackProbeType::Call;
+    base.stack_probes = StackProbeType::X86;
     base.disable_redzone = true;
 
     Target {
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index dc585fca34f..911d1cf8bdf 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -235,14 +235,18 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
                   .emit()
             }
 
-            Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
-                NotConstEvaluatable::MentionsInfer
-                } else if uv.has_param_types_or_consts() {
-                NotConstEvaluatable::MentionsParam
-            } else {
-                let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?"));
-                NotConstEvaluatable::Error(guar)
-            }),
+            Err(ErrorHandled::TooGeneric) => {
+                let err = if uv.has_non_region_infer() {
+                    NotConstEvaluatable::MentionsInfer
+                } else if uv.has_non_region_param() {
+                    NotConstEvaluatable::MentionsParam
+                } else {
+                    let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?"));
+                    NotConstEvaluatable::Error(guar)
+                };
+
+                Err(err)
+            },
             Err(ErrorHandled::Linted) => {
                 let reported =
                     infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
@@ -250,23 +254,23 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
             }
             Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
             Ok(_) => {
-              if uv.substs.has_param_types_or_consts() {
-                  assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
-                  let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
+                if uv.substs.has_non_region_param() {
+                    assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
+                    let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
 
-                  if mir_body.is_polymorphic {
-                      let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
-                      tcx.struct_span_lint_hir(
-                          lint::builtin::CONST_EVALUATABLE_UNCHECKED,
-                          tcx.hir().local_def_id_to_hir_id(local_def_id),
-                          span,
-                          |err| {
-                              err.build("cannot use constants which depend on generic parameters in types").emit();
-                        })
-                  }
-              }
+                    if mir_body.is_polymorphic {
+                        let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
+                        tcx.struct_span_lint_hir(
+                            lint::builtin::CONST_EVALUATABLE_UNCHECKED,
+                            tcx.hir().local_def_id_to_hir_id(local_def_id),
+                            span,
+                            "cannot use constants which depend on generic parameters in types",
+                            |err| err
+                        )
+                    }
+                }
 
-              Ok(())
+                Ok(())
             },
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index b0cabc6275f..6dcf9c4d261 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -661,7 +661,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                                     );
                                 }
                             }
-                        } else if !trait_ref.has_infer_types_or_consts()
+                        } else if !trait_ref.has_non_region_infer()
                             && self.predicate_can_apply(obligation.param_env, trait_ref)
                         {
                             // If a where-clause may be useful, remind the
@@ -2093,7 +2093,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 // Pick the first substitution that still contains inference variables as the one
                 // we're going to emit an error for. If there are none (see above), fall back to
                 // a more general error.
-                let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts());
+                let subst = data.trait_ref.substs.iter().find(|s| s.has_non_region_infer());
 
                 let mut err = if let Some(subst) = subst {
                     self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true)
@@ -2263,13 +2263,22 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                                     trait_impls.non_blanket_impls().len()
                                 )
                             };
-
+                            let mut suggestions = vec![(
+                                trait_path_segment.ident.span.shrink_to_lo(),
+                                format!("<{} as ", self.tcx.type_of(impl_def_id))
+                            )];
+                            if let Some(generic_arg) = trait_path_segment.args {
+                                let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext);
+                                // get rid of :: between Trait and <type>
+                                // must be '::' between them, otherwise the parser won't accept the code
+                                suggestions.push((between_span, "".to_string(),));
+                                suggestions.push((generic_arg.span_ext.shrink_to_hi(), format!(">")));
+                            } else {
+                                suggestions.push((trait_path_segment.ident.span.shrink_to_hi(), format!(">")));
+                            }
                             err.multipart_suggestion(
                                 message,
-                                vec![
-                                    (trait_path_segment.ident.span.shrink_to_lo(), format!("<{} as ", self.tcx.def_path(impl_def_id).to_string_no_crate_verbose())),
-                                    (trait_path_segment.ident.span.shrink_to_hi(), format!(">"))
-                                ],
+                                suggestions,
                                 Applicability::MaybeIncorrect
                             );
                         }
@@ -2314,7 +2323,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                     .substs
                     .iter()
                     .chain(Some(data.term.into_arg()))
-                    .find(|g| g.has_infer_types_or_consts());
+                    .find(|g| g.has_non_region_infer());
                 if let Some(subst) = subst {
                     let mut err = self.emit_inference_failure_err(
                         body_id,
@@ -2343,7 +2352,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 if predicate.references_error() || self.is_tainted_by_errors() {
                     return;
                 }
-                let subst = data.substs.iter().find(|g| g.has_infer_types_or_consts());
+                let subst = data.substs.iter().find(|g| g.has_non_region_infer());
                 if let Some(subst) = subst {
                     let err = self.emit_inference_failure_err(
                         body_id,
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 fff26547be0..7aae014af60 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1231,7 +1231,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 return;
             }
             let trait_pred = self.resolve_vars_if_possible(trait_pred);
-            if trait_pred.has_infer_types_or_consts() {
+            if trait_pred.has_non_region_infer() {
                 // Do not ICE while trying to find if a reborrow would succeed on a trait with
                 // unresolved bindings.
                 return;
@@ -1425,7 +1425,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let mut spans_and_needs_box = vec![];
 
         match liberated_sig.output().kind() {
-            ty::Dynamic(predicates, _, _) => {
+            ty::Dynamic(predicates, _, ty::Dyn) => {
                 let cause = ObligationCause::misc(ret_ty.span, fn_hir_id);
                 let param_env = ty::ParamEnv::empty();
 
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index f13736a76b2..5802f038e89 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -279,7 +279,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
 
         debug!(?obligation, "pre-resolve");
 
-        if obligation.predicate.has_infer_types_or_consts() {
+        if obligation.predicate.has_non_region_infer() {
             obligation.predicate =
                 self.selcx.infcx().resolve_vars_if_possible(obligation.predicate);
         }
@@ -569,7 +569,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                             )
                         }
                         (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
-                            if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() {
+                            if c1.has_non_region_infer() || c2.has_non_region_infer() {
                                 ProcessResult::Unchanged
                             } else {
                                 // Two different constants using generic parameters ~> error.
@@ -726,11 +726,11 @@ fn substs_infer_vars<'a, 'tcx>(
         .resolve_vars_if_possible(substs)
         .skip_binder() // ok because this check doesn't care about regions
         .iter()
-        .filter(|arg| arg.has_infer_types_or_consts())
+        .filter(|arg| arg.has_non_region_infer())
         .flat_map(|arg| {
             let mut walker = arg.walk();
             while let Some(c) = walker.next() {
-                if !c.has_infer_types_or_consts() {
+                if !c.has_non_region_infer() {
                     walker.visited.remove(&c);
                     walker.skip_current_subtree();
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index e1bd48ba8ac..41b742734cd 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -57,7 +57,7 @@ pub fn can_type_implement_copy<'tcx>(
                 // to begin with, and point to the bad field's span instead.
                 let cause = if field
                     .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did()))
-                    .has_param_types_or_consts()
+                    .has_non_region_param()
                 {
                     parent_cause.clone()
                 } else {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 8da68c225d8..659ffc178aa 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -170,7 +170,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
         result
     );
 
-    if result && ty.has_infer_types_or_consts() {
+    if result && ty.has_non_region_infer() {
         // Because of inference "guessing", selection can sometimes claim
         // to succeed while the success requires a guess. To ensure
         // this function's result remains infallible, we must confirm
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 2773b61e9ba..8f87a7fdeba 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -14,7 +14,7 @@ use crate::infer::TyCtxtInferExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{self, Obligation, ObligationCause};
 use hir::def::DefKind;
-use rustc_errors::{FatalError, MultiSpan};
+use rustc_errors::{DelayDm, FatalError, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::abstract_const::{walk_abstract_const, AbstractConst};
@@ -164,37 +164,42 @@ fn lint_object_unsafe_trait(
 ) {
     // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
     // It's also hard to get a use site span, so we use the method definition span.
-    tcx.struct_span_lint_hir(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |lint| {
-        let mut err = lint.build(&format!(
-            "the trait `{}` cannot be made into an object",
-            tcx.def_path_str(trait_def_id)
-        ));
-        let node = tcx.hir().get_if_local(trait_def_id);
-        let mut spans = MultiSpan::from_span(span);
-        if let Some(hir::Node::Item(item)) = node {
-            spans.push_span_label(item.ident.span, "this trait cannot be made into an object...");
-            spans.push_span_label(span, format!("...because {}", violation.error_msg()));
-        } else {
-            spans.push_span_label(
-                span,
-                format!(
-                    "the trait cannot be made into an object because {}",
-                    violation.error_msg()
-                ),
+    tcx.struct_span_lint_hir(
+        WHERE_CLAUSES_OBJECT_SAFETY,
+        hir::CRATE_HIR_ID,
+        span,
+        DelayDm(|| format!("the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id))),
+        |err| {
+            let node = tcx.hir().get_if_local(trait_def_id);
+            let mut spans = MultiSpan::from_span(span);
+            if let Some(hir::Node::Item(item)) = node {
+                spans.push_span_label(
+                    item.ident.span,
+                    "this trait cannot be made into an object...",
+                );
+                spans.push_span_label(span, format!("...because {}", violation.error_msg()));
+            } else {
+                spans.push_span_label(
+                    span,
+                    format!(
+                        "the trait cannot be made into an object because {}",
+                        violation.error_msg()
+                    ),
+                );
+            };
+            err.span_note(
+                spans,
+                "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \
+                call to be resolvable dynamically; for more information visit \
+                <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
             );
-        };
-        err.span_note(
-            spans,
-            "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \
-             call to be resolvable dynamically; for more information visit \
-             <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
-        );
-        if node.is_some() {
-            // Only provide the help if its a local trait, otherwise it's not
-            violation.solution(&mut err);
-        }
-        err.emit();
-    });
+            if node.is_some() {
+                // Only provide the help if its a local trait, otherwise it's not
+                violation.solution(err);
+            }
+            err
+        },
+    );
 }
 
 fn sized_trait_bound_spans<'tcx>(
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 07b65a9748d..085045bcdcb 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1488,7 +1488,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
                     candidate_set.push_candidate(ctor(data));
 
                     if potentially_unnormalized_candidates
-                        && !obligation.predicate.has_infer_types_or_consts()
+                        && !obligation.predicate.has_non_region_infer()
                     {
                         // HACK: Pick the first trait def candidate for a fully
                         // inferred predicate. This is to allow duplicates that
@@ -2146,10 +2146,10 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     } else {
         ty.map_bound(|ty| ty.into())
     };
-    if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() {
+    if !check_substs_compatible(tcx, &assoc_ty.item, substs) {
         let err = tcx.ty_error_with_message(
             obligation.cause.span,
-            "impl item and trait item have different parameter counts",
+            "impl item and trait item have different parameters",
         );
         Progress { term: err.into(), obligations: nested }
     } else {
@@ -2158,6 +2158,44 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     }
 }
 
+// Verify that the trait item and its implementation have compatible substs lists
+fn check_substs_compatible<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    assoc_ty: &ty::AssocItem,
+    substs: ty::SubstsRef<'tcx>,
+) -> bool {
+    fn check_substs_compatible_inner<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        generics: &'tcx ty::Generics,
+        args: &'tcx [ty::GenericArg<'tcx>],
+    ) -> bool {
+        if generics.count() != args.len() {
+            return false;
+        }
+
+        let (parent_args, own_args) = args.split_at(generics.parent_count);
+
+        if let Some(parent) = generics.parent
+            && let parent_generics = tcx.generics_of(parent)
+            && !check_substs_compatible_inner(tcx, parent_generics, parent_args) {
+            return false;
+        }
+
+        for (param, arg) in std::iter::zip(&generics.params, own_args) {
+            match (&param.kind, arg.unpack()) {
+                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
+                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
+                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
+                _ => return false,
+            }
+        }
+
+        true
+    }
+
+    check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice())
+}
+
 fn confirm_impl_trait_in_trait_candidate<'tcx>(
     selcx: &mut SelectionContext<'_, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 451427a6980..9a8331614b0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -6,6 +6,7 @@
 //!
 //! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
 use hir::LangItem;
+use rustc_errors::DelayDm;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::ObligationCause;
@@ -173,7 +174,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len());
 
-        let needs_infer = stack.obligation.predicate.has_infer_types_or_consts();
+        let needs_infer = stack.obligation.predicate.has_non_region_infer();
 
         // If there are STILL multiple candidates, we can further
         // reduce the list by dropping duplicates -- including
@@ -825,13 +826,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                     DEREF_INTO_DYN_SUPERTRAIT,
                                     obligation.cause.body_id,
                                     obligation.cause.span,
-                                    |lint| {
-                                        lint.build(&format!(
-                                            "`{}` implements `Deref` with supertrait `{}` as output",
-                                            source,
-                                            deref_output_ty
-                                        )).emit();
-                                    },
+                                    DelayDm(|| format!(
+                                        "`{}` implements `Deref` with supertrait `{}` as output",
+                                        source, deref_output_ty
+                                    )),
+                                    |lint| lint,
                                 );
                                 return;
                             }
@@ -890,11 +889,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &TraitObligation<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
-        if obligation.has_param_types_or_consts() {
+        if obligation.has_non_region_param() {
             return;
         }
 
-        if obligation.has_infer_types_or_consts() {
+        if obligation.has_non_region_infer() {
             candidates.ambiguous = true;
             return;
         }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index dd49dcecf77..5c8a76401d2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -11,9 +11,10 @@ use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_infer::infer::InferOk;
 use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
-use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
-use rustc_middle::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
-use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
+use rustc_middle::ty::{
+    self, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef,
+    ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
+};
 use rustc_span::def_id::DefId;
 
 use crate::traits::project::{normalize_with_depth, normalize_with_depth_to};
@@ -289,8 +290,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let scope = type_at(2).skip_binder();
 
-        let assume =
-            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3));
+        let Some(assume) =
+            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3)) else {
+                return Err(Unimplemented);
+            };
 
         let cause = obligation.cause.clone();
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5e32a27cdb1..8f2a6f337ba 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -35,7 +35,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::fold::BottomUpFolder;
-use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::SubstsRef;
 use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
@@ -729,7 +728,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             )
                         }
                         (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
-                            if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() {
+                            if c1.has_non_region_infer() || c2.has_non_region_infer() {
                                 Ok(EvaluatedToAmbig)
                             } else {
                                 // Two different constants using generic parameters ~> error.
@@ -914,38 +913,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let unbound_input_types =
             stack.fresh_trait_pred.skip_binder().trait_ref.substs.types().any(|ty| ty.is_fresh());
 
-        if stack.obligation.polarity() != ty::ImplPolarity::Negative {
-            // This check was an imperfect workaround for a bug in the old
-            // intercrate mode; it should be removed when that goes away.
-            if unbound_input_types && self.intercrate {
-                debug!("evaluate_stack --> unbound argument, intercrate -->  ambiguous",);
-                // Heuristics: show the diagnostics when there are no candidates in crate.
-                if self.intercrate_ambiguity_causes.is_some() {
-                    debug!("evaluate_stack: intercrate_ambiguity_causes is some");
-                    if let Ok(candidate_set) = self.assemble_candidates(stack) {
-                        if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
-                            let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
-                            let self_ty = trait_ref.self_ty();
-                            let cause = with_no_trimmed_paths!({
-                                IntercrateAmbiguityCause::DownstreamCrate {
-                                    trait_desc: trait_ref.print_only_trait_path().to_string(),
-                                    self_desc: if self_ty.has_concrete_skeleton() {
-                                        Some(self_ty.to_string())
-                                    } else {
-                                        None
-                                    },
-                                }
-                            });
-
-                            debug!(?cause, "evaluate_stack: pushing cause");
-                            self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
-                        }
-                    }
-                }
-                return Ok(EvaluatedToAmbig);
-            }
-        }
-
         if unbound_input_types
             && stack.iter().skip(1).any(|prev| {
                 stack.obligation.param_env == prev.obligation.param_env
@@ -1553,7 +1520,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             if !generics.params.is_empty()
                 && obligation.predicate.substs[generics.parent_count..]
                     .iter()
-                    .any(|&p| p.has_infer_types_or_consts() && self.infcx.shallow_resolve(p) != p)
+                    .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p)
             {
                 ProjectionMatchesProjection::Ambiguous
             } else {
@@ -1737,12 +1704,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             (&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
                 // See if we can toss out `victim` based on specialization.
-                // This requires us to know *for sure* that the `other` impl applies
-                // i.e., `EvaluatedToOk`.
+                // While this requires us to know *for sure* that the `other` impl applies
+                // we still use modulo regions here.
                 //
-                // FIXME(@lcnr): Using `modulo_regions` here seems kind of scary
-                // to me but is required for `std` to compile, so I didn't change it
-                // for now.
+                // This is fine as specialization currently assumes that specializing
+                // impls have to be always applicable, meaning that the only allowed
+                // region constraints may be constraints also present on the default impl.
                 let tcx = self.tcx();
                 if other.evaluation.must_apply_modulo_regions() {
                     if tcx.specializes((other_def, victim_def)) {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 56a88749c46..eac3f0f30e8 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -17,7 +17,7 @@ use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
-use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
+use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::{self, ImplSubject, TyCtxt};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
@@ -350,26 +350,12 @@ fn report_conflicting_impls(
     // Work to be done after we've built the DiagnosticBuilder. We have to define it
     // now because the struct_lint methods don't return back the DiagnosticBuilder
     // that's passed in.
-    fn decorate<G: EmissionGuarantee>(
+    fn decorate<'a, 'b, G: EmissionGuarantee>(
         tcx: TyCtxt<'_>,
         overlap: OverlapError,
-        used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
         impl_span: Span,
-        err: LintDiagnosticBuilder<'_, G>,
-    ) -> G {
-        let msg = format!(
-            "conflicting implementations of trait `{}`{}{}",
-            overlap.trait_desc,
-            overlap
-                .self_desc
-                .clone()
-                .map_or_else(String::new, |ty| { format!(" for type `{}`", ty) }),
-            match used_to_be_allowed {
-                Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
-                _ => "",
-            }
-        );
-        let mut err = err.build(&msg);
+        err: &'b mut DiagnosticBuilder<'a, G>,
+    ) -> &'b mut DiagnosticBuilder<'a, G> {
         match tcx.span_of_impl(overlap.with_impl) {
             Ok(span) => {
                 err.span_label(span, "first implementation here");
@@ -384,7 +370,9 @@ fn report_conflicting_impls(
             }
             Err(cname) => {
                 let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
-                    Some(s) => format!("conflicting implementation in crate `{}`:\n- {}", cname, s),
+                    Some(s) => {
+                        format!("conflicting implementation in crate `{}`:\n- {}", cname, s)
+                    }
                     None => format!("conflicting implementation in crate `{}`", cname),
                 };
                 err.note(&msg);
@@ -392,28 +380,33 @@ fn report_conflicting_impls(
         }
 
         for cause in &overlap.intercrate_ambiguity_causes {
-            cause.add_intercrate_ambiguity_hint(&mut err);
+            cause.add_intercrate_ambiguity_hint(err);
         }
 
         if overlap.involves_placeholder {
-            coherence::add_placeholder_note(&mut err);
+            coherence::add_placeholder_note(err);
         }
-        err.emit()
+        err
     }
 
+    let msg = format!(
+        "conflicting implementations of trait `{}`{}{}",
+        overlap.trait_desc,
+        overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")),
+        match used_to_be_allowed {
+            Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
+            _ => "",
+        }
+    );
+
     match used_to_be_allowed {
         None => {
             let reported = if overlap.with_impl.is_local()
                 || tcx.orphan_check_impl(impl_def_id).is_ok()
             {
-                let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
-                Some(decorate(
-                    tcx,
-                    overlap,
-                    used_to_be_allowed,
-                    impl_span,
-                    LintDiagnosticBuilder::new(err),
-                ))
+                let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",);
+                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"))
             };
@@ -428,9 +421,8 @@ fn report_conflicting_impls(
                 lint,
                 tcx.hir().local_def_id_to_hir_id(impl_def_id),
                 impl_span,
-                |ldb| {
-                    decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb);
-                },
+                msg,
+                |err| decorate(tcx, overlap, impl_span, err),
             );
         }
     };
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 9722b48a68a..5f901d6995e 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -308,6 +308,32 @@ impl<'tcx> WfPredicates<'tcx> {
         let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
             self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs)
         } else {
+            if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) {
+                if let Some(item) = self.item &&
+                   let hir::ItemKind::Impl(impl_) = item.kind &&
+                   let Some(trait_) = &impl_.of_trait &&
+                   let Some(def_id) = trait_.trait_def_id() &&
+                   def_id == trait_ref.def_id
+                {
+                    let trait_name = tcx.item_name(def_id);
+                    let mut err = tcx.sess.struct_span_err(
+                        self.span,
+                        &format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"),
+                    );
+                    if def_id.is_local() {
+                        let sp = tcx.def_span(def_id).shrink_to_lo();
+                        err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable);
+                    }
+                    err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`");
+                    err.note("adding a non-const method body in the future would be a breaking change");
+                    err.emit();
+                } else {
+                    tcx.sess.span_err(
+                        self.span,
+                        "~const can only be applied to `#[const_trait]` traits",
+                    );
+                }
+            }
             self.nominal_obligations(trait_ref.def_id, trait_ref.substs)
         };
 
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 32aca4a8a3f..e540ee1664d 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -79,7 +79,7 @@ fn compute_implied_outlives_bounds<'tcx>(
         // implied bounds in some cases, mostly when dealing with projections.
         fulfill_cx.register_predicate_obligations(
             infcx,
-            obligations.iter().filter(|o| o.predicate.has_infer_types_or_consts()).cloned(),
+            obligations.iter().filter(|o| o.predicate.has_non_region_infer()).cloned(),
         );
 
         // From the full set of obligations, just filter down to the
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 64cd70d3678..51f2eb8606a 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -115,7 +115,7 @@ mod rustc {
             tcx: TyCtxt<'tcx>,
             param_env: ParamEnv<'tcx>,
             c: Const<'tcx>,
-        ) -> Self {
+        ) -> Option<Self> {
             use rustc_middle::ty::ScalarInt;
             use rustc_middle::ty::TypeVisitable;
             use rustc_span::symbol::sym;
@@ -123,10 +123,15 @@ mod rustc {
             let c = c.eval(tcx, param_env);
 
             if let Some(err) = c.error_reported() {
-                return Self { alignment: true, lifetimes: true, safety: true, validity: true };
+                return Some(Self {
+                    alignment: true,
+                    lifetimes: true,
+                    safety: true,
+                    validity: true,
+                });
             }
 
-            let adt_def = c.ty().ty_adt_def().expect("The given `Const` must be an ADT.");
+            let adt_def = c.ty().ty_adt_def()?;
 
             assert_eq!(
                 tcx.require_lang_item(LangItem::TransmuteOpts, None),
@@ -148,12 +153,12 @@ mod rustc {
                 fields[field_idx].unwrap_leaf() == ScalarInt::TRUE
             };
 
-            Self {
+            Some(Self {
                 alignment: get_field(sym::alignment),
                 lifetimes: get_field(sym::lifetimes),
                 safety: get_field(sym::safety),
                 validity: get_field(sym::validity),
-            }
+            })
         }
     }
 }
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml
index 52fbd3ae047..5e4ba473061 100644
--- a/compiler/rustc_ty_utils/Cargo.toml
+++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -4,6 +4,8 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
+rand = "0.8.4"
+rand_xoshiro = "0.6.0"
 tracing = "0.1"
 rustc_middle = { path = "../rustc_middle" }
 rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
new file mode 100644
index 00000000000..6e34ee21082
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -0,0 +1,518 @@
+use rustc_hir as hir;
+use rustc_hir::lang_items::LangItem;
+use rustc_middle::ty::layout::{
+    fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout,
+};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::def_id::DefId;
+use rustc_target::abi::call::{
+    ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind,
+};
+use rustc_target::abi::*;
+use rustc_target::spec::abi::Abi as SpecAbi;
+
+use std::iter;
+
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers };
+}
+
+// NOTE(eddyb) this is private to avoid using it from outside of
+// `fn_abi_of_instance` - any other uses are either too high-level
+// for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
+// or should go through `FnAbi` instead, to avoid losing any
+// adjustments `fn_abi_of_instance` might be performing.
+#[tracing::instrument(level = "debug", skip(tcx, param_env))]
+fn fn_sig_for_fn_abi<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: ty::Instance<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+) -> ty::PolyFnSig<'tcx> {
+    let ty = instance.ty(tcx, param_env);
+    match *ty.kind() {
+        ty::FnDef(..) => {
+            // HACK(davidtwco,eddyb): This is a workaround for polymorphization considering
+            // parameters unused if they show up in the signature, but not in the `mir::Body`
+            // (i.e. due to being inside a projection that got normalized, see
+            // `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping
+            // track of a polymorphization `ParamEnv` to allow normalizing later.
+            //
+            // We normalize the `fn_sig` again after substituting at a later point.
+            let mut sig = match *ty.kind() {
+                ty::FnDef(def_id, substs) => tcx
+                    .bound_fn_sig(def_id)
+                    .map_bound(|fn_sig| {
+                        tcx.normalize_erasing_regions(tcx.param_env(def_id), fn_sig)
+                    })
+                    .subst(tcx, substs),
+                _ => unreachable!(),
+            };
+
+            if let ty::InstanceDef::VTableShim(..) = instance.def {
+                // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
+                sig = sig.map_bound(|mut sig| {
+                    let mut inputs_and_output = sig.inputs_and_output.to_vec();
+                    inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]);
+                    sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+                    sig
+                });
+            }
+            sig
+        }
+        ty::Closure(def_id, substs) => {
+            let sig = substs.as_closure().sig();
+
+            let bound_vars = tcx.mk_bound_variable_kinds(
+                sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
+            );
+            let br = ty::BoundRegion {
+                var: ty::BoundVar::from_usize(bound_vars.len() - 1),
+                kind: ty::BoundRegionKind::BrEnv,
+            };
+            let env_region = ty::ReLateBound(ty::INNERMOST, br);
+            let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
+
+            let sig = sig.skip_binder();
+            ty::Binder::bind_with_vars(
+                tcx.mk_fn_sig(
+                    iter::once(env_ty).chain(sig.inputs().iter().cloned()),
+                    sig.output(),
+                    sig.c_variadic,
+                    sig.unsafety,
+                    sig.abi,
+                ),
+                bound_vars,
+            )
+        }
+        ty::Generator(_, substs, _) => {
+            let sig = substs.as_generator().poly_sig();
+
+            let bound_vars = tcx.mk_bound_variable_kinds(
+                sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
+            );
+            let br = ty::BoundRegion {
+                var: ty::BoundVar::from_usize(bound_vars.len() - 1),
+                kind: ty::BoundRegionKind::BrEnv,
+            };
+            let env_region = ty::ReLateBound(ty::INNERMOST, br);
+            let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
+
+            let pin_did = tcx.require_lang_item(LangItem::Pin, None);
+            let pin_adt_ref = tcx.adt_def(pin_did);
+            let pin_substs = tcx.intern_substs(&[env_ty.into()]);
+            let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
+
+            let sig = sig.skip_binder();
+            let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
+            let state_adt_ref = tcx.adt_def(state_did);
+            let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
+            let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
+            ty::Binder::bind_with_vars(
+                tcx.mk_fn_sig(
+                    [env_ty, sig.resume_ty].iter(),
+                    &ret_ty,
+                    false,
+                    hir::Unsafety::Normal,
+                    rustc_target::spec::abi::Abi::Rust,
+                ),
+                bound_vars,
+            )
+        }
+        _ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
+    }
+}
+
+#[inline]
+fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
+    use rustc_target::spec::abi::Abi::*;
+    match tcx.sess.target.adjust_abi(abi) {
+        RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
+        RustCold => Conv::RustCold,
+
+        // It's the ABI's job to select this, not ours.
+        System { .. } => bug!("system abi should be selected elsewhere"),
+        EfiApi => bug!("eficall abi should be selected elsewhere"),
+
+        Stdcall { .. } => Conv::X86Stdcall,
+        Fastcall { .. } => Conv::X86Fastcall,
+        Vectorcall { .. } => Conv::X86VectorCall,
+        Thiscall { .. } => Conv::X86ThisCall,
+        C { .. } => Conv::C,
+        Unadjusted => Conv::C,
+        Win64 { .. } => Conv::X86_64Win64,
+        SysV64 { .. } => Conv::X86_64SysV,
+        Aapcs { .. } => Conv::ArmAapcs,
+        CCmseNonSecureCall => Conv::CCmseNonSecureCall,
+        PtxKernel => Conv::PtxKernel,
+        Msp430Interrupt => Conv::Msp430Intr,
+        X86Interrupt => Conv::X86Intr,
+        AmdGpuKernel => Conv::AmdGpuKernel,
+        AvrInterrupt => Conv::AvrInterrupt,
+        AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
+        Wasm => Conv::C,
+
+        // These API constants ought to be more specific...
+        Cdecl { .. } => Conv::C,
+    }
+}
+
+fn fn_abi_of_fn_ptr<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
+) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
+    let (param_env, (sig, extra_args)) = query.into_parts();
+
+    let cx = LayoutCx { tcx, param_env };
+    fn_abi_new_uncached(&cx, sig, extra_args, None, None, false)
+}
+
+fn fn_abi_of_instance<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
+) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
+    let (param_env, (instance, extra_args)) = query.into_parts();
+
+    let sig = fn_sig_for_fn_abi(tcx, instance, param_env);
+
+    let caller_location = if instance.def.requires_caller_location(tcx) {
+        Some(tcx.caller_location_ty())
+    } else {
+        None
+    };
+
+    fn_abi_new_uncached(
+        &LayoutCx { tcx, param_env },
+        sig,
+        extra_args,
+        caller_location,
+        Some(instance.def_id()),
+        matches!(instance.def, ty::InstanceDef::Virtual(..)),
+    )
+}
+
+// Handle safe Rust thin and fat pointers.
+fn adjust_for_rust_scalar<'tcx>(
+    cx: LayoutCx<'tcx, TyCtxt<'tcx>>,
+    attrs: &mut ArgAttributes,
+    scalar: Scalar,
+    layout: TyAndLayout<'tcx>,
+    offset: Size,
+    is_return: bool,
+) {
+    // Booleans are always a noundef i1 that needs to be zero-extended.
+    if scalar.is_bool() {
+        attrs.ext(ArgExtension::Zext);
+        attrs.set(ArgAttribute::NoUndef);
+        return;
+    }
+
+    // Scalars which have invalid values cannot be undef.
+    if !scalar.is_always_valid(&cx) {
+        attrs.set(ArgAttribute::NoUndef);
+    }
+
+    // Only pointer types handled below.
+    let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return };
+
+    if !valid_range.contains(0) {
+        attrs.set(ArgAttribute::NonNull);
+    }
+
+    if let Some(pointee) = layout.pointee_info_at(&cx, offset) {
+        if let Some(kind) = pointee.safe {
+            attrs.pointee_align = Some(pointee.align);
+
+            // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable
+            // for the entire duration of the function as they can be deallocated
+            // at any time. Same for shared mutable references. If LLVM had a
+            // way to say "dereferenceable on entry" we could use it here.
+            attrs.pointee_size = match kind {
+                PointerKind::UniqueBorrowed
+                | PointerKind::UniqueBorrowedPinned
+                | PointerKind::Frozen => pointee.size,
+                PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO,
+            };
+
+            // `Box`, `&T`, and `&mut T` cannot be undef.
+            // Note that this only applies to the value of the pointer itself;
+            // this attribute doesn't make it UB for the pointed-to data to be undef.
+            attrs.set(ArgAttribute::NoUndef);
+
+            // The aliasing rules for `Box<T>` are still not decided, but currently we emit
+            // `noalias` for it. This can be turned off using an unstable flag.
+            // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
+            let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true);
+
+            // `&mut` pointer parameters never alias other parameters,
+            // or mutable global data
+            //
+            // `&T` where `T` contains no `UnsafeCell<U>` is immutable,
+            // and can be marked as both `readonly` and `noalias`, as
+            // LLVM's definition of `noalias` is based solely on memory
+            // dependencies rather than pointer equality
+            //
+            // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute
+            // for UniqueBorrowed arguments, so that the codegen backend can decide whether
+            // or not to actually emit the attribute. It can also be controlled with the
+            // `-Zmutable-noalias` debugging option.
+            let no_alias = match kind {
+                PointerKind::SharedMutable
+                | PointerKind::UniqueBorrowed
+                | PointerKind::UniqueBorrowedPinned => false,
+                PointerKind::UniqueOwned => noalias_for_box,
+                PointerKind::Frozen => !is_return,
+            };
+            if no_alias {
+                attrs.set(ArgAttribute::NoAlias);
+            }
+
+            if kind == PointerKind::Frozen && !is_return {
+                attrs.set(ArgAttribute::ReadOnly);
+            }
+
+            if kind == PointerKind::UniqueBorrowed && !is_return {
+                attrs.set(ArgAttribute::NoAliasMutRef);
+            }
+        }
+    }
+}
+
+// FIXME(eddyb) perhaps group the signature/type-containing (or all of them?)
+// arguments of this method, into a separate `struct`.
+#[tracing::instrument(level = "debug", skip(cx, caller_location, fn_def_id, force_thin_self_ptr))]
+fn fn_abi_new_uncached<'tcx>(
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    sig: ty::PolyFnSig<'tcx>,
+    extra_args: &[Ty<'tcx>],
+    caller_location: Option<Ty<'tcx>>,
+    fn_def_id: Option<DefId>,
+    // FIXME(eddyb) replace this with something typed, like an `enum`.
+    force_thin_self_ptr: bool,
+) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
+    let sig = cx.tcx.normalize_erasing_late_bound_regions(cx.param_env, sig);
+
+    let conv = conv_from_spec_abi(cx.tcx(), sig.abi);
+
+    let mut inputs = sig.inputs();
+    let extra_args = if sig.abi == RustCall {
+        assert!(!sig.c_variadic && extra_args.is_empty());
+
+        if let Some(input) = sig.inputs().last() {
+            if let ty::Tuple(tupled_arguments) = input.kind() {
+                inputs = &sig.inputs()[0..sig.inputs().len() - 1];
+                tupled_arguments
+            } else {
+                bug!(
+                    "argument to function with \"rust-call\" ABI \
+                        is not a tuple"
+                );
+            }
+        } else {
+            bug!(
+                "argument to function with \"rust-call\" ABI \
+                    is not a tuple"
+            );
+        }
+    } else {
+        assert!(sig.c_variadic || extra_args.is_empty());
+        extra_args
+    };
+
+    let target = &cx.tcx.sess.target;
+    let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
+    let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
+    let linux_s390x_gnu_like =
+        target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
+    let linux_sparc64_gnu_like =
+        target.os == "linux" && target.arch == "sparc64" && target_env_gnu_like;
+    let linux_powerpc_gnu_like =
+        target.os == "linux" && target.arch == "powerpc" && target_env_gnu_like;
+    use SpecAbi::*;
+    let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall);
+
+    let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> {
+        let span = tracing::debug_span!("arg_of");
+        let _entered = span.enter();
+        let is_return = arg_idx.is_none();
+
+        let layout = cx.layout_of(ty)?;
+        let layout = if force_thin_self_ptr && arg_idx == Some(0) {
+            // Don't pass the vtable, it's not an argument of the virtual fn.
+            // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
+            // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
+            make_thin_self_ptr(cx, layout)
+        } else {
+            layout
+        };
+
+        let mut arg = ArgAbi::new(cx, layout, |layout, scalar, offset| {
+            let mut attrs = ArgAttributes::new();
+            adjust_for_rust_scalar(*cx, &mut attrs, scalar, *layout, offset, is_return);
+            attrs
+        });
+
+        if arg.layout.is_zst() {
+            // For some forsaken reason, x86_64-pc-windows-gnu
+            // doesn't ignore zero-sized struct arguments.
+            // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}.
+            if is_return
+                || rust_abi
+                || (!win_x64_gnu
+                    && !linux_s390x_gnu_like
+                    && !linux_sparc64_gnu_like
+                    && !linux_powerpc_gnu_like)
+            {
+                arg.mode = PassMode::Ignore;
+            }
+        }
+
+        Ok(arg)
+    };
+
+    let mut fn_abi = FnAbi {
+        ret: arg_of(sig.output(), None)?,
+        args: inputs
+            .iter()
+            .copied()
+            .chain(extra_args.iter().copied())
+            .chain(caller_location)
+            .enumerate()
+            .map(|(i, ty)| arg_of(ty, Some(i)))
+            .collect::<Result<_, _>>()?,
+        c_variadic: sig.c_variadic,
+        fixed_count: inputs.len() as u32,
+        conv,
+        can_unwind: fn_can_unwind(cx.tcx(), fn_def_id, sig.abi),
+    };
+    fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi)?;
+    debug!("fn_abi_new_uncached = {:?}", fn_abi);
+    Ok(cx.tcx.arena.alloc(fn_abi))
+}
+
+#[tracing::instrument(level = "trace", skip(cx))]
+fn fn_abi_adjust_for_abi<'tcx>(
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>,
+    abi: SpecAbi,
+) -> Result<(), FnAbiError<'tcx>> {
+    if abi == SpecAbi::Unadjusted {
+        return Ok(());
+    }
+
+    if abi == SpecAbi::Rust
+        || abi == SpecAbi::RustCall
+        || abi == SpecAbi::RustIntrinsic
+        || abi == SpecAbi::PlatformIntrinsic
+    {
+        let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| {
+            if arg.is_ignore() {
+                return;
+            }
+
+            match arg.layout.abi {
+                Abi::Aggregate { .. } => {}
+
+                // This is a fun case! The gist of what this is doing is
+                // that we want callers and callees to always agree on the
+                // ABI of how they pass SIMD arguments. If we were to *not*
+                // make these arguments indirect then they'd be immediates
+                // in LLVM, which means that they'd used whatever the
+                // appropriate ABI is for the callee and the caller. That
+                // means, for example, if the caller doesn't have AVX
+                // enabled but the callee does, then passing an AVX argument
+                // across this boundary would cause corrupt data to show up.
+                //
+                // This problem is fixed by unconditionally passing SIMD
+                // arguments through memory between callers and callees
+                // which should get them all to agree on ABI regardless of
+                // target feature sets. Some more information about this
+                // issue can be found in #44367.
+                //
+                // Note that the platform intrinsic ABI is exempt here as
+                // that's how we connect up to LLVM and it's unstable
+                // anyway, we control all calls to it in libstd.
+                Abi::Vector { .. }
+                    if abi != SpecAbi::PlatformIntrinsic
+                        && cx.tcx.sess.target.simd_types_indirect =>
+                {
+                    arg.make_indirect();
+                    return;
+                }
+
+                _ => return,
+            }
+
+            let size = arg.layout.size;
+            if arg.layout.is_unsized() || size > Pointer.size(cx) {
+                arg.make_indirect();
+            } else {
+                // We want to pass small aggregates as immediates, but using
+                // a LLVM aggregate type for this leads to bad optimizations,
+                // so we pick an appropriately sized integer type instead.
+                arg.cast_to(Reg { kind: RegKind::Integer, size });
+            }
+        };
+        fixup(&mut fn_abi.ret);
+        for arg in fn_abi.args.iter_mut() {
+            fixup(arg);
+        }
+    } else {
+        fn_abi.adjust_for_foreign_abi(cx, abi)?;
+    }
+
+    Ok(())
+}
+
+#[tracing::instrument(level = "debug", skip(cx))]
+fn make_thin_self_ptr<'tcx>(
+    cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
+    layout: TyAndLayout<'tcx>,
+) -> TyAndLayout<'tcx> {
+    let tcx = cx.tcx();
+    let fat_pointer_ty = if layout.is_unsized() {
+        // unsized `self` is passed as a pointer to `self`
+        // FIXME (mikeyhew) change this to use &own if it is ever added to the language
+        tcx.mk_mut_ptr(layout.ty)
+    } else {
+        match layout.abi {
+            Abi::ScalarPair(..) | Abi::Scalar(..) => (),
+            _ => bug!("receiver type has unsupported layout: {:?}", layout),
+        }
+
+        // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self>
+        // with a Scalar (not ScalarPair) ABI. This is a hack that is understood
+        // elsewhere in the compiler as a method on a `dyn Trait`.
+        // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we
+        // get a built-in pointer type
+        let mut fat_pointer_layout = layout;
+        'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr()
+            && !fat_pointer_layout.ty.is_region_ptr()
+        {
+            for i in 0..fat_pointer_layout.fields.count() {
+                let field_layout = fat_pointer_layout.field(cx, i);
+
+                if !field_layout.is_zst() {
+                    fat_pointer_layout = field_layout;
+                    continue 'descend_newtypes;
+                }
+            }
+
+            bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout);
+        }
+
+        fat_pointer_layout.ty
+    };
+
+    // we now have a type like `*mut RcBox<dyn Trait>`
+    // change its layout to that of `*mut ()`, a thin pointer, but keep the same type
+    // this is understood as a special case elsewhere in the compiler
+    let unit_ptr_ty = tcx.mk_mut_ptr(tcx.mk_unit());
+
+    TyAndLayout {
+        ty: fat_pointer_ty,
+
+        // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result`
+        // should always work because the type is always `*mut ()`.
+        ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap()
+    }
+}
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 493ef335113..e057bb66825 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -135,30 +135,30 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
 
         impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
             fn expr_is_poly(&mut self, expr: &thir::Expr<'tcx>) -> bool {
-                if expr.ty.has_param_types_or_consts() {
+                if expr.ty.has_non_region_param() {
                     return true;
                 }
 
                 match expr.kind {
-                    thir::ExprKind::NamedConst { substs, .. } => substs.has_param_types_or_consts(),
+                    thir::ExprKind::NamedConst { substs, .. } => substs.has_non_region_param(),
                     thir::ExprKind::ConstParam { .. } => true,
                     thir::ExprKind::Repeat { value, count } => {
                         self.visit_expr(&self.thir()[value]);
-                        count.has_param_types_or_consts()
+                        count.has_non_region_param()
                     }
                     _ => false,
                 }
             }
 
             fn pat_is_poly(&mut self, pat: &thir::Pat<'tcx>) -> bool {
-                if pat.ty.has_param_types_or_consts() {
+                if pat.ty.has_non_region_param() {
                     return true;
                 }
 
                 match pat.kind {
-                    thir::PatKind::Constant { value } => value.has_param_types_or_consts(),
+                    thir::PatKind::Constant { value } => value.has_non_region_param(),
                     thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => {
-                        lo.has_param_types_or_consts() || hi.has_param_types_or_consts()
+                        lo.has_non_region_param() || hi.has_non_region_param()
                     }
                     _ => false,
                 }
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index fa1dc90e4a2..81ca8b646ff 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -171,9 +171,13 @@ fn resolve_associated_item<'tcx>(
                 return Ok(None);
             }
 
-            // If the item does not have a value, then we cannot return an instance.
+            // Any final impl is required to define all associated items.
             if !leaf_def.item.defaultness(tcx).has_value() {
-                return Ok(None);
+                let guard = tcx.sess.delay_span_bug(
+                    tcx.def_span(leaf_def.item.def_id),
+                    "missing value for assoc item in impl",
+                );
+                return Err(guard);
             }
 
             let substs = tcx.erase_regions(substs);
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
new file mode 100644
index 00000000000..345911f4309
--- /dev/null
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -0,0 +1,1804 @@
+use rustc_hir as hir;
+use rustc_index::bit_set::BitSet;
+use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal};
+use rustc_middle::ty::layout::{
+    IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES,
+};
+use rustc_middle::ty::{
+    self, subst::SubstsRef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable,
+};
+use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
+use rustc_span::symbol::Symbol;
+use rustc_span::DUMMY_SP;
+use rustc_target::abi::*;
+
+use std::cmp::{self, Ordering};
+use std::iter;
+use std::num::NonZeroUsize;
+use std::ops::Bound;
+
+use rand::{seq::SliceRandom, SeedableRng};
+use rand_xoshiro::Xoshiro128StarStar;
+
+use crate::layout_sanity_check::sanity_check_layout;
+
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers { layout_of, ..*providers };
+}
+
+#[instrument(skip(tcx, query), level = "debug")]
+fn layout_of<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
+) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> {
+    let (param_env, ty) = query.into_parts();
+    debug!(?ty);
+
+    let param_env = param_env.with_reveal_all_normalized(tcx);
+    let unnormalized_ty = ty;
+
+    // FIXME: We might want to have two different versions of `layout_of`:
+    // One that can be called after typecheck has completed and can use
+    // `normalize_erasing_regions` here and another one that can be called
+    // before typecheck has completed and uses `try_normalize_erasing_regions`.
+    let ty = match tcx.try_normalize_erasing_regions(param_env, ty) {
+        Ok(t) => t,
+        Err(normalization_error) => {
+            return Err(LayoutError::NormalizationFailure(ty, normalization_error));
+        }
+    };
+
+    if ty != unnormalized_ty {
+        // Ensure this layout is also cached for the normalized type.
+        return tcx.layout_of(param_env.and(ty));
+    }
+
+    let cx = LayoutCx { tcx, param_env };
+
+    let layout = layout_of_uncached(&cx, ty)?;
+    let layout = TyAndLayout { ty, layout };
+
+    record_layout_for_printing(&cx, layout);
+
+    sanity_check_layout(&cx, &layout);
+
+    Ok(layout)
+}
+
+#[derive(Copy, Clone, Debug)]
+enum StructKind {
+    /// A tuple, closure, or univariant which cannot be coerced to unsized.
+    AlwaysSized,
+    /// A univariant, the last field of which may be coerced to unsized.
+    MaybeUnsized,
+    /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
+    Prefixed(Size, Align),
+}
+
+// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`.
+// This is used to go between `memory_index` (source field order to memory order)
+// and `inverse_memory_index` (memory order to source field order).
+// See also `FieldsShape::Arbitrary::memory_index` for more details.
+// FIXME(eddyb) build a better abstraction for permutations, if possible.
+fn invert_mapping(map: &[u32]) -> Vec<u32> {
+    let mut inverse = vec![0; map.len()];
+    for i in 0..map.len() {
+        inverse[map[i] as usize] = i as u32;
+    }
+    inverse
+}
+
+fn scalar_pair<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, a: Scalar, b: Scalar) -> LayoutS<'tcx> {
+    let dl = cx.data_layout();
+    let b_align = b.align(dl);
+    let align = a.align(dl).max(b_align).max(dl.aggregate_align);
+    let b_offset = a.size(dl).align_to(b_align.abi);
+    let size = (b_offset + b.size(dl)).align_to(align.abi);
+
+    // HACK(nox): We iter on `b` and then `a` because `max_by_key`
+    // returns the last maximum.
+    let largest_niche = Niche::from_scalar(dl, b_offset, b)
+        .into_iter()
+        .chain(Niche::from_scalar(dl, Size::ZERO, a))
+        .max_by_key(|niche| niche.available(dl));
+
+    LayoutS {
+        variants: Variants::Single { index: VariantIdx::new(0) },
+        fields: FieldsShape::Arbitrary {
+            offsets: vec![Size::ZERO, b_offset],
+            memory_index: vec![0, 1],
+        },
+        abi: Abi::ScalarPair(a, b),
+        largest_niche,
+        align,
+        size,
+    }
+}
+
+fn univariant_uninterned<'tcx>(
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    ty: Ty<'tcx>,
+    fields: &[TyAndLayout<'_>],
+    repr: &ReprOptions,
+    kind: StructKind,
+) -> Result<LayoutS<'tcx>, LayoutError<'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");
+        return Err(LayoutError::Unknown(ty));
+    }
+
+    let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
+
+    let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
+
+    let optimize = !repr.inhibit_struct_field_reordering_opt();
+    if optimize {
+        let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
+        let optimizing = &mut inverse_memory_index[..end];
+        let field_align = |f: &TyAndLayout<'_>| {
+            if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi }
+        };
+
+        // If `-Z randomize-layout` was enabled for the type definition we can shuffle
+        // the field ordering to try and catch some code making assumptions about layouts
+        // we don't guarantee
+        if repr.can_randomize_type_layout() {
+            // `ReprOptions.layout_seed` is a deterministic seed that we can use to
+            // randomize field ordering with
+            let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
+
+            // Shuffle the ordering of the fields
+            optimizing.shuffle(&mut rng);
+
+            // Otherwise we just leave things alone and actually optimize the type's fields
+        } else {
+            match kind {
+                StructKind::AlwaysSized | StructKind::MaybeUnsized => {
+                    optimizing.sort_by_key(|&x| {
+                        // Place ZSTs first to avoid "interesting offsets",
+                        // especially with only one or two non-ZST fields.
+                        let f = &fields[x as usize];
+                        (!f.is_zst(), cmp::Reverse(field_align(f)))
+                    });
+                }
+
+                StructKind::Prefixed(..) => {
+                    // Sort in ascending alignment so that the layout stays optimal
+                    // regardless of the prefix
+                    optimizing.sort_by_key(|&x| field_align(&fields[x as usize]));
+                }
+            }
+
+            // FIXME(Kixiron): We can always shuffle fields within a given alignment class
+            //                 regardless of the status of `-Z randomize-layout`
+        }
+    }
+
+    // inverse_memory_index holds field indices by increasing memory offset.
+    // That is, if field 5 has offset 0, the first element of inverse_memory_index is 5.
+    // We now write field offsets to the corresponding offset slot;
+    // field 5 with offset 0 puts 0 in offsets[5].
+    // At the bottom of this function, we invert `inverse_memory_index` to
+    // produce `memory_index` (see `invert_mapping`).
+
+    let mut sized = true;
+    let mut offsets = vec![Size::ZERO; fields.len()];
+    let mut offset = Size::ZERO;
+    let mut largest_niche = None;
+    let mut largest_niche_available = 0;
+
+    if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
+        let prefix_align =
+            if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
+        align = align.max(AbiAndPrefAlign::new(prefix_align));
+        offset = prefix_size.align_to(prefix_align);
+    }
+
+    for &i in &inverse_memory_index {
+        let field = fields[i as usize];
+        if !sized {
+            cx.tcx.sess.delay_span_bug(
+                DUMMY_SP,
+                &format!(
+                    "univariant: field #{} of `{}` comes after unsized field",
+                    offsets.len(),
+                    ty
+                ),
+            );
+        }
+
+        if field.is_unsized() {
+            sized = false;
+        }
+
+        // Invariant: offset < dl.obj_size_bound() <= 1<<61
+        let field_align = if let Some(pack) = pack {
+            field.align.min(AbiAndPrefAlign::new(pack))
+        } else {
+            field.align
+        };
+        offset = offset.align_to(field_align.abi);
+        align = align.max(field_align);
+
+        debug!("univariant offset: {:?} field: {:#?}", offset, field);
+        offsets[i as usize] = offset;
+
+        if let Some(mut niche) = field.largest_niche {
+            let available = niche.available(dl);
+            if available > largest_niche_available {
+                largest_niche_available = available;
+                niche.offset += offset;
+                largest_niche = Some(niche);
+            }
+        }
+
+        offset = offset.checked_add(field.size, dl).ok_or(LayoutError::SizeOverflow(ty))?;
+    }
+
+    if let Some(repr_align) = repr.align {
+        align = align.max(AbiAndPrefAlign::new(repr_align));
+    }
+
+    debug!("univariant min_size: {:?}", offset);
+    let min_size = offset;
+
+    // As stated above, inverse_memory_index holds field indices by increasing offset.
+    // This makes it an already-sorted view of the offsets vec.
+    // To invert it, consider:
+    // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
+    // Field 5 would be the first element, so memory_index is i:
+    // Note: if we didn't optimize, it's already right.
+
+    let memory_index =
+        if optimize { invert_mapping(&inverse_memory_index) } else { inverse_memory_index };
+
+    let size = min_size.align_to(align.abi);
+    let mut abi = Abi::Aggregate { sized };
+
+    // Unpack newtype ABIs and find scalar pairs.
+    if sized && size.bytes() > 0 {
+        // All other fields must be ZSTs.
+        let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst());
+
+        match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) {
+            // We have exactly one non-ZST field.
+            (Some((i, field)), None, None) => {
+                // Field fills the struct and it has a scalar or scalar pair ABI.
+                if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size {
+                    match field.abi {
+                        // For plain scalars, or vectors of them, we can't unpack
+                        // newtypes for `#[repr(C)]`, as that affects C ABIs.
+                        Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
+                            abi = field.abi;
+                        }
+                        // But scalar pairs are Rust-specific and get
+                        // treated as aggregates by C ABIs anyway.
+                        Abi::ScalarPair(..) => {
+                            abi = field.abi;
+                        }
+                        _ => {}
+                    }
+                }
+            }
+
+            // Two non-ZST fields, and they're both scalars.
+            (Some((i, a)), Some((j, b)), None) => {
+                match (a.abi, b.abi) {
+                    (Abi::Scalar(a), Abi::Scalar(b)) => {
+                        // Order by the memory placement, not source order.
+                        let ((i, a), (j, b)) = if offsets[i] < offsets[j] {
+                            ((i, a), (j, b))
+                        } else {
+                            ((j, b), (i, a))
+                        };
+                        let pair = scalar_pair(cx, a, b);
+                        let pair_offsets = match pair.fields {
+                            FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
+                                assert_eq!(memory_index, &[0, 1]);
+                                offsets
+                            }
+                            _ => bug!(),
+                        };
+                        if offsets[i] == pair_offsets[0]
+                            && offsets[j] == pair_offsets[1]
+                            && align == pair.align
+                            && size == pair.size
+                        {
+                            // We can use `ScalarPair` only when it matches our
+                            // already computed layout (including `#[repr(C)]`).
+                            abi = pair.abi;
+                        }
+                    }
+                    _ => {}
+                }
+            }
+
+            _ => {}
+        }
+    }
+
+    if fields.iter().any(|f| f.abi.is_uninhabited()) {
+        abi = Abi::Uninhabited;
+    }
+
+    Ok(LayoutS {
+        variants: Variants::Single { index: VariantIdx::new(0) },
+        fields: FieldsShape::Arbitrary { offsets, memory_index },
+        abi,
+        largest_niche,
+        align,
+        size,
+    })
+}
+
+fn layout_of_uncached<'tcx>(
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    ty: Ty<'tcx>,
+) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
+    let tcx = cx.tcx;
+    let param_env = cx.param_env;
+    let dl = cx.data_layout();
+    let scalar_unit = |value: Primitive| {
+        let size = value.size(dl);
+        assert!(size.bits() <= 128);
+        Scalar::Initialized { value, valid_range: WrappingRange::full(size) }
+    };
+    let scalar = |value: Primitive| tcx.intern_layout(LayoutS::scalar(cx, scalar_unit(value)));
+
+    let univariant = |fields: &[TyAndLayout<'_>], repr: &ReprOptions, kind| {
+        Ok(tcx.intern_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
+    };
+    debug_assert!(!ty.has_non_region_infer());
+
+    Ok(match *ty.kind() {
+        // Basic scalars.
+        ty::Bool => tcx.intern_layout(LayoutS::scalar(
+            cx,
+            Scalar::Initialized {
+                value: Int(I8, false),
+                valid_range: WrappingRange { start: 0, end: 1 },
+            },
+        )),
+        ty::Char => tcx.intern_layout(LayoutS::scalar(
+            cx,
+            Scalar::Initialized {
+                value: Int(I32, false),
+                valid_range: WrappingRange { start: 0, end: 0x10FFFF },
+            },
+        )),
+        ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
+        ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
+        ty::Float(fty) => scalar(match fty {
+            ty::FloatTy::F32 => F32,
+            ty::FloatTy::F64 => F64,
+        }),
+        ty::FnPtr(_) => {
+            let mut ptr = scalar_unit(Pointer);
+            ptr.valid_range_mut().start = 1;
+            tcx.intern_layout(LayoutS::scalar(cx, ptr))
+        }
+
+        // The never type.
+        ty::Never => tcx.intern_layout(LayoutS {
+            variants: Variants::Single { index: VariantIdx::new(0) },
+            fields: FieldsShape::Primitive,
+            abi: Abi::Uninhabited,
+            largest_niche: None,
+            align: dl.i8_align,
+            size: Size::ZERO,
+        }),
+
+        // Potentially-wide pointers.
+        ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
+            let mut data_ptr = scalar_unit(Pointer);
+            if !ty.is_unsafe_ptr() {
+                data_ptr.valid_range_mut().start = 1;
+            }
+
+            let pointee = tcx.normalize_erasing_regions(param_env, pointee);
+            if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
+                return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+            }
+
+            let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
+            let metadata = match unsized_part.kind() {
+                ty::Foreign(..) => {
+                    return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                }
+                ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
+                ty::Dynamic(..) => {
+                    let mut vtable = scalar_unit(Pointer);
+                    vtable.valid_range_mut().start = 1;
+                    vtable
+                }
+                _ => return Err(LayoutError::Unknown(unsized_part)),
+            };
+
+            // Effectively a (ptr, meta) tuple.
+            tcx.intern_layout(scalar_pair(cx, data_ptr, metadata))
+        }
+
+        ty::Dynamic(_, _, ty::DynStar) => {
+            let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false));
+            data.valid_range_mut().start = 0;
+            let mut vtable = scalar_unit(Pointer);
+            vtable.valid_range_mut().start = 1;
+            tcx.intern_layout(scalar_pair(cx, data, vtable))
+        }
+
+        // Arrays and slices.
+        ty::Array(element, mut count) => {
+            if count.has_projections() {
+                count = tcx.normalize_erasing_regions(param_env, count);
+                if count.has_projections() {
+                    return Err(LayoutError::Unknown(ty));
+                }
+            }
+
+            let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?;
+            let element = cx.layout_of(element)?;
+            let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?;
+
+            let abi = if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty))
+            {
+                Abi::Uninhabited
+            } else {
+                Abi::Aggregate { sized: true }
+            };
+
+            let largest_niche = if count != 0 { element.largest_niche } else { None };
+
+            tcx.intern_layout(LayoutS {
+                variants: Variants::Single { index: VariantIdx::new(0) },
+                fields: FieldsShape::Array { stride: element.size, count },
+                abi,
+                largest_niche,
+                align: element.align,
+                size,
+            })
+        }
+        ty::Slice(element) => {
+            let element = cx.layout_of(element)?;
+            tcx.intern_layout(LayoutS {
+                variants: Variants::Single { index: VariantIdx::new(0) },
+                fields: FieldsShape::Array { stride: element.size, count: 0 },
+                abi: Abi::Aggregate { sized: false },
+                largest_niche: None,
+                align: element.align,
+                size: Size::ZERO,
+            })
+        }
+        ty::Str => tcx.intern_layout(LayoutS {
+            variants: Variants::Single { index: VariantIdx::new(0) },
+            fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
+            abi: Abi::Aggregate { sized: false },
+            largest_niche: None,
+            align: dl.i8_align,
+            size: Size::ZERO,
+        }),
+
+        // Odd unit types.
+        ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?,
+        ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => {
+            let mut unit = univariant_uninterned(
+                cx,
+                ty,
+                &[],
+                &ReprOptions::default(),
+                StructKind::AlwaysSized,
+            )?;
+            match unit.abi {
+                Abi::Aggregate { ref mut sized } => *sized = false,
+                _ => bug!(),
+            }
+            tcx.intern_layout(unit)
+        }
+
+        ty::Generator(def_id, substs, _) => generator_layout(cx, ty, def_id, substs)?,
+
+        ty::Closure(_, ref substs) => {
+            let tys = substs.as_closure().upvar_tys();
+            univariant(
+                &tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
+                &ReprOptions::default(),
+                StructKind::AlwaysSized,
+            )?
+        }
+
+        ty::Tuple(tys) => {
+            let kind =
+                if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
+
+            univariant(
+                &tys.iter().map(|k| cx.layout_of(k)).collect::<Result<Vec<_>, _>>()?,
+                &ReprOptions::default(),
+                kind,
+            )?
+        }
+
+        // SIMD vector types.
+        ty::Adt(def, substs) if def.repr().simd() => {
+            if !def.is_struct() {
+                // Should have yielded E0517 by now.
+                tcx.sess.delay_span_bug(
+                    DUMMY_SP,
+                    "#[repr(simd)] was applied to an ADT that is not a struct",
+                );
+                return Err(LayoutError::Unknown(ty));
+            }
+
+            // Supported SIMD vectors are homogeneous ADTs with at least one field:
+            //
+            // * #[repr(simd)] struct S(T, T, T, T);
+            // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
+            // * #[repr(simd)] struct S([T; 4])
+            //
+            // where T is a primitive scalar (integer/float/pointer).
+
+            // SIMD vectors with zero fields are not supported.
+            // (should be caught by typeck)
+            if def.non_enum_variant().fields.is_empty() {
+                tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty));
+            }
+
+            // Type of the first ADT field:
+            let f0_ty = def.non_enum_variant().fields[0].ty(tcx, substs);
+
+            // Heterogeneous SIMD vectors are not supported:
+            // (should be caught by typeck)
+            for fi in &def.non_enum_variant().fields {
+                if fi.ty(tcx, substs) != f0_ty {
+                    tcx.sess.fatal(&format!("monomorphising heterogeneous SIMD type `{}`", ty));
+                }
+            }
+
+            // The element type and number of elements of the SIMD vector
+            // are obtained from:
+            //
+            // * the element type and length of the single array field, if
+            // the first field is of array type, or
+            //
+            // * the homogeneous field type and the number of fields.
+            let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() {
+                // First ADT field is an array:
+
+                // SIMD vectors with multiple array fields are not supported:
+                // (should be caught by typeck)
+                if def.non_enum_variant().fields.len() != 1 {
+                    tcx.sess.fatal(&format!(
+                        "monomorphising SIMD type `{}` with more than one array field",
+                        ty
+                    ));
+                }
+
+                // Extract the number of elements from the layout of the array field:
+                let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else {
+                        return Err(LayoutError::Unknown(ty));
+                    };
+
+                (*e_ty, *count, true)
+            } else {
+                // First ADT field is not an array:
+                (f0_ty, def.non_enum_variant().fields.len() as _, false)
+            };
+
+            // SIMD vectors of zero length are not supported.
+            // Additionally, lengths are capped at 2^16 as a fixed maximum backends must
+            // support.
+            //
+            // Can't be caught in typeck if the array length is generic.
+            if e_len == 0 {
+                tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty));
+            } else if e_len > MAX_SIMD_LANES {
+                tcx.sess.fatal(&format!(
+                    "monomorphising SIMD type `{}` of length greater than {}",
+                    ty, MAX_SIMD_LANES,
+                ));
+            }
+
+            // Compute the ABI of the element type:
+            let e_ly = cx.layout_of(e_ty)?;
+            let Abi::Scalar(e_abi) = e_ly.abi else {
+                    // This error isn't caught in typeck, e.g., if
+                    // the element type of the vector is generic.
+                    tcx.sess.fatal(&format!(
+                        "monomorphising SIMD type `{}` with a non-primitive-scalar \
+                        (integer/float/pointer) element type `{}`",
+                        ty, e_ty
+                    ))
+                };
+
+            // Compute the size and alignment of the vector:
+            let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?;
+            let align = dl.vector_align(size);
+            let size = size.align_to(align.abi);
+
+            // Compute the placement of the vector fields:
+            let fields = if is_array {
+                FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] }
+            } else {
+                FieldsShape::Array { stride: e_ly.size, count: e_len }
+            };
+
+            tcx.intern_layout(LayoutS {
+                variants: Variants::Single { index: VariantIdx::new(0) },
+                fields,
+                abi: Abi::Vector { element: e_abi, count: e_len },
+                largest_niche: e_ly.largest_niche,
+                size,
+                align,
+            })
+        }
+
+        // ADTs.
+        ty::Adt(def, substs) => {
+            // Cache the field layouts.
+            let variants = def
+                .variants()
+                .iter()
+                .map(|v| {
+                    v.fields
+                        .iter()
+                        .map(|field| cx.layout_of(field.ty(tcx, substs)))
+                        .collect::<Result<Vec<_>, _>>()
+                })
+                .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+
+            if def.is_union() {
+                if def.repr().pack.is_some() && def.repr().align.is_some() {
+                    cx.tcx.sess.delay_span_bug(
+                        tcx.def_span(def.did()),
+                        "union cannot be packed and aligned",
+                    );
+                    return Err(LayoutError::Unknown(ty));
+                }
+
+                let mut align =
+                    if def.repr().pack.is_some() { dl.i8_align } else { dl.aggregate_align };
+
+                if let Some(repr_align) = def.repr().align {
+                    align = align.max(AbiAndPrefAlign::new(repr_align));
+                }
+
+                let optimize = !def.repr().inhibit_union_abi_opt();
+                let mut size = Size::ZERO;
+                let mut abi = Abi::Aggregate { sized: true };
+                let index = VariantIdx::new(0);
+                for field in &variants[index] {
+                    assert!(!field.is_unsized());
+                    align = align.max(field.align);
+
+                    // If all non-ZST fields have the same ABI, forward this ABI
+                    if optimize && !field.is_zst() {
+                        // Discard valid range information and allow undef
+                        let field_abi = match field.abi {
+                            Abi::Scalar(x) => Abi::Scalar(x.to_union()),
+                            Abi::ScalarPair(x, y) => Abi::ScalarPair(x.to_union(), y.to_union()),
+                            Abi::Vector { element: x, count } => {
+                                Abi::Vector { element: x.to_union(), count }
+                            }
+                            Abi::Uninhabited | Abi::Aggregate { .. } => {
+                                Abi::Aggregate { sized: true }
+                            }
+                        };
+
+                        if size == Size::ZERO {
+                            // first non ZST: initialize 'abi'
+                            abi = field_abi;
+                        } else if abi != field_abi {
+                            // different fields have different ABI: reset to Aggregate
+                            abi = Abi::Aggregate { sized: true };
+                        }
+                    }
+
+                    size = cmp::max(size, field.size);
+                }
+
+                if let Some(pack) = def.repr().pack {
+                    align = align.min(AbiAndPrefAlign::new(pack));
+                }
+
+                return Ok(tcx.intern_layout(LayoutS {
+                    variants: Variants::Single { index },
+                    fields: FieldsShape::Union(
+                        NonZeroUsize::new(variants[index].len()).ok_or(LayoutError::Unknown(ty))?,
+                    ),
+                    abi,
+                    largest_niche: None,
+                    align,
+                    size: size.align_to(align.abi),
+                }));
+            }
+
+            // A variant is absent if it's uninhabited and only has ZST fields.
+            // Present uninhabited variants only require space for their fields,
+            // but *not* an encoding of the discriminant (e.g., a tag value).
+            // See issue #49298 for more details on the need to leave space
+            // for non-ZST uninhabited data (mostly partial initialization).
+            let absent = |fields: &[TyAndLayout<'_>]| {
+                let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited());
+                let is_zst = fields.iter().all(|f| f.is_zst());
+                uninhabited && is_zst
+            };
+            let (present_first, present_second) = {
+                let mut present_variants = variants
+                    .iter_enumerated()
+                    .filter_map(|(i, v)| if absent(v) { None } else { Some(i) });
+                (present_variants.next(), present_variants.next())
+            };
+            let present_first = match present_first {
+                Some(present_first) => present_first,
+                // Uninhabited because it has no variants, or only absent ones.
+                None if def.is_enum() => {
+                    return Ok(tcx.layout_of(param_env.and(tcx.types.never))?.layout);
+                }
+                // If it's a struct, still compute a layout so that we can still compute the
+                // field offsets.
+                None => VariantIdx::new(0),
+            };
+
+            let is_struct = !def.is_enum() ||
+                    // Only one variant is present.
+                    (present_second.is_none() &&
+                        // Representation optimizations are allowed.
+                        !def.repr().inhibit_enum_layout_opt());
+            if is_struct {
+                // Struct, or univariant enum equivalent to a struct.
+                // (Typechecking will reject discriminant-sizing attrs.)
+
+                let v = present_first;
+                let kind = if def.is_enum() || variants[v].is_empty() {
+                    StructKind::AlwaysSized
+                } else {
+                    let param_env = tcx.param_env(def.did());
+                    let last_field = def.variant(v).fields.last().unwrap();
+                    let always_sized =
+                        tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
+                    if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
+                };
+
+                let mut st = univariant_uninterned(cx, ty, &variants[v], &def.repr(), kind)?;
+                st.variants = Variants::Single { index: v };
+
+                if def.is_unsafe_cell() {
+                    let hide_niches = |scalar: &mut _| match scalar {
+                        Scalar::Initialized { value, valid_range } => {
+                            *valid_range = WrappingRange::full(value.size(dl))
+                        }
+                        // Already doesn't have any niches
+                        Scalar::Union { .. } => {}
+                    };
+                    match &mut st.abi {
+                        Abi::Uninhabited => {}
+                        Abi::Scalar(scalar) => hide_niches(scalar),
+                        Abi::ScalarPair(a, b) => {
+                            hide_niches(a);
+                            hide_niches(b);
+                        }
+                        Abi::Vector { element, count: _ } => hide_niches(element),
+                        Abi::Aggregate { sized: _ } => {}
+                    }
+                    st.largest_niche = None;
+                    return Ok(tcx.intern_layout(st));
+                }
+
+                let (start, end) = cx.tcx.layout_scalar_valid_range(def.did());
+                match st.abi {
+                    Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
+                        // the asserts ensure that we are not using the
+                        // `#[rustc_layout_scalar_valid_range(n)]`
+                        // attribute to widen the range of anything as that would probably
+                        // result in UB somewhere
+                        // FIXME(eddyb) the asserts are probably not needed,
+                        // as larger validity ranges would result in missed
+                        // optimizations, *not* wrongly assuming the inner
+                        // value is valid. e.g. unions enlarge validity ranges,
+                        // because the values may be uninitialized.
+                        if let Bound::Included(start) = start {
+                            // FIXME(eddyb) this might be incorrect - it doesn't
+                            // account for wrap-around (end < start) ranges.
+                            let valid_range = scalar.valid_range_mut();
+                            assert!(valid_range.start <= start);
+                            valid_range.start = start;
+                        }
+                        if let Bound::Included(end) = end {
+                            // FIXME(eddyb) this might be incorrect - it doesn't
+                            // account for wrap-around (end < start) ranges.
+                            let valid_range = scalar.valid_range_mut();
+                            assert!(valid_range.end >= end);
+                            valid_range.end = end;
+                        }
+
+                        // Update `largest_niche` if we have introduced a larger niche.
+                        let niche = Niche::from_scalar(dl, Size::ZERO, *scalar);
+                        if let Some(niche) = niche {
+                            match st.largest_niche {
+                                Some(largest_niche) => {
+                                    // Replace the existing niche even if they're equal,
+                                    // because this one is at a lower offset.
+                                    if largest_niche.available(dl) <= niche.available(dl) {
+                                        st.largest_niche = Some(niche);
+                                    }
+                                }
+                                None => st.largest_niche = Some(niche),
+                            }
+                        }
+                    }
+                    _ => assert!(
+                        start == Bound::Unbounded && end == Bound::Unbounded,
+                        "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}",
+                        def,
+                        st,
+                    ),
+                }
+
+                return Ok(tcx.intern_layout(st));
+            }
+
+            // At this point, we have handled all unions and
+            // structs. (We have also handled univariant enums
+            // that allow representation optimization.)
+            assert!(def.is_enum());
+
+            // Until we've decided whether to use the tagged or
+            // niche filling LayoutS, we don't want to intern the
+            // variant layouts, so we can't store them in the
+            // overall LayoutS. Store the overall LayoutS
+            // and the variant LayoutSs here until then.
+            struct TmpLayout<'tcx> {
+                layout: LayoutS<'tcx>,
+                variants: IndexVec<VariantIdx, LayoutS<'tcx>>,
+            }
+
+            let calculate_niche_filling_layout =
+                || -> Result<Option<TmpLayout<'tcx>>, LayoutError<'tcx>> {
+                    // The current code for niche-filling relies on variant indices
+                    // instead of actual discriminants, so enums with
+                    // explicit discriminants (RFC #2363) would misbehave.
+                    if def.repr().inhibit_enum_layout_opt()
+                        || def
+                            .variants()
+                            .iter_enumerated()
+                            .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()))
+                    {
+                        return Ok(None);
+                    }
+
+                    if variants.len() < 2 {
+                        return Ok(None);
+                    }
+
+                    let mut align = dl.aggregate_align;
+                    let mut variant_layouts = variants
+                        .iter_enumerated()
+                        .map(|(j, v)| {
+                            let mut st = univariant_uninterned(
+                                cx,
+                                ty,
+                                v,
+                                &def.repr(),
+                                StructKind::AlwaysSized,
+                            )?;
+                            st.variants = Variants::Single { index: j };
+
+                            align = align.max(st.align);
+
+                            Ok(st)
+                        })
+                        .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+
+                    let largest_variant_index = match variant_layouts
+                        .iter_enumerated()
+                        .max_by_key(|(_i, layout)| layout.size.bytes())
+                        .map(|(i, _layout)| i)
+                    {
+                        None => return Ok(None),
+                        Some(i) => i,
+                    };
+
+                    let all_indices = VariantIdx::new(0)..=VariantIdx::new(variants.len() - 1);
+                    let needs_disc = |index: VariantIdx| {
+                        index != largest_variant_index && !absent(&variants[index])
+                    };
+                    let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
+                        ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
+
+                    let count = niche_variants.size_hint().1.unwrap() as u128;
+
+                    // Find the field with the largest niche
+                    let (field_index, niche, (niche_start, niche_scalar)) = match variants
+                        [largest_variant_index]
+                        .iter()
+                        .enumerate()
+                        .filter_map(|(j, field)| Some((j, field.largest_niche?)))
+                        .max_by_key(|(_, niche)| niche.available(dl))
+                        .and_then(|(j, niche)| Some((j, niche, niche.reserve(cx, count)?)))
+                    {
+                        None => return Ok(None),
+                        Some(x) => x,
+                    };
+
+                    let niche_offset = niche.offset
+                        + variant_layouts[largest_variant_index].fields.offset(field_index);
+                    let niche_size = niche.value.size(dl);
+                    let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
+
+                    let all_variants_fit =
+                        variant_layouts.iter_enumerated_mut().all(|(i, layout)| {
+                            if i == largest_variant_index {
+                                return true;
+                            }
+
+                            layout.largest_niche = None;
+
+                            if layout.size <= niche_offset {
+                                // This variant will fit before the niche.
+                                return true;
+                            }
+
+                            // Determine if it'll fit after the niche.
+                            let this_align = layout.align.abi;
+                            let this_offset = (niche_offset + niche_size).align_to(this_align);
+
+                            if this_offset + layout.size > size {
+                                return false;
+                            }
+
+                            // It'll fit, but we need to make some adjustments.
+                            match layout.fields {
+                                FieldsShape::Arbitrary { ref mut offsets, .. } => {
+                                    for (j, offset) in offsets.iter_mut().enumerate() {
+                                        if !variants[i][j].is_zst() {
+                                            *offset += this_offset;
+                                        }
+                                    }
+                                }
+                                _ => {
+                                    panic!("Layout of fields should be Arbitrary for variants")
+                                }
+                            }
+
+                            // It can't be a Scalar or ScalarPair because the offset isn't 0.
+                            if !layout.abi.is_uninhabited() {
+                                layout.abi = Abi::Aggregate { sized: true };
+                            }
+                            layout.size += this_offset;
+
+                            true
+                        });
+
+                    if !all_variants_fit {
+                        return Ok(None);
+                    }
+
+                    let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar);
+
+                    let others_zst = variant_layouts
+                        .iter_enumerated()
+                        .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO);
+                    let same_size = size == variant_layouts[largest_variant_index].size;
+                    let same_align = align == variant_layouts[largest_variant_index].align;
+
+                    let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) {
+                        Abi::Uninhabited
+                    } else if same_size && same_align && others_zst {
+                        match variant_layouts[largest_variant_index].abi {
+                            // When the total alignment and size match, we can use the
+                            // same ABI as the scalar variant with the reserved niche.
+                            Abi::Scalar(_) => Abi::Scalar(niche_scalar),
+                            Abi::ScalarPair(first, second) => {
+                                // Only the niche is guaranteed to be initialised,
+                                // so use union layouts for the other primitive.
+                                if niche_offset == Size::ZERO {
+                                    Abi::ScalarPair(niche_scalar, second.to_union())
+                                } else {
+                                    Abi::ScalarPair(first.to_union(), niche_scalar)
+                                }
+                            }
+                            _ => Abi::Aggregate { sized: true },
+                        }
+                    } else {
+                        Abi::Aggregate { sized: true }
+                    };
+
+                    let layout = LayoutS {
+                        variants: Variants::Multiple {
+                            tag: niche_scalar,
+                            tag_encoding: TagEncoding::Niche {
+                                untagged_variant: largest_variant_index,
+                                niche_variants,
+                                niche_start,
+                            },
+                            tag_field: 0,
+                            variants: IndexVec::new(),
+                        },
+                        fields: FieldsShape::Arbitrary {
+                            offsets: vec![niche_offset],
+                            memory_index: vec![0],
+                        },
+                        abi,
+                        largest_niche,
+                        size,
+                        align,
+                    };
+
+                    Ok(Some(TmpLayout { layout, variants: variant_layouts }))
+                };
+
+            let niche_filling_layout = calculate_niche_filling_layout()?;
+
+            let (mut min, mut max) = (i128::MAX, i128::MIN);
+            let discr_type = def.repr().discr_type();
+            let bits = Integer::from_attr(cx, discr_type).size().bits();
+            for (i, discr) in def.discriminants(tcx) {
+                if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
+                    continue;
+                }
+                let mut x = discr.val as i128;
+                if discr_type.is_signed() {
+                    // sign extend the raw representation to be an i128
+                    x = (x << (128 - bits)) >> (128 - bits);
+                }
+                if x < min {
+                    min = x;
+                }
+                if x > max {
+                    max = x;
+                }
+            }
+            // We might have no inhabited variants, so pretend there's at least one.
+            if (min, max) == (i128::MAX, i128::MIN) {
+                min = 0;
+                max = 0;
+            }
+            assert!(min <= max, "discriminant range is {}...{}", min, max);
+            let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr(), min, max);
+
+            let mut align = dl.aggregate_align;
+            let mut size = Size::ZERO;
+
+            // We're interested in the smallest alignment, so start large.
+            let mut start_align = Align::from_bytes(256).unwrap();
+            assert_eq!(Integer::for_align(dl, start_align), None);
+
+            // repr(C) on an enum tells us to make a (tag, union) layout,
+            // so we need to grow the prefix alignment to be at least
+            // the alignment of the union. (This value is used both for
+            // determining the alignment of the overall enum, and the
+            // determining the alignment of the payload after the tag.)
+            let mut prefix_align = min_ity.align(dl).abi;
+            if def.repr().c() {
+                for fields in &variants {
+                    for field in fields {
+                        prefix_align = prefix_align.max(field.align.abi);
+                    }
+                }
+            }
+
+            // Create the set of structs that represent each variant.
+            let mut layout_variants = variants
+                .iter_enumerated()
+                .map(|(i, field_layouts)| {
+                    let mut st = univariant_uninterned(
+                        cx,
+                        ty,
+                        &field_layouts,
+                        &def.repr(),
+                        StructKind::Prefixed(min_ity.size(), prefix_align),
+                    )?;
+                    st.variants = Variants::Single { index: i };
+                    // Find the first field we can't move later
+                    // to make room for a larger discriminant.
+                    for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) {
+                        if !field.is_zst() || field.align.abi.bytes() != 1 {
+                            start_align = start_align.min(field.align.abi);
+                            break;
+                        }
+                    }
+                    size = cmp::max(size, st.size);
+                    align = align.max(st.align);
+                    Ok(st)
+                })
+                .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+
+            // Align the maximum variant size to the largest alignment.
+            size = size.align_to(align.abi);
+
+            if size.bytes() >= dl.obj_size_bound() {
+                return Err(LayoutError::SizeOverflow(ty));
+            }
+
+            let typeck_ity = Integer::from_attr(dl, def.repr().discr_type());
+            if typeck_ity < min_ity {
+                // It is a bug if Layout decided on a greater discriminant size than typeck for
+                // some reason at this point (based on values discriminant can take on). Mostly
+                // because this discriminant will be loaded, and then stored into variable of
+                // type calculated by typeck. Consider such case (a bug): typeck decided on
+                // byte-sized discriminant, but layout thinks we need a 16-bit to store all
+                // discriminant values. That would be a bug, because then, in codegen, in order
+                // to store this 16-bit discriminant into 8-bit sized temporary some of the
+                // space necessary to represent would have to be discarded (or layout is wrong
+                // on thinking it needs 16 bits)
+                bug!(
+                    "layout decided on a larger discriminant type ({:?}) than typeck ({:?})",
+                    min_ity,
+                    typeck_ity
+                );
+                // However, it is fine to make discr type however large (as an optimisation)
+                // after this point – we’ll just truncate the value we load in codegen.
+            }
+
+            // Check to see if we should use a different type for the
+            // discriminant. We can safely use a type with the same size
+            // as the alignment of the first field of each variant.
+            // We increase the size of the discriminant to avoid LLVM copying
+            // padding when it doesn't need to. This normally causes unaligned
+            // load/stores and excessive memcpy/memset operations. By using a
+            // bigger integer size, LLVM can be sure about its contents and
+            // won't be so conservative.
+
+            // Use the initial field alignment
+            let mut ity = if def.repr().c() || def.repr().int.is_some() {
+                min_ity
+            } else {
+                Integer::for_align(dl, start_align).unwrap_or(min_ity)
+            };
+
+            // If the alignment is not larger than the chosen discriminant size,
+            // don't use the alignment as the final size.
+            if ity <= min_ity {
+                ity = min_ity;
+            } else {
+                // Patch up the variants' first few fields.
+                let old_ity_size = min_ity.size();
+                let new_ity_size = ity.size();
+                for variant in &mut layout_variants {
+                    match variant.fields {
+                        FieldsShape::Arbitrary { ref mut offsets, .. } => {
+                            for i in offsets {
+                                if *i <= old_ity_size {
+                                    assert_eq!(*i, old_ity_size);
+                                    *i = new_ity_size;
+                                }
+                            }
+                            // We might be making the struct larger.
+                            if variant.size <= old_ity_size {
+                                variant.size = new_ity_size;
+                            }
+                        }
+                        _ => bug!(),
+                    }
+                }
+            }
+
+            let tag_mask = ity.size().unsigned_int_max();
+            let tag = Scalar::Initialized {
+                value: Int(ity, signed),
+                valid_range: WrappingRange {
+                    start: (min as u128 & tag_mask),
+                    end: (max as u128 & tag_mask),
+                },
+            };
+            let mut abi = Abi::Aggregate { sized: true };
+
+            if layout_variants.iter().all(|v| v.abi.is_uninhabited()) {
+                abi = Abi::Uninhabited;
+            } else if tag.size(dl) == size {
+                // Make sure we only use scalar layout when the enum is entirely its
+                // own tag (i.e. it has no padding nor any non-ZST variant fields).
+                abi = Abi::Scalar(tag);
+            } else {
+                // Try to use a ScalarPair for all tagged enums.
+                let mut common_prim = None;
+                let mut common_prim_initialized_in_all_variants = true;
+                for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) {
+                    let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
+                            bug!();
+                        };
+                    let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
+                    let (field, offset) = match (fields.next(), fields.next()) {
+                        (None, None) => {
+                            common_prim_initialized_in_all_variants = false;
+                            continue;
+                        }
+                        (Some(pair), None) => pair,
+                        _ => {
+                            common_prim = None;
+                            break;
+                        }
+                    };
+                    let prim = match field.abi {
+                        Abi::Scalar(scalar) => {
+                            common_prim_initialized_in_all_variants &=
+                                matches!(scalar, Scalar::Initialized { .. });
+                            scalar.primitive()
+                        }
+                        _ => {
+                            common_prim = None;
+                            break;
+                        }
+                    };
+                    if let Some(pair) = common_prim {
+                        // This is pretty conservative. We could go fancier
+                        // by conflating things like i32 and u32, or even
+                        // realising that (u8, u8) could just cohabit with
+                        // u16 or even u32.
+                        if pair != (prim, offset) {
+                            common_prim = None;
+                            break;
+                        }
+                    } else {
+                        common_prim = Some((prim, offset));
+                    }
+                }
+                if let Some((prim, offset)) = common_prim {
+                    let prim_scalar = if common_prim_initialized_in_all_variants {
+                        scalar_unit(prim)
+                    } else {
+                        // Common prim might be uninit.
+                        Scalar::Union { value: prim }
+                    };
+                    let pair = scalar_pair(cx, tag, prim_scalar);
+                    let pair_offsets = match pair.fields {
+                        FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
+                            assert_eq!(memory_index, &[0, 1]);
+                            offsets
+                        }
+                        _ => bug!(),
+                    };
+                    if pair_offsets[0] == Size::ZERO
+                        && pair_offsets[1] == *offset
+                        && align == pair.align
+                        && size == pair.size
+                    {
+                        // We can use `ScalarPair` only when it matches our
+                        // already computed layout (including `#[repr(C)]`).
+                        abi = pair.abi;
+                    }
+                }
+            }
+
+            // If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the
+            // variants to ensure they are consistent. This is because a downcast is
+            // semantically a NOP, and thus should not affect layout.
+            if matches!(abi, Abi::Scalar(..) | Abi::ScalarPair(..)) {
+                for variant in &mut layout_variants {
+                    // We only do this for variants with fields; the others are not accessed anyway.
+                    // Also do not overwrite any already existing "clever" ABIs.
+                    if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) {
+                        variant.abi = abi;
+                        // Also need to bump up the size and alignment, so that the entire value fits in here.
+                        variant.size = cmp::max(variant.size, size);
+                        variant.align.abi = cmp::max(variant.align.abi, align.abi);
+                    }
+                }
+            }
+
+            let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
+
+            let tagged_layout = LayoutS {
+                variants: Variants::Multiple {
+                    tag,
+                    tag_encoding: TagEncoding::Direct,
+                    tag_field: 0,
+                    variants: IndexVec::new(),
+                },
+                fields: FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] },
+                largest_niche,
+                abi,
+                align,
+                size,
+            };
+
+            let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants };
+
+            let mut best_layout = match (tagged_layout, niche_filling_layout) {
+                (tl, Some(nl)) => {
+                    // Pick the smaller layout; otherwise,
+                    // pick the layout with the larger niche; otherwise,
+                    // pick tagged as it has simpler codegen.
+                    use Ordering::*;
+                    let niche_size = |tmp_l: &TmpLayout<'_>| {
+                        tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
+                    };
+                    match (
+                        tl.layout.size.cmp(&nl.layout.size),
+                        niche_size(&tl).cmp(&niche_size(&nl)),
+                    ) {
+                        (Greater, _) => nl,
+                        (Equal, Less) => nl,
+                        _ => tl,
+                    }
+                }
+                (tl, None) => tl,
+            };
+
+            // Now we can intern the variant layouts and store them in the enum layout.
+            best_layout.layout.variants = match best_layout.layout.variants {
+                Variants::Multiple { tag, tag_encoding, tag_field, .. } => Variants::Multiple {
+                    tag,
+                    tag_encoding,
+                    tag_field,
+                    variants: best_layout
+                        .variants
+                        .into_iter()
+                        .map(|layout| tcx.intern_layout(layout))
+                        .collect(),
+                },
+                _ => bug!(),
+            };
+
+            tcx.intern_layout(best_layout.layout)
+        }
+
+        // Types with no meaningful known layout.
+        ty::Projection(_) | ty::Opaque(..) => {
+            // NOTE(eddyb) `layout_of` query should've normalized these away,
+            // if that was possible, so there's no reason to try again here.
+            return Err(LayoutError::Unknown(ty));
+        }
+
+        ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) => {
+            bug!("Layout::compute: unexpected type `{}`", ty)
+        }
+
+        ty::Bound(..) | ty::Param(_) | ty::Error(_) => {
+            return Err(LayoutError::Unknown(ty));
+        }
+    })
+}
+
+/// Overlap eligibility and variant assignment for each GeneratorSavedLocal.
+#[derive(Clone, Debug, PartialEq)]
+enum SavedLocalEligibility {
+    Unassigned,
+    Assigned(VariantIdx),
+    // FIXME: Use newtype_index so we aren't wasting bytes
+    Ineligible(Option<u32>),
+}
+
+// When laying out generators, we divide our saved local fields into two
+// categories: overlap-eligible and overlap-ineligible.
+//
+// Those fields which are ineligible for overlap go in a "prefix" at the
+// beginning of the layout, and always have space reserved for them.
+//
+// Overlap-eligible fields are only assigned to one variant, so we lay
+// those fields out for each variant and put them right after the
+// prefix.
+//
+// Finally, in the layout details, we point to the fields from the
+// variants they are assigned to. It is possible for some fields to be
+// included in multiple variants. No field ever "moves around" in the
+// layout; its offset is always the same.
+//
+// Also included in the layout are the upvars and the discriminant.
+// These are included as fields on the "outer" layout; they are not part
+// of any variant.
+
+/// Compute the eligibility and assignment of each local.
+fn generator_saved_local_eligibility<'tcx>(
+    info: &GeneratorLayout<'tcx>,
+) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) {
+    use SavedLocalEligibility::*;
+
+    let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> =
+        IndexVec::from_elem_n(Unassigned, info.field_tys.len());
+
+    // The saved locals not eligible for overlap. These will get
+    // "promoted" to the prefix of our generator.
+    let mut ineligible_locals = BitSet::new_empty(info.field_tys.len());
+
+    // Figure out which of our saved locals are fields in only
+    // one variant. The rest are deemed ineligible for overlap.
+    for (variant_index, fields) in info.variant_fields.iter_enumerated() {
+        for local in fields {
+            match assignments[*local] {
+                Unassigned => {
+                    assignments[*local] = Assigned(variant_index);
+                }
+                Assigned(idx) => {
+                    // We've already seen this local at another suspension
+                    // point, so it is no longer a candidate.
+                    trace!(
+                        "removing local {:?} in >1 variant ({:?}, {:?})",
+                        local,
+                        variant_index,
+                        idx
+                    );
+                    ineligible_locals.insert(*local);
+                    assignments[*local] = Ineligible(None);
+                }
+                Ineligible(_) => {}
+            }
+        }
+    }
+
+    // Next, check every pair of eligible locals to see if they
+    // conflict.
+    for local_a in info.storage_conflicts.rows() {
+        let conflicts_a = info.storage_conflicts.count(local_a);
+        if ineligible_locals.contains(local_a) {
+            continue;
+        }
+
+        for local_b in info.storage_conflicts.iter(local_a) {
+            // local_a and local_b are storage live at the same time, therefore they
+            // cannot overlap in the generator layout. The only way to guarantee
+            // this is if they are in the same variant, or one is ineligible
+            // (which means it is stored in every variant).
+            if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] {
+                continue;
+            }
+
+            // If they conflict, we will choose one to make ineligible.
+            // This is not always optimal; it's just a greedy heuristic that
+            // seems to produce good results most of the time.
+            let conflicts_b = info.storage_conflicts.count(local_b);
+            let (remove, other) =
+                if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) };
+            ineligible_locals.insert(remove);
+            assignments[remove] = Ineligible(None);
+            trace!("removing local {:?} due to conflict with {:?}", remove, other);
+        }
+    }
+
+    // Count the number of variants in use. If only one of them, then it is
+    // impossible to overlap any locals in our layout. In this case it's
+    // always better to make the remaining locals ineligible, so we can
+    // lay them out with the other locals in the prefix and eliminate
+    // unnecessary padding bytes.
+    {
+        let mut used_variants = BitSet::new_empty(info.variant_fields.len());
+        for assignment in &assignments {
+            if let Assigned(idx) = assignment {
+                used_variants.insert(*idx);
+            }
+        }
+        if used_variants.count() < 2 {
+            for assignment in assignments.iter_mut() {
+                *assignment = Ineligible(None);
+            }
+            ineligible_locals.insert_all();
+        }
+    }
+
+    // Write down the order of our locals that will be promoted to the prefix.
+    {
+        for (idx, local) in ineligible_locals.iter().enumerate() {
+            assignments[local] = Ineligible(Some(idx as u32));
+        }
+    }
+    debug!("generator saved local assignments: {:?}", assignments);
+
+    (ineligible_locals, assignments)
+}
+
+/// Compute the full generator layout.
+fn generator_layout<'tcx>(
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    ty: Ty<'tcx>,
+    def_id: hir::def_id::DefId,
+    substs: SubstsRef<'tcx>,
+) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
+    use SavedLocalEligibility::*;
+    let tcx = cx.tcx;
+    let subst_field = |ty: Ty<'tcx>| EarlyBinder(ty).subst(tcx, substs);
+
+    let Some(info) = tcx.generator_layout(def_id) else {
+            return Err(LayoutError::Unknown(ty));
+        };
+    let (ineligible_locals, assignments) = generator_saved_local_eligibility(&info);
+
+    // Build a prefix layout, including "promoting" all ineligible
+    // locals as part of the prefix. We compute the layout of all of
+    // these fields at once to get optimal packing.
+    let tag_index = substs.as_generator().prefix_tys().count();
+
+    // `info.variant_fields` already accounts for the reserved variants, so no need to add them.
+    let max_discr = (info.variant_fields.len() - 1) as u128;
+    let discr_int = Integer::fit_unsigned(max_discr);
+    let discr_int_ty = discr_int.to_ty(tcx, false);
+    let tag = Scalar::Initialized {
+        value: Primitive::Int(discr_int, false),
+        valid_range: WrappingRange { start: 0, end: max_discr },
+    };
+    let tag_layout = cx.tcx.intern_layout(LayoutS::scalar(cx, tag));
+    let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout };
+
+    let promoted_layouts = ineligible_locals
+        .iter()
+        .map(|local| subst_field(info.field_tys[local]))
+        .map(|ty| tcx.mk_maybe_uninit(ty))
+        .map(|ty| cx.layout_of(ty));
+    let prefix_layouts = substs
+        .as_generator()
+        .prefix_tys()
+        .map(|ty| cx.layout_of(ty))
+        .chain(iter::once(Ok(tag_layout)))
+        .chain(promoted_layouts)
+        .collect::<Result<Vec<_>, _>>()?;
+    let prefix = univariant_uninterned(
+        cx,
+        ty,
+        &prefix_layouts,
+        &ReprOptions::default(),
+        StructKind::AlwaysSized,
+    )?;
+
+    let (prefix_size, prefix_align) = (prefix.size, prefix.align);
+
+    // Split the prefix layout into the "outer" fields (upvars and
+    // discriminant) and the "promoted" fields. Promoted fields will
+    // get included in each variant that requested them in
+    // GeneratorLayout.
+    debug!("prefix = {:#?}", prefix);
+    let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
+        FieldsShape::Arbitrary { mut offsets, memory_index } => {
+            let mut inverse_memory_index = invert_mapping(&memory_index);
+
+            // "a" (`0..b_start`) and "b" (`b_start..`) correspond to
+            // "outer" and "promoted" fields respectively.
+            let b_start = (tag_index + 1) as u32;
+            let offsets_b = offsets.split_off(b_start as usize);
+            let offsets_a = offsets;
+
+            // Disentangle the "a" and "b" components of `inverse_memory_index`
+            // by preserving the order but keeping only one disjoint "half" each.
+            // FIXME(eddyb) build a better abstraction for permutations, if possible.
+            let inverse_memory_index_b: Vec<_> =
+                inverse_memory_index.iter().filter_map(|&i| i.checked_sub(b_start)).collect();
+            inverse_memory_index.retain(|&i| i < b_start);
+            let inverse_memory_index_a = inverse_memory_index;
+
+            // Since `inverse_memory_index_{a,b}` each only refer to their
+            // respective fields, they can be safely inverted
+            let memory_index_a = invert_mapping(&inverse_memory_index_a);
+            let memory_index_b = invert_mapping(&inverse_memory_index_b);
+
+            let outer_fields =
+                FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
+            (outer_fields, offsets_b, memory_index_b)
+        }
+        _ => bug!(),
+    };
+
+    let mut size = prefix.size;
+    let mut align = prefix.align;
+    let variants = info
+        .variant_fields
+        .iter_enumerated()
+        .map(|(index, variant_fields)| {
+            // Only include overlap-eligible fields when we compute our variant layout.
+            let variant_only_tys = variant_fields
+                .iter()
+                .filter(|local| match assignments[**local] {
+                    Unassigned => bug!(),
+                    Assigned(v) if v == index => true,
+                    Assigned(_) => bug!("assignment does not match variant"),
+                    Ineligible(_) => false,
+                })
+                .map(|local| subst_field(info.field_tys[*local]));
+
+            let mut variant = univariant_uninterned(
+                cx,
+                ty,
+                &variant_only_tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
+                &ReprOptions::default(),
+                StructKind::Prefixed(prefix_size, prefix_align.abi),
+            )?;
+            variant.variants = Variants::Single { index };
+
+            let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else {
+                    bug!();
+                };
+
+            // Now, stitch the promoted and variant-only fields back together in
+            // the order they are mentioned by our GeneratorLayout.
+            // Because we only use some subset (that can differ between variants)
+            // of the promoted fields, we can't just pick those elements of the
+            // `promoted_memory_index` (as we'd end up with gaps).
+            // So instead, we build an "inverse memory_index", as if all of the
+            // promoted fields were being used, but leave the elements not in the
+            // subset as `INVALID_FIELD_IDX`, which we can filter out later to
+            // obtain a valid (bijective) mapping.
+            const INVALID_FIELD_IDX: u32 = !0;
+            let mut combined_inverse_memory_index =
+                vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()];
+            let mut offsets_and_memory_index = iter::zip(offsets, memory_index);
+            let combined_offsets = variant_fields
+                .iter()
+                .enumerate()
+                .map(|(i, local)| {
+                    let (offset, memory_index) = match assignments[*local] {
+                        Unassigned => bug!(),
+                        Assigned(_) => {
+                            let (offset, memory_index) = offsets_and_memory_index.next().unwrap();
+                            (offset, promoted_memory_index.len() as u32 + memory_index)
+                        }
+                        Ineligible(field_idx) => {
+                            let field_idx = field_idx.unwrap() as usize;
+                            (promoted_offsets[field_idx], promoted_memory_index[field_idx])
+                        }
+                    };
+                    combined_inverse_memory_index[memory_index as usize] = i as u32;
+                    offset
+                })
+                .collect();
+
+            // Remove the unused slots and invert the mapping to obtain the
+            // combined `memory_index` (also see previous comment).
+            combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX);
+            let combined_memory_index = invert_mapping(&combined_inverse_memory_index);
+
+            variant.fields = FieldsShape::Arbitrary {
+                offsets: combined_offsets,
+                memory_index: combined_memory_index,
+            };
+
+            size = size.max(variant.size);
+            align = align.max(variant.align);
+            Ok(tcx.intern_layout(variant))
+        })
+        .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+
+    size = size.align_to(align.abi);
+
+    let abi = if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi().is_uninhabited()) {
+        Abi::Uninhabited
+    } else {
+        Abi::Aggregate { sized: true }
+    };
+
+    let layout = tcx.intern_layout(LayoutS {
+        variants: Variants::Multiple {
+            tag,
+            tag_encoding: TagEncoding::Direct,
+            tag_field: tag_index,
+            variants,
+        },
+        fields: outer_fields,
+        abi,
+        largest_niche: prefix.largest_niche,
+        size,
+        align,
+    });
+    debug!("generator layout ({:?}): {:#?}", ty, layout);
+    Ok(layout)
+}
+
+/// This is invoked by the `layout_of` query to record the final
+/// layout of each type.
+#[inline(always)]
+fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: TyAndLayout<'tcx>) {
+    // If we are running with `-Zprint-type-sizes`, maybe record layouts
+    // for dumping later.
+    if cx.tcx.sess.opts.unstable_opts.print_type_sizes {
+        record_layout_for_printing_outlined(cx, layout)
+    }
+}
+
+fn record_layout_for_printing_outlined<'tcx>(
+    cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
+    layout: TyAndLayout<'tcx>,
+) {
+    // Ignore layouts that are done with non-empty environments or
+    // non-monomorphic layouts, as the user only wants to see the stuff
+    // resulting from the final codegen session.
+    if layout.ty.has_non_region_param() || !cx.param_env.caller_bounds().is_empty() {
+        return;
+    }
+
+    // (delay format until we actually need it)
+    let record = |kind, packed, opt_discr_size, variants| {
+        let type_desc = format!("{:?}", layout.ty);
+        cx.tcx.sess.code_stats.record_type_size(
+            kind,
+            type_desc,
+            layout.align.abi,
+            layout.size,
+            packed,
+            opt_discr_size,
+            variants,
+        );
+    };
+
+    let adt_def = match *layout.ty.kind() {
+        ty::Adt(ref adt_def, _) => {
+            debug!("print-type-size t: `{:?}` process adt", layout.ty);
+            adt_def
+        }
+
+        ty::Closure(..) => {
+            debug!("print-type-size t: `{:?}` record closure", layout.ty);
+            record(DataTypeKind::Closure, false, None, vec![]);
+            return;
+        }
+
+        _ => {
+            debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
+            return;
+        }
+    };
+
+    let adt_kind = adt_def.adt_kind();
+    let adt_packed = adt_def.repr().pack.is_some();
+
+    let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
+        let mut min_size = Size::ZERO;
+        let field_info: Vec<_> = flds
+            .iter()
+            .enumerate()
+            .map(|(i, &name)| {
+                let field_layout = layout.field(cx, i);
+                let offset = layout.fields.offset(i);
+                let field_end = offset + field_layout.size;
+                if min_size < field_end {
+                    min_size = field_end;
+                }
+                FieldInfo {
+                    name,
+                    offset: offset.bytes(),
+                    size: field_layout.size.bytes(),
+                    align: field_layout.align.abi.bytes(),
+                }
+            })
+            .collect();
+
+        VariantInfo {
+            name: n,
+            kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact },
+            align: layout.align.abi.bytes(),
+            size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() },
+            fields: field_info,
+        }
+    };
+
+    match layout.variants {
+        Variants::Single { index } => {
+            if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive {
+                debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name);
+                let variant_def = &adt_def.variant(index);
+                let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
+                record(
+                    adt_kind.into(),
+                    adt_packed,
+                    None,
+                    vec![build_variant_info(Some(variant_def.name), &fields, layout)],
+                );
+            } else {
+                // (This case arises for *empty* enums; so give it
+                // zero variants.)
+                record(adt_kind.into(), adt_packed, None, vec![]);
+            }
+        }
+
+        Variants::Multiple { tag, ref tag_encoding, .. } => {
+            debug!(
+                "print-type-size `{:#?}` adt general variants def {}",
+                layout.ty,
+                adt_def.variants().len()
+            );
+            let variant_infos: Vec<_> = adt_def
+                .variants()
+                .iter_enumerated()
+                .map(|(i, variant_def)| {
+                    let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
+                    build_variant_info(Some(variant_def.name), &fields, layout.for_variant(cx, i))
+                })
+                .collect();
+            record(
+                adt_kind.into(),
+                adt_packed,
+                match tag_encoding {
+                    TagEncoding::Direct => Some(tag.size(cx)),
+                    _ => None,
+                },
+                variant_infos,
+            );
+        }
+    }
+}
diff --git a/compiler/rustc_middle/src/ty/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
index 87c85dcfff3..100926ad446 100644
--- a/compiler/rustc_middle/src/ty/layout_sanity_check.rs
+++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs
@@ -1,4 +1,4 @@
-use crate::ty::{
+use rustc_middle::ty::{
     layout::{LayoutCx, TyAndLayout},
     TyCtxt,
 };
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 10c18789f74..f97fc4c199d 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -9,8 +9,6 @@
 #![feature(never_type)]
 #![feature(box_patterns)]
 #![recursion_limit = "256"]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_middle;
@@ -19,21 +17,26 @@ extern crate tracing;
 
 use rustc_middle::ty::query::Providers;
 
+mod abi;
 mod assoc;
 mod common_traits;
 mod consts;
 mod errors;
 mod implied_bounds;
 pub mod instance;
+mod layout;
+mod layout_sanity_check;
 mod needs_drop;
 pub mod representability;
 mod ty;
 
 pub fn provide(providers: &mut Providers) {
+    abi::provide(providers);
     assoc::provide(providers);
     common_traits::provide(providers);
     consts::provide(providers);
     implied_bounds::provide(providers);
+    layout::provide(providers);
     needs_drop::provide(providers);
     ty::provide(providers);
     instance::provide(providers);
diff --git a/config.toml.example b/config.toml.example
index a967d881b02..1f5747456e9 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -291,6 +291,10 @@ changelog-seen = 2
 # on this runtime, such as `-C profile-generate` or `-C instrument-coverage`).
 #profiler = false
 
+# Use the optimized LLVM C intrinsics for `compiler_builtins`, rather than Rust intrinsics.
+# Requires the LLVM submodule to be managed by bootstrap (i.e. not external).
+#optimized-compiler-builtins = false
+
 # Indicates whether the native libraries linked into Cargo will be statically
 # linked or not.
 #cargo-native-static = false
@@ -521,6 +525,12 @@ changelog-seen = 2
 # A descriptive string to be appended to `rustc --version` output, which is
 # also used in places like debuginfo `DW_AT_producer`. This may be useful for
 # supplementary build information, like distro-specific package versions.
+#
+# The Rust compiler will differentiate between versions of itself, including
+# based on this string, which means that if you wish to be compatible with
+# upstream Rust you need to set this to "". However, note that if you are not
+# actually compatible -- for example if you've backported patches that change
+# behavior -- this may lead to miscompilations or other bugs.
 #description = <none> (string)
 
 # The root location of the musl installation directory. The library directory
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 3018d1c9125..3687f84b1bd 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -2392,7 +2392,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
+    #[rustc_const_unstable(
+        feature = "const_btree_len",
+        issue = "71835",
+        implied_by = "const_btree_new"
+    )]
     pub const fn len(&self) -> usize {
         self.length
     }
@@ -2413,7 +2417,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
+    #[rustc_const_unstable(
+        feature = "const_btree_len",
+        issue = "71835",
+        implied_by = "const_btree_new"
+    )]
     pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 3caaf521240..5783d836e10 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1174,7 +1174,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
+    #[rustc_const_unstable(
+        feature = "const_btree_len",
+        issue = "71835",
+        implied_by = "const_btree_new"
+    )]
     pub const fn len(&self) -> usize {
         self.map.len()
     }
@@ -1193,7 +1197,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
+    #[rustc_const_unstable(
+        feature = "const_btree_len",
+        issue = "71835",
+        implied_by = "const_btree_new"
+    )]
     pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index a5322953d49..df315dad893 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -3,6 +3,10 @@
 //! Thread-safe reference-counting pointers.
 //!
 //! See the [`Arc<T>`][Arc] documentation for more details.
+//!
+//! **Note**: This module is only available on platforms that support atomic
+//! loads and stores of pointers. This may be detected at compile time using
+//! `#[cfg(target_has_atomic = "ptr")]`.
 
 use core::any::Any;
 use core::borrow;
@@ -82,6 +86,11 @@ macro_rules! acquire {
 /// [`Mutex`][mutex], [`RwLock`][rwlock], or one of the [`Atomic`][atomic]
 /// types.
 ///
+/// **Note**: This type is only available on platforms that support atomic
+/// loads and stores of pointers, which includes all platforms that support
+/// the `std` crate but not all those which only support [`alloc`](crate).
+/// This may be detected at compile time using `#[cfg(target_has_atomic = "ptr")]`.
+///
 /// ## Thread Safety
 ///
 /// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference
@@ -1980,33 +1989,26 @@ impl<T: ?Sized> Weak<T> {
         // We use a CAS loop to increment the strong count instead of a
         // fetch_add as this function should never take the reference count
         // from zero to one.
-        let inner = self.inner()?;
-
-        // Relaxed load because any write of 0 that we can observe
-        // leaves the field in a permanently zero state (so a
-        // "stale" read of 0 is fine), and any other value is
-        // confirmed via the CAS below.
-        let mut n = inner.strong.load(Relaxed);
-
-        loop {
-            if n == 0 {
-                return None;
-            }
-
-            // See comments in `Arc::clone` for why we do this (for `mem::forget`).
-            if n > MAX_REFCOUNT {
-                abort();
-            }
-
+        self.inner()?
+            .strong
             // Relaxed is fine for the failure case because we don't have any expectations about the new state.
             // Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner
             // value can be initialized after `Weak` references have already been created. In that case, we
             // expect to observe the fully initialized value.
-            match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) {
-                Ok(_) => return Some(unsafe { Arc::from_inner(self.ptr) }), // null checked above
-                Err(old) => n = old,
-            }
-        }
+            .fetch_update(Acquire, Relaxed, |n| {
+                // Any write of 0 we can observe leaves the field in permanently zero state.
+                if n == 0 {
+                    return None;
+                }
+                // See comments in `Arc::clone` for why we do this (for `mem::forget`).
+                if n > MAX_REFCOUNT {
+                    abort();
+                }
+                Some(n + 1)
+            })
+            .ok()
+            // null checked above
+            .map(|_| unsafe { Arc::from_inner(self.ptr) })
     }
 
     /// Gets the number of strong (`Arc`) pointers pointing to this allocation.
diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs
index 528ee4ff154..9d8e309a978 100644
--- a/library/alloc/src/task.rs
+++ b/library/alloc/src/task.rs
@@ -1,5 +1,11 @@
 #![stable(feature = "wake_trait", since = "1.51.0")]
+
 //! Types and Traits for working with asynchronous tasks.
+//!
+//! **Note**: This module is only available on platforms that support atomic
+//! loads and stores of pointers. This may be detected at compile time using
+//! `#[cfg(target_has_atomic = "ptr")]`.
+
 use core::mem::ManuallyDrop;
 use core::task::{RawWaker, RawWakerVTable, Waker};
 
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs
index a3f8fe40fd5..87d61deb1eb 100644
--- a/library/alloc/src/vec/in_place_collect.rs
+++ b/library/alloc/src/vec/in_place_collect.rs
@@ -55,6 +55,9 @@
 //! This is handled by the [`InPlaceDrop`] guard for sink items (`U`) and by
 //! [`vec::IntoIter::forget_allocation_drop_remaining()`] for remaining source items (`T`).
 //!
+//! If dropping any remaining source item (`T`) panics then [`InPlaceDstBufDrop`] will handle dropping
+//! the already collected sink items (`U`) and freeing the allocation.
+//!
 //! [`vec::IntoIter::forget_allocation_drop_remaining()`]: super::IntoIter::forget_allocation_drop_remaining()
 //!
 //! # O(1) collect
@@ -138,7 +141,7 @@ use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
 use core::mem::{self, ManuallyDrop, SizedTypeProperties};
 use core::ptr::{self};
 
-use super::{InPlaceDrop, SpecFromIter, SpecFromIterNested, Vec};
+use super::{InPlaceDrop, InPlaceDstBufDrop, SpecFromIter, SpecFromIterNested, Vec};
 
 /// Specialization marker for collecting an iterator pipeline into a Vec while reusing the
 /// source allocation, i.e. executing the pipeline in place.
@@ -191,14 +194,17 @@ where
             );
         }
 
-        // Drop any remaining values at the tail of the source but prevent drop of the allocation
-        // itself once IntoIter goes out of scope.
-        // If the drop panics then we also leak any elements collected into dst_buf.
+        // The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`.
+        // This is safe because `forget_allocation_drop_remaining` immediately forgets the allocation
+        // before any panic can occur in order to avoid any double free, and then proceeds to drop
+        // any remaining values at the tail of the source.
         //
         // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce
         // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the
         // module documenttation why this is ok anyway.
+        let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap };
         src.forget_allocation_drop_remaining();
+        mem::forget(dst_guard);
 
         let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) };
 
diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs
index 1b1ef9130fa..25ca33c6a7b 100644
--- a/library/alloc/src/vec/in_place_drop.rs
+++ b/library/alloc/src/vec/in_place_drop.rs
@@ -22,3 +22,18 @@ impl<T> Drop for InPlaceDrop<T> {
         }
     }
 }
+
+// A helper struct for in-place collection that drops the destination allocation and elements,
+// to avoid leaking them if some other destructor panics.
+pub(super) struct InPlaceDstBufDrop<T> {
+    pub(super) ptr: *mut T,
+    pub(super) len: usize,
+    pub(super) cap: usize,
+}
+
+impl<T> Drop for InPlaceDstBufDrop<T> {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe { super::Vec::from_raw_parts(self.ptr, self.len, self.cap) };
+    }
+}
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index d74e77637bd..73d7c90cf78 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -95,13 +95,16 @@ impl<T, A: Allocator> IntoIter<T, A> {
     }
 
     /// Drops remaining elements and relinquishes the backing allocation.
+    /// This method guarantees it won't panic before relinquishing
+    /// the backing allocation.
     ///
     /// This is roughly equivalent to the following, but more efficient
     ///
     /// ```
     /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter();
+    /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter());
     /// (&mut into_iter).for_each(core::mem::drop);
-    /// unsafe { core::ptr::write(&mut into_iter, Vec::new().into_iter()); }
+    /// std::mem::forget(into_iter);
     /// ```
     ///
     /// This method is used by in-place iteration, refer to the vec::in_place_collect
@@ -118,6 +121,8 @@ impl<T, A: Allocator> IntoIter<T, A> {
         self.ptr = self.buf.as_ptr();
         self.end = self.buf.as_ptr();
 
+        // Dropping the remaining elements can panic, so this needs to be
+        // done only after updating the other fields.
         unsafe {
             ptr::drop_in_place(remaining);
         }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index d6d986905e6..0332047e6b6 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -125,7 +125,7 @@ use self::set_len_on_drop::SetLenOnDrop;
 mod set_len_on_drop;
 
 #[cfg(not(no_global_oom_handling))]
-use self::in_place_drop::InPlaceDrop;
+use self::in_place_drop::{InPlaceDrop, InPlaceDstBufDrop};
 
 #[cfg(not(no_global_oom_handling))]
 mod in_place_drop;
@@ -483,15 +483,13 @@ impl<T> Vec<T> {
         Self::with_capacity_in(capacity, Global)
     }
 
-    /// Creates a `Vec<T>` directly from the raw components of another vector.
+    /// Creates a `Vec<T>` directly from a pointer, a capacity, and a length.
     ///
     /// # Safety
     ///
     /// This is highly unsafe, due to the number of invariants that aren't
     /// checked:
     ///
-    /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
-    ///   (at least, it's highly likely to be incorrect if it wasn't).
     /// * `T` needs to have the same alignment as what `ptr` was allocated with.
     ///   (`T` having a less strict alignment is not sufficient, the alignment really
     ///   needs to be equal to satisfy the [`dealloc`] requirement that memory must be
@@ -500,6 +498,14 @@ impl<T> Vec<T> {
     ///   to be the same size as the pointer was allocated with. (Because similar to
     ///   alignment, [`dealloc`] must be called with the same layout `size`.)
     /// * `length` needs to be less than or equal to `capacity`.
+    /// * The first `length` values must be properly initialized values of type `T`.
+    /// * `capacity` needs to be the capacity that the pointer was allocated with.
+    /// * The allocated size in bytes must be no larger than `isize::MAX`.
+    ///   See the safety documentation of [`pointer::offset`].
+    ///
+    /// These requirements are always upheld by any `ptr` that has been allocated
+    /// via `Vec<T>`. Other allocation sources are allowed if the invariants are
+    /// upheld.
     ///
     /// Violating these may cause problems like corrupting the allocator's
     /// internal data structures. For example it is normally **not** safe
@@ -551,6 +557,32 @@ impl<T> Vec<T> {
     ///     assert_eq!(rebuilt, [4, 5, 6]);
     /// }
     /// ```
+    ///
+    /// Using memory that was allocated elsewhere:
+    ///
+    /// ```rust
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::{AllocError, Allocator, Global, Layout};
+    ///
+    /// fn main() {
+    ///     let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
+    ///
+    ///     let vec = unsafe {
+    ///         let mem = match Global.allocate(layout) {
+    ///             Ok(mem) => mem.cast::<u32>().as_ptr(),
+    ///             Err(AllocError) => return,
+    ///         };
+    ///
+    ///         mem.write(1_000_000);
+    ///
+    ///         Vec::from_raw_parts_in(mem, 1, 16, Global)
+    ///     };
+    ///
+    ///     assert_eq!(vec, &[1_000_000]);
+    ///     assert_eq!(vec.capacity(), 16);
+    /// }
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
@@ -641,21 +673,30 @@ impl<T, A: Allocator> Vec<T, A> {
         Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
     }
 
-    /// Creates a `Vec<T, A>` directly from the raw components of another vector.
+    /// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length,
+    /// and an allocator.
     ///
     /// # Safety
     ///
     /// This is highly unsafe, due to the number of invariants that aren't
     /// checked:
     ///
-    /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
-    ///   (at least, it's highly likely to be incorrect if it wasn't).
-    /// * `T` needs to have the same size and alignment as what `ptr` was allocated with.
+    /// * `T` needs to have the same alignment as what `ptr` was allocated with.
     ///   (`T` having a less strict alignment is not sufficient, the alignment really
     ///   needs to be equal to satisfy the [`dealloc`] requirement that memory must be
     ///   allocated and deallocated with the same layout.)
+    /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
+    ///   to be the same size as the pointer was allocated with. (Because similar to
+    ///   alignment, [`dealloc`] must be called with the same layout `size`.)
     /// * `length` needs to be less than or equal to `capacity`.
-    /// * `capacity` needs to be the capacity that the pointer was allocated with.
+    /// * The first `length` values must be properly initialized values of type `T`.
+    /// * `capacity` needs to [*fit*] the layout size that the pointer was allocated with.
+    /// * The allocated size in bytes must be no larger than `isize::MAX`.
+    ///   See the safety documentation of [`pointer::offset`].
+    ///
+    /// These requirements are always upheld by any `ptr` that has been allocated
+    /// via `Vec<T, A>`. Other allocation sources are allowed if the invariants are
+    /// upheld.
     ///
     /// Violating these may cause problems like corrupting the allocator's
     /// internal data structures. For example it is **not** safe
@@ -673,6 +714,7 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// [`String`]: crate::string::String
     /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
+    /// [*fit*]: crate::alloc::Allocator#memory-fitting
     ///
     /// # Examples
     ///
@@ -711,6 +753,29 @@ impl<T, A: Allocator> Vec<T, A> {
     ///     assert_eq!(rebuilt, [4, 5, 6]);
     /// }
     /// ```
+    ///
+    /// Using memory that was allocated elsewhere:
+    ///
+    /// ```rust
+    /// use std::alloc::{alloc, Layout};
+    ///
+    /// fn main() {
+    ///     let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
+    ///     let vec = unsafe {
+    ///         let mem = alloc(layout).cast::<u32>();
+    ///         if mem.is_null() {
+    ///             return;
+    ///         }
+    ///
+    ///         mem.write(1_000_000);
+    ///
+    ///         Vec::from_raw_parts(mem, 1, 16)
+    ///     };
+    ///
+    ///     assert_eq!(vec, &[1_000_000]);
+    ///     assert_eq!(vec.capacity(), 16);
+    /// }
+    /// ```
     #[inline]
     #[unstable(feature = "allocator_api", issue = "32838")]
     pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self {
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index f140fc4143f..e0271187044 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1191,48 +1191,53 @@ fn test_from_iter_specialization_panic_during_iteration_drops() {
 }
 
 #[test]
-fn test_from_iter_specialization_panic_during_drop_leaks() {
-    static mut DROP_COUNTER: usize = 0;
+fn test_from_iter_specialization_panic_during_drop_doesnt_leak() {
+    static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5];
+    static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2];
 
     #[derive(Debug)]
-    enum Droppable {
-        DroppedTwice(Box<i32>),
-        PanicOnDrop,
-    }
+    struct Old(usize);
 
-    impl Drop for Droppable {
+    impl Drop for Old {
         fn drop(&mut self) {
-            match self {
-                Droppable::DroppedTwice(_) => {
-                    unsafe {
-                        DROP_COUNTER += 1;
-                    }
-                    println!("Dropping!")
-                }
-                Droppable::PanicOnDrop => {
-                    if !std::thread::panicking() {
-                        panic!();
-                    }
-                }
+            unsafe {
+                DROP_COUNTER_OLD[self.0] += 1;
+            }
+
+            if self.0 == 3 {
+                panic!();
             }
+
+            println!("Dropped Old: {}", self.0);
         }
     }
 
-    let mut to_free: *mut Droppable = core::ptr::null_mut();
-    let mut cap = 0;
+    #[derive(Debug)]
+    struct New(usize);
+
+    impl Drop for New {
+        fn drop(&mut self) {
+            unsafe {
+                DROP_COUNTER_NEW[self.0] += 1;
+            }
+
+            println!("Dropped New: {}", self.0);
+        }
+    }
 
     let _ = std::panic::catch_unwind(AssertUnwindSafe(|| {
-        let mut v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop];
-        to_free = v.as_mut_ptr();
-        cap = v.capacity();
-        let _ = v.into_iter().take(0).collect::<Vec<_>>();
+        let v = vec![Old(0), Old(1), Old(2), Old(3), Old(4)];
+        let _ = v.into_iter().map(|x| New(x.0)).take(2).collect::<Vec<_>>();
     }));
 
-    assert_eq!(unsafe { DROP_COUNTER }, 1);
-    // clean up the leak to keep miri happy
-    unsafe {
-        drop(Vec::from_raw_parts(to_free, 0, cap));
-    }
+    assert_eq!(unsafe { DROP_COUNTER_OLD[0] }, 1);
+    assert_eq!(unsafe { DROP_COUNTER_OLD[1] }, 1);
+    assert_eq!(unsafe { DROP_COUNTER_OLD[2] }, 1);
+    assert_eq!(unsafe { DROP_COUNTER_OLD[3] }, 1);
+    assert_eq!(unsafe { DROP_COUNTER_OLD[4] }, 1);
+
+    assert_eq!(unsafe { DROP_COUNTER_NEW[0] }, 1);
+    assert_eq!(unsafe { DROP_COUNTER_NEW[1] }, 1);
 }
 
 // regression test for issue #85322. Peekable previously implemented InPlaceIterable,
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 288cab1ef39..4474b673a95 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -405,6 +405,7 @@ impl<T> Cell<T> {
     /// assert_eq!(cell.replace(10), 5);
     /// assert_eq!(cell.get(), 10);
     /// ```
+    #[inline]
     #[stable(feature = "move_cell", since = "1.17.0")]
     pub fn replace(&self, val: T) -> T {
         // SAFETY: This can cause data races if called from a separate thread,
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index b7a63b7c675..224bc9effe6 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -1444,6 +1444,38 @@ impl char {
         matches!(*self, '0'..='9')
     }
 
+    /// Checks if the value is an ASCII octal digit:
+    /// U+0030 '0' ..= U+0037 '7'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(is_ascii_octdigit)]
+    ///
+    /// let uppercase_a = 'A';
+    /// let a = 'a';
+    /// let zero = '0';
+    /// let seven = '7';
+    /// let nine = '9';
+    /// let percent = '%';
+    /// let lf = '\n';
+    ///
+    /// assert!(!uppercase_a.is_ascii_octdigit());
+    /// assert!(!a.is_ascii_octdigit());
+    /// assert!(zero.is_ascii_octdigit());
+    /// assert!(seven.is_ascii_octdigit());
+    /// assert!(!nine.is_ascii_octdigit());
+    /// assert!(!percent.is_ascii_octdigit());
+    /// assert!(!lf.is_ascii_octdigit());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
+    #[rustc_const_unstable(feature = "is_ascii_octdigit", issue = "101288")]
+    #[inline]
+    pub const fn is_ascii_octdigit(&self) -> bool {
+        matches!(*self, '0'..='7')
+    }
+
     /// Checks if the value is an ASCII hexadecimal digit:
     ///
     /// - U+0030 '0' ..= U+0039 '9', or
diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs
index d2e80e8e7e5..9e9c02093be 100644
--- a/library/core/src/const_closure.rs
+++ b/library/core/src/const_closure.rs
@@ -16,15 +16,18 @@ use crate::marker::Destruct;
 /// assert!(7 == cl(2));
 /// assert!(8 == cl(1));
 /// ```
-pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> {
-    data: &'a mut CapturedData,
-    func: Function,
+pub(crate) struct ConstFnMutClosure<CapturedData, Function> {
+    /// The Data captured by the Closure.
+    /// Must be either a (mutable) reference or a tuple of (mutable) references.
+    pub data: CapturedData,
+    /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn
+    pub func: Function,
 }
-
-impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> {
+impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> {
     /// Function for creating a new closure.
     ///
     /// `data` is the a mutable borrow of data that is captured from the environment.
+    /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually.
     ///
     /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
     ///   and return the return value of the closure.
@@ -39,25 +42,36 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Fun
     }
 }
 
-impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
-    FnOnce<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
-where
-    Function:
-        ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
-{
-    type Output = ClosureReturnValue;
+macro_rules! impl_fn_mut_tuple {
+    ($($var:ident)*) => {
+        #[allow(unused_parens)]
+        impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
+            FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
+        where
+            Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
+        {
+            type Output = ClosureReturnValue;
 
-    extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
-        self.call_mut(args)
-    }
-}
-
-impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
-    FnMut<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
-where
-    Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
-{
-    extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
-        (self.func)(self.data, args)
-    }
+            extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
+            self.call_mut(args)
+            }
+        }
+        #[allow(unused_parens)]
+        impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
+            FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
+        where
+            Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
+        {
+            extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
+                #[allow(non_snake_case)]
+                let ($($var),*) = &mut self.data;
+                (self.func)(($($var),*), args)
+            }
+        }
+    };
 }
+impl_fn_mut_tuple!(A);
+impl_fn_mut_tuple!(A B);
+impl_fn_mut_tuple!(A B C);
+impl_fn_mut_tuple!(A B C D);
+impl_fn_mut_tuple!(A B C D E);
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index c42adda8da5..33493964bad 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -25,6 +25,7 @@
 //! # Generic Implementations
 //!
 //! - [`AsRef`] and [`AsMut`] auto-dereference if the inner type is a reference
+//!   (but not generally for all [dereferenceable types][core::ops::Deref])
 //! - [`From`]`<U> for T` implies [`Into`]`<T> for U`
 //! - [`TryFrom`]`<U> for T` implies [`TryInto`]`<T> for U`
 //! - [`From`] and [`Into`] are reflexive, which means that all types can
@@ -109,10 +110,12 @@ pub const fn identity<T>(x: T) -> T {
 /// If you need to do a costly conversion it is better to implement [`From`] with type
 /// `&T` or write a custom function.
 ///
+/// # Relation to `Borrow`
+///
 /// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in a few aspects:
 ///
 /// - Unlike `AsRef`, [`Borrow`] has a blanket impl for any `T`, and can be used to accept either
-///   a reference or a value.
+///   a reference or a value. (See also note on `AsRef`'s reflexibility below.)
 /// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for a borrowed value are
 ///   equivalent to those of the owned value. For this reason, if you want to
 ///   borrow only a single field of a struct you can implement `AsRef`, but not [`Borrow`].
@@ -122,9 +125,66 @@ pub const fn identity<T>(x: T) -> T {
 ///
 /// # Generic Implementations
 ///
-/// - `AsRef` auto-dereferences if the inner type is a reference or a mutable
-///   reference (e.g.: `foo.as_ref()` will work the same if `foo` has type
-///   `&mut Foo` or `&&mut Foo`)
+/// `AsRef` auto-dereferences if the inner type is a reference or a mutable reference
+/// (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`).
+///
+/// Note that due to historic reasons, the above currently does not hold generally for all
+/// [dereferenceable types], e.g. `foo.as_ref()` will *not* work the same as
+/// `Box::new(foo).as_ref()`. Instead, many smart pointers provide an `as_ref` implementation which
+/// simply returns a reference to the [pointed-to value] (but do not perform a cheap
+/// reference-to-reference conversion for that value). However, [`AsRef::as_ref`] should not be
+/// used for the sole purpose of dereferencing; instead ['`Deref` coercion'] can be used:
+///
+/// [dereferenceable types]: core::ops::Deref
+/// [pointed-to value]: core::ops::Deref::Target
+/// ['`Deref` coercion']: core::ops::Deref#more-on-deref-coercion
+///
+/// ```
+/// let x = Box::new(5i32);
+/// // Avoid this:
+/// // let y: &i32 = x.as_ref();
+/// // Better just write:
+/// let y: &i32 = &x;
+/// ```
+///
+/// Types which implement [`Deref`] should consider implementing `AsRef<T>` as follows:
+///
+/// [`Deref`]: core::ops::Deref
+///
+/// ```
+/// # use core::ops::Deref;
+/// # struct SomeType;
+/// # impl Deref for SomeType {
+/// #     type Target = [u8];
+/// #     fn deref(&self) -> &[u8] {
+/// #         &[]
+/// #     }
+/// # }
+/// impl<T> AsRef<T> for SomeType
+/// where
+///     T: ?Sized,
+///     <SomeType as Deref>::Target: AsRef<T>,
+/// {
+///     fn as_ref(&self) -> &T {
+///         self.deref().as_ref()
+///     }
+/// }
+/// ```
+///
+/// # Reflexivity
+///
+/// Ideally, `AsRef` would be reflexive, i.e. there would be an `impl<T: ?Sized> AsRef<T> for T`
+/// with [`as_ref`] simply returning its argument unchanged.
+/// Such a blanket implementation is currently *not* provided due to technical restrictions of
+/// Rust's type system (it would be overlapping with another existing blanket implementation for
+/// `&T where T: AsRef<U>` which allows `AsRef` to auto-dereference, see "Generic Implementations"
+/// above).
+///
+/// [`as_ref`]: AsRef::as_ref
+///
+/// A trivial implementation of `AsRef<T> for T` must be added explicitly for a particular type `T`
+/// where needed or desired. Note, however, that not all types from `std` contain such an
+/// implementation, and those cannot be added by external code due to orphan rules.
 ///
 /// # Examples
 ///
@@ -172,29 +232,138 @@ pub trait AsRef<T: ?Sized> {
 ///
 /// # Generic Implementations
 ///
-/// - `AsMut` auto-dereferences if the inner type is a mutable reference
-///   (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo`
-///   or `&mut &mut Foo`)
+/// `AsMut` auto-dereferences if the inner type is a mutable reference
+/// (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo` or `&mut &mut Foo`).
+///
+/// Note that due to historic reasons, the above currently does not hold generally for all
+/// [mutably dereferenceable types], e.g. `foo.as_mut()` will *not* work the same as
+/// `Box::new(foo).as_mut()`. Instead, many smart pointers provide an `as_mut` implementation which
+/// simply returns a reference to the [pointed-to value] (but do not perform a cheap
+/// reference-to-reference conversion for that value). However, [`AsMut::as_mut`] should not be
+/// used for the sole purpose of mutable dereferencing; instead ['`Deref` coercion'] can be used:
+///
+/// [mutably dereferenceable types]: core::ops::DerefMut
+/// [pointed-to value]: core::ops::Deref::Target
+/// ['`Deref` coercion']: core::ops::DerefMut#more-on-deref-coercion
+///
+/// ```
+/// let mut x = Box::new(5i32);
+/// // Avoid this:
+/// // let y: &mut i32 = x.as_mut();
+/// // Better just write:
+/// let y: &mut i32 = &mut x;
+/// ```
+///
+/// Types which implement [`DerefMut`] should consider to add an implementation of `AsMut<T>` as
+/// follows:
+///
+/// [`DerefMut`]: core::ops::DerefMut
+///
+/// ```
+/// # use core::ops::{Deref, DerefMut};
+/// # struct SomeType;
+/// # impl Deref for SomeType {
+/// #     type Target = [u8];
+/// #     fn deref(&self) -> &[u8] {
+/// #         &[]
+/// #     }
+/// # }
+/// # impl DerefMut for SomeType {
+/// #     fn deref_mut(&mut self) -> &mut [u8] {
+/// #         &mut []
+/// #     }
+/// # }
+/// impl<T> AsMut<T> for SomeType
+/// where
+///     <SomeType as Deref>::Target: AsMut<T>,
+/// {
+///     fn as_mut(&mut self) -> &mut T {
+///         self.deref_mut().as_mut()
+///     }
+/// }
+/// ```
+///
+/// # Reflexivity
+///
+/// Ideally, `AsMut` would be reflexive, i.e. there would be an `impl<T: ?Sized> AsMut<T> for T`
+/// with [`as_mut`] simply returning its argument unchanged.
+/// Such a blanket implementation is currently *not* provided due to technical restrictions of
+/// Rust's type system (it would be overlapping with another existing blanket implementation for
+/// `&mut T where T: AsMut<U>` which allows `AsMut` to auto-dereference, see "Generic
+/// Implementations" above).
+///
+/// [`as_mut`]: AsMut::as_mut
+///
+/// A trivial implementation of `AsMut<T> for T` must be added explicitly for a particular type `T`
+/// where needed or desired. Note, however, that not all types from `std` contain such an
+/// implementation, and those cannot be added by external code due to orphan rules.
 ///
 /// # Examples
 ///
-/// Using `AsMut` as trait bound for a generic function we can accept all mutable references
-/// that can be converted to type `&mut T`. Because [`Box<T>`] implements `AsMut<T>` we can
-/// write a function `add_one` that takes all arguments that can be converted to `&mut u64`.
-/// Because [`Box<T>`] implements `AsMut<T>`, `add_one` accepts arguments of type
-/// `&mut Box<u64>` as well:
+/// Using `AsMut` as trait bound for a generic function, we can accept all mutable references that
+/// can be converted to type `&mut T`. Unlike [dereference], which has a single [target type],
+/// there can be multiple implementations of `AsMut` for a type. In particular, `Vec<T>` implements
+/// both `AsMut<Vec<T>>` and `AsMut<[T]>`.
+///
+/// In the following, the example functions `caesar` and `null_terminate` provide a generic
+/// interface which work with any type that can be converted by cheap mutable-to-mutable conversion
+/// into a byte slice (`[u8]`) or byte vector (`Vec<u8>`), respectively.
+///
+/// [dereference]: core::ops::DerefMut
+/// [target type]: core::ops::Deref::Target
 ///
 /// ```
-/// fn add_one<T: AsMut<u64>>(num: &mut T) {
-///     *num.as_mut() += 1;
+/// struct Document {
+///     info: String,
+///     content: Vec<u8>,
 /// }
 ///
-/// let mut boxed_num = Box::new(0);
-/// add_one(&mut boxed_num);
-/// assert_eq!(*boxed_num, 1);
+/// impl<T: ?Sized> AsMut<T> for Document
+/// where
+///     Vec<u8>: AsMut<T>,
+/// {
+///     fn as_mut(&mut self) -> &mut T {
+///         self.content.as_mut()
+///     }
+/// }
+///
+/// fn caesar<T: AsMut<[u8]>>(data: &mut T, key: u8) {
+///     for byte in data.as_mut() {
+///         *byte = byte.wrapping_add(key);
+///     }
+/// }
+///
+/// fn null_terminate<T: AsMut<Vec<u8>>>(data: &mut T) {
+///     // Using a non-generic inner function, which contains most of the
+///     // functionality, helps to minimize monomorphization overhead.
+///     fn doit(data: &mut Vec<u8>) {
+///         let len = data.len();
+///         if len == 0 || data[len-1] != 0 {
+///             data.push(0);
+///         }
+///     }
+///     doit(data.as_mut());
+/// }
+///
+/// fn main() {
+///     let mut v: Vec<u8> = vec![1, 2, 3];
+///     caesar(&mut v, 5);
+///     assert_eq!(v, [6, 7, 8]);
+///     null_terminate(&mut v);
+///     assert_eq!(v, [6, 7, 8, 0]);
+///     let mut doc = Document {
+///         info: String::from("Example"),
+///         content: vec![17, 19, 8],
+///     };
+///     caesar(&mut doc, 1);
+///     assert_eq!(doc.content, [18, 20, 9]);
+///     null_terminate(&mut doc);
+///     assert_eq!(doc.content, [18, 20, 9, 0]);
+/// }
 /// ```
 ///
-/// [`Box<T>`]: ../../std/boxed/struct.Box.html
+/// Note, however, that APIs don't need to be generic. In many cases taking a `&mut [u8]` or
+/// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then).
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
 #[const_trait]
@@ -376,7 +545,7 @@ pub trait From<T>: Sized {
     #[lang = "from"]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn from(_: T) -> Self;
+    fn from(value: T) -> Self;
 }
 
 /// An attempted conversion that consumes `self`, which may or may not be
@@ -440,7 +609,7 @@ pub trait TryInto<T>: Sized {
 ///
 ///     fn try_from(value: i32) -> Result<Self, Self::Error> {
 ///         if value <= 0 {
-///             Err("GreaterThanZero only accepts value superior than zero!")
+///             Err("GreaterThanZero only accepts values greater than zero!")
 ///         } else {
 ///             Ok(GreaterThanZero(value))
 ///         }
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 372439f14ec..c8d28550567 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2610,7 +2610,7 @@ impl Debug for () {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Debug for PhantomData<T> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-        f.debug_struct("PhantomData").finish()
+        write!(f, "PhantomData<{}>", crate::any::type_name::<T>())
     }
 }
 
diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs
index 48f20f90a32..a07b63fb62b 100644
--- a/library/core/src/future/ready.rs
+++ b/library/core/src/future/ready.rs
@@ -24,6 +24,30 @@ impl<T> Future for Ready<T> {
     }
 }
 
+impl<T> Ready<T> {
+    /// Consumes the `Ready`, returning the wrapped value.
+    ///
+    /// # Panics
+    ///
+    /// Will panic if this [`Ready`] was already polled to completion.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ready_into_inner)]
+    /// use std::future;
+    ///
+    /// let a = future::ready(1);
+    /// assert_eq!(a.into_inner(), 1);
+    /// ```
+    #[unstable(feature = "ready_into_inner", issue = "101196")]
+    #[must_use]
+    #[inline]
+    pub fn into_inner(self) -> T {
+        self.0.expect("Called `into_inner()` on `Ready` after completion")
+    }
+}
+
 /// Creates a future that is immediately ready with a value.
 ///
 /// Futures created through this function are functionally similar to those
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 12b43da5a42..15ee14398b6 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -788,6 +788,7 @@ extern "rust-intrinsic" {
     /// uninitialized at that point in the control flow.
     ///
     /// This intrinsic should not be used outside of the compiler.
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn rustc_peek<T>(_: T) -> T;
 
     /// Aborts the execution of the process.
@@ -805,6 +806,7 @@ extern "rust-intrinsic" {
     /// On Unix, the
     /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
     /// `SIGBUS`.  The precise behaviour is not guaranteed and not stable.
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn abort() -> !;
 
     /// Informs the optimizer that this point in the code is not reachable,
@@ -843,6 +845,7 @@ extern "rust-intrinsic" {
     ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_likely", issue = "none")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn likely(b: bool) -> bool;
 
     /// Hints to the compiler that branch condition is likely to be false.
@@ -857,6 +860,7 @@ extern "rust-intrinsic" {
     ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_likely", issue = "none")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn unlikely(b: bool) -> bool;
 
     /// Executes a breakpoint trap, for inspection by a debugger.
@@ -876,6 +880,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is [`core::mem::size_of`].
     #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn size_of<T>() -> usize;
 
     /// The minimum alignment of a type.
@@ -887,6 +892,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is [`core::mem::align_of`].
     #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn min_align_of<T>() -> usize;
     /// The preferred alignment of a type.
     ///
@@ -915,6 +921,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is [`core::any::type_name`].
     #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn type_name<T: ?Sized>() -> &'static str;
 
     /// Gets an identifier which is globally unique to the specified type. This
@@ -928,6 +935,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
     #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn type_id<T: ?Sized + 'static>() -> u64;
 
     /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
@@ -935,6 +943,7 @@ extern "rust-intrinsic" {
     ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn assert_inhabited<T>();
 
     /// A guard for unsafe functions that cannot ever be executed if `T` does not permit
@@ -942,6 +951,7 @@ extern "rust-intrinsic" {
     ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn assert_zero_valid<T>();
 
     /// A guard for unsafe functions that cannot ever be executed if `T` has invalid
@@ -949,6 +959,7 @@ extern "rust-intrinsic" {
     ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn assert_uninit_valid<T>();
 
     /// Gets a reference to a static `Location` indicating where it was called.
@@ -960,6 +971,7 @@ extern "rust-intrinsic" {
     ///
     /// Consider using [`core::panic::Location::caller`] instead.
     #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn caller_location() -> &'static crate::panic::Location<'static>;
 
     /// Moves a value out of scope without running drop glue.
@@ -972,6 +984,7 @@ extern "rust-intrinsic" {
     /// Therefore, implementations must not require the user to uphold
     /// any safety invariants.
     #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn forget<T: ?Sized>(_: T);
 
     /// Reinterprets the bits of a value of one type as another type.
@@ -1251,6 +1264,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
     #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn needs_drop<T: ?Sized>() -> bool;
 
     /// Calculates the offset from a pointer.
@@ -1295,6 +1309,7 @@ extern "rust-intrinsic" {
     /// any safety invariants.
     ///
     /// Consider using [`pointer::mask`] instead.
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
 
     /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
@@ -1486,6 +1501,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is
     /// [`f32::min`]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn minnumf32(x: f32, y: f32) -> f32;
     /// Returns the minimum of two `f64` values.
     ///
@@ -1496,6 +1512,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is
     /// [`f64::min`]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn minnumf64(x: f64, y: f64) -> f64;
     /// Returns the maximum of two `f32` values.
     ///
@@ -1506,6 +1523,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is
     /// [`f32::max`]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn maxnumf32(x: f32, y: f32) -> f32;
     /// Returns the maximum of two `f64` values.
     ///
@@ -1516,6 +1534,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is
     /// [`f64::max`]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn maxnumf64(x: f64, y: f64) -> f64;
 
     /// Copies the sign from `y` to `x` for `f32` values.
@@ -1636,6 +1655,7 @@ extern "rust-intrinsic" {
     /// primitives via the `count_ones` method. For example,
     /// [`u32::count_ones`]
     #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn ctpop<T: Copy>(x: T) -> T;
 
     /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
@@ -1673,6 +1693,7 @@ extern "rust-intrinsic" {
     /// assert_eq!(num_leading, 16);
     /// ```
     #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn ctlz<T: Copy>(x: T) -> T;
 
     /// Like `ctlz`, but extra-unsafe as it returns `undef` when
@@ -1729,6 +1750,7 @@ extern "rust-intrinsic" {
     /// assert_eq!(num_trailing, 16);
     /// ```
     #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn cttz<T: Copy>(x: T) -> T;
 
     /// Like `cttz`, but extra-unsafe as it returns `undef` when
@@ -1761,6 +1783,7 @@ extern "rust-intrinsic" {
     /// primitives via the `swap_bytes` method. For example,
     /// [`u32::swap_bytes`]
     #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn bswap<T: Copy>(x: T) -> T;
 
     /// Reverses the bits in an integer type `T`.
@@ -1774,6 +1797,7 @@ extern "rust-intrinsic" {
     /// primitives via the `reverse_bits` method. For example,
     /// [`u32::reverse_bits`]
     #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn bitreverse<T: Copy>(x: T) -> T;
 
     /// Performs checked integer addition.
@@ -1787,6 +1811,7 @@ extern "rust-intrinsic" {
     /// primitives via the `overflowing_add` method. For example,
     /// [`u32::overflowing_add`]
     #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs checked integer subtraction
@@ -1800,6 +1825,7 @@ extern "rust-intrinsic" {
     /// primitives via the `overflowing_sub` method. For example,
     /// [`u32::overflowing_sub`]
     #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs checked integer multiplication
@@ -1813,6 +1839,7 @@ extern "rust-intrinsic" {
     /// primitives via the `overflowing_mul` method. For example,
     /// [`u32::overflowing_mul`]
     #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
 
     /// Performs an exact division, resulting in undefined behavior where
@@ -1887,6 +1914,7 @@ extern "rust-intrinsic" {
     /// primitives via the `rotate_left` method. For example,
     /// [`u32::rotate_left`]
     #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn rotate_left<T: Copy>(x: T, y: T) -> T;
 
     /// Performs rotate right.
@@ -1900,6 +1928,7 @@ extern "rust-intrinsic" {
     /// primitives via the `rotate_right` method. For example,
     /// [`u32::rotate_right`]
     #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
 
     /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
@@ -1913,6 +1942,7 @@ extern "rust-intrinsic" {
     /// primitives via the `wrapping_add` method. For example,
     /// [`u32::wrapping_add`]
     #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
     /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
@@ -1925,6 +1955,7 @@ extern "rust-intrinsic" {
     /// primitives via the `wrapping_sub` method. For example,
     /// [`u32::wrapping_sub`]
     #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
     /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
@@ -1937,6 +1968,7 @@ extern "rust-intrinsic" {
     /// primitives via the `wrapping_mul` method. For example,
     /// [`u32::wrapping_mul`]
     #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T;
 
     /// Computes `a + b`, saturating at numeric bounds.
@@ -1950,6 +1982,7 @@ extern "rust-intrinsic" {
     /// primitives via the `saturating_add` method. For example,
     /// [`u32::saturating_add`]
     #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
     /// Computes `a - b`, saturating at numeric bounds.
     ///
@@ -1962,6 +1995,7 @@ extern "rust-intrinsic" {
     /// primitives via the `saturating_sub` method. For example,
     /// [`u32::saturating_sub`]
     #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn saturating_sub<T: Copy>(a: T, b: T) -> T;
 
     /// Returns the value of the discriminant for the variant in 'v';
@@ -1974,6 +2008,7 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is [`core::mem::discriminant`].
     #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
 
     /// Returns the number of variants of the type `T` cast to a `usize`;
@@ -1986,6 +2021,7 @@ extern "rust-intrinsic" {
     ///
     /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`].
     #[rustc_const_unstable(feature = "variant_count", issue = "73662")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn variant_count<T>() -> usize;
 
     /// Rust's "try catch" construct which invokes the function pointer `try_fn`
@@ -2019,6 +2055,7 @@ extern "rust-intrinsic" {
     /// Therefore, implementations must not require the user to uphold
     /// any safety invariants.
     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8;
 
     /// Allocates a block of memory at compile time.
@@ -2069,6 +2106,7 @@ extern "rust-intrinsic" {
     ///
     /// [`std::hint::black_box`]: crate::hint::black_box
     #[rustc_const_unstable(feature = "const_black_box", issue = "none")]
+    #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
     pub fn black_box<T>(dummy: T) -> T;
 
     /// `ptr` must point to a vtable.
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index e598a54b4f1..e099700e3e7 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -264,7 +264,7 @@ pub trait IntoIterator {
 
 #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: ~const Iterator> const IntoIterator for I {
+impl<I: Iterator> const IntoIterator for I {
     type Item = I::Item;
     type IntoIter = I;
 
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index e26920b25cc..f6e6732b0e3 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -2431,22 +2431,13 @@ pub trait Iterator {
     ///
     /// # Example
     ///
-    /// Find the maximum value:
-    ///
     /// ```
-    /// fn find_max<I>(iter: I) -> Option<I::Item>
-    ///     where I: Iterator,
-    ///           I::Item: Ord,
-    /// {
-    ///     iter.reduce(|accum, item| {
-    ///         if accum >= item { accum } else { item }
-    ///     })
-    /// }
-    /// let a = [10, 20, 5, -23, 0];
-    /// let b: [u32; 0] = [];
+    /// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap();
+    /// assert_eq!(reduced, 45);
     ///
-    /// assert_eq!(find_max(a.iter()), Some(&20));
-    /// assert_eq!(find_max(b.iter()), None);
+    /// // Which is equivalent to doing it with `fold`:
+    /// let folded: i32 = (1..10).fold(0, |acc, e| acc + e);
+    /// assert_eq!(reduced, folded);
     /// ```
     #[inline]
     #[stable(feature = "iterator_fold_self", since = "1.51.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index c3df0d4f9b9..ca02ae90fde 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -164,6 +164,7 @@
 #![feature(const_slice_index)]
 #![feature(const_is_char_boundary)]
 #![feature(const_cstr_methods)]
+#![feature(is_ascii_octdigit)]
 //
 // Language features:
 #![feature(abi_unadjusted)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5cb5e4458cc..d5ed52124e2 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -799,6 +799,7 @@ impl<T: ?Sized> Unpin for *mut T {}
 #[unstable(feature = "const_trait_impl", issue = "67792")]
 #[lang = "destruct"]
 #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
+#[const_trait]
 pub trait Destruct {}
 
 /// A marker for tuple types.
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index c0be235c120..311c5fa5b68 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -622,6 +622,38 @@ impl u8 {
         matches!(*self, b'0'..=b'9')
     }
 
+    /// Checks if the value is an ASCII octal digit:
+    /// U+0030 '0' ..= U+0037 '7'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(is_ascii_octdigit)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let a = b'a';
+    /// let zero = b'0';
+    /// let seven = b'7';
+    /// let nine = b'9';
+    /// let percent = b'%';
+    /// let lf = b'\n';
+    ///
+    /// assert!(!uppercase_a.is_ascii_octdigit());
+    /// assert!(!a.is_ascii_octdigit());
+    /// assert!(zero.is_ascii_octdigit());
+    /// assert!(seven.is_ascii_octdigit());
+    /// assert!(!nine.is_ascii_octdigit());
+    /// assert!(!percent.is_ascii_octdigit());
+    /// assert!(!lf.is_ascii_octdigit());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
+    #[rustc_const_unstable(feature = "is_ascii_octdigit", issue = "101288")]
+    #[inline]
+    pub const fn is_ascii_octdigit(&self) -> bool {
+        matches!(*self, b'0'..=b'7')
+    }
+
     /// Checks if the value is an ASCII hexadecimal digit:
     ///
     /// - U+0030 '0' ..= U+0039 '9', or
@@ -976,8 +1008,8 @@ impl usize {
 /// assert_eq!(num.classify(), FpCategory::Normal);
 /// assert_eq!(inf.classify(), FpCategory::Infinite);
 /// assert_eq!(zero.classify(), FpCategory::Zero);
-/// assert_eq!(nan.classify(), FpCategory::Nan);
 /// assert_eq!(sub.classify(), FpCategory::Subnormal);
+/// assert_eq!(nan.classify(), FpCategory::Nan);
 /// ```
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 532a09736a7..da402d66502 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -721,6 +721,160 @@ macro_rules! nonzero_signed_operations {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
                     unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
                 }
+
+                /// Returns `true` if `self` is negative and `false` if the
+                /// number is positive.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_negation_ops)]
+                ///
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+                ///
+                /// assert!(neg_five.is_negative());
+                /// assert!(!pos_five.is_negative());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[must_use]
+                #[inline]
+                #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+                pub const fn is_negative(self) -> bool {
+                    self.get().is_negative()
+                }
+
+                /// Checked negation. Computes `-self`, returning `None` if `self == i32::MIN`.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_negation_ops)]
+                ///
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                ///
+                /// assert_eq!(pos_five.checked_neg(), Some(neg_five));
+                /// assert_eq!(min.checked_neg(), None);
+                /// # Some(())
+                /// # }
+                /// ```
+                #[inline]
+                #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+                pub const fn checked_neg(self) -> Option<$Ty> {
+                    if let Some(result) = self.get().checked_neg() {
+                        // SAFETY: negation of nonzero cannot yield zero values.
+                        return Some(unsafe { $Ty::new_unchecked(result) });
+                    }
+                    None
+                }
+
+                /// Negates self, overflowing if this is equal to the minimum value.
+                ///
+                #[doc = concat!("See [`", stringify!($Int), "::overflowing_neg`]")]
+                /// for documentation on overflow behaviour.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_negation_ops)]
+                ///
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                ///
+                /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false));
+                /// assert_eq!(min.overflowing_neg(), (min, true));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[inline]
+                #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+                pub const fn overflowing_neg(self) -> ($Ty, bool) {
+                    let (result, overflow) = self.get().overflowing_neg();
+                    // SAFETY: negation of nonzero cannot yield zero values.
+                    ((unsafe { $Ty::new_unchecked(result) }), overflow)
+                }
+
+                /// Saturating negation. Computes `-self`, returning `MAX` if
+                /// `self == i32::MIN` instead of overflowing.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_negation_ops)]
+                ///
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                #[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN + 1)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(pos_five.saturating_neg(), neg_five);
+                /// assert_eq!(min.saturating_neg(), max);
+                /// assert_eq!(max.saturating_neg(), min_plus_one);
+                /// # Some(())
+                /// # }
+                /// ```
+                #[inline]
+                #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+                pub const fn saturating_neg(self) -> $Ty {
+                    if let Some(result) = self.checked_neg() {
+                        return result;
+                    }
+                    $Ty::MAX
+                }
+
+                /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
+                /// of the type.
+                ///
+                #[doc = concat!("See [`", stringify!($Int), "::wrapping_neg`]")]
+                /// for documentation on overflow behaviour.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_negation_ops)]
+                ///
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                ///
+                /// assert_eq!(pos_five.wrapping_neg(), neg_five);
+                /// assert_eq!(min.wrapping_neg(), min);
+                /// # Some(())
+                /// # }
+                /// ```
+                #[inline]
+                #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+                pub const fn wrapping_neg(self) -> $Ty {
+                    let result = self.get().wrapping_neg();
+                    // SAFETY: negation of nonzero cannot yield zero values.
+                    unsafe { $Ty::new_unchecked(result) }
+                }
             }
         )+
     }
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
index 33df9e6c5cd..84a69046807 100644
--- a/library/core/src/ops/try_trait.rs
+++ b/library/core/src/ops/try_trait.rs
@@ -379,7 +379,7 @@ pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::
 pub(crate) struct NeverShortCircuit<T>(pub T);
 
 impl<T> NeverShortCircuit<T> {
-    /// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`.
+    /// Implementation for building `ConstFnMutClosure` for wrapping the output of a ~const FnMut in a `NeverShortCircuit`.
     #[inline]
     pub const fn wrap_mut_2_imp<A, B, F: ~const FnMut(A, B) -> T>(
         f: &mut F,
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 4a93df4591b..4b57371096e 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -559,22 +559,25 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(is_some_with)]
+    /// #![feature(is_some_and)]
     ///
     /// let x: Option<u32> = Some(2);
-    /// assert_eq!(x.is_some_and(|&x| x > 1), true);
+    /// assert_eq!(x.is_some_and(|x| x > 1), true);
     ///
     /// let x: Option<u32> = Some(0);
-    /// assert_eq!(x.is_some_and(|&x| x > 1), false);
+    /// assert_eq!(x.is_some_and(|x| x > 1), false);
     ///
     /// let x: Option<u32> = None;
-    /// assert_eq!(x.is_some_and(|&x| x > 1), false);
+    /// assert_eq!(x.is_some_and(|x| x > 1), false);
     /// ```
     #[must_use]
     #[inline]
-    #[unstable(feature = "is_some_with", issue = "93050")]
-    pub fn is_some_and(&self, f: impl FnOnce(&T) -> bool) -> bool {
-        matches!(self, Some(x) if f(x))
+    #[unstable(feature = "is_some_and", issue = "93050")]
+    pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
+        match self {
+            None => false,
+            Some(x) => f(x),
+        }
     }
 
     /// Returns `true` if the option is a [`None`] value.
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index dc90e90402c..3f33c5fd6ca 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -548,22 +548,25 @@ impl<T, E> Result<T, E> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(is_some_with)]
+    /// #![feature(is_some_and)]
     ///
     /// let x: Result<u32, &str> = Ok(2);
-    /// assert_eq!(x.is_ok_and(|&x| x > 1), true);
+    /// assert_eq!(x.is_ok_and(|x| x > 1), true);
     ///
     /// let x: Result<u32, &str> = Ok(0);
-    /// assert_eq!(x.is_ok_and(|&x| x > 1), false);
+    /// assert_eq!(x.is_ok_and(|x| x > 1), false);
     ///
     /// let x: Result<u32, &str> = Err("hey");
-    /// assert_eq!(x.is_ok_and(|&x| x > 1), false);
+    /// assert_eq!(x.is_ok_and(|x| x > 1), false);
     /// ```
     #[must_use]
     #[inline]
-    #[unstable(feature = "is_some_with", issue = "93050")]
-    pub fn is_ok_and(&self, f: impl FnOnce(&T) -> bool) -> bool {
-        matches!(self, Ok(x) if f(x))
+    #[unstable(feature = "is_some_and", issue = "93050")]
+    pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool {
+        match self {
+            Err(_) => false,
+            Ok(x) => f(x),
+        }
     }
 
     /// Returns `true` if the result is [`Err`].
@@ -592,7 +595,7 @@ impl<T, E> Result<T, E> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(is_some_with)]
+    /// #![feature(is_some_and)]
     /// use std::io::{Error, ErrorKind};
     ///
     /// let x: Result<u32, Error> = Err(Error::new(ErrorKind::NotFound, "!"));
@@ -606,9 +609,12 @@ impl<T, E> Result<T, E> {
     /// ```
     #[must_use]
     #[inline]
-    #[unstable(feature = "is_some_with", issue = "93050")]
-    pub fn is_err_and(&self, f: impl FnOnce(&E) -> bool) -> bool {
-        matches!(self, Err(x) if f(x))
+    #[unstable(feature = "is_some_and", issue = "93050")]
+    pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool {
+        match self {
+            Ok(_) => false,
+            Err(e) => f(e),
+        }
     }
 
     /////////////////////////////////////////////////////////////////////////
@@ -2066,9 +2072,6 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16.
     #[inline]
     fn from_iter<I: IntoIterator<Item = Result<A, E>>>(iter: I) -> Result<V, E> {
-        // FIXME(#11084): This could be replaced with Iterator::scan when this
-        // performance bug is closed.
-
         iter::try_process(iter.into_iter(), |i| i.collect())
     }
 }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index aed8fbf092e..56133f346ae 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -2426,15 +2426,20 @@ impl<T> [T] {
     where
         F: FnMut(&'a T) -> Ordering,
     {
+        // INVARIANTS:
+        // - 0 <= left <= left + size = right <= self.len()
+        // - f returns Less for everything in self[..left]
+        // - f returns Greater for everything in self[right..]
         let mut size = self.len();
         let mut left = 0;
         let mut right = size;
         while left < right {
             let mid = left + size / 2;
 
-            // SAFETY: the call is made safe by the following invariants:
-            // - `mid >= 0`
-            // - `mid < size`: `mid` is limited by `[left; right)` bound.
+            // SAFETY: the while condition means `size` is strictly positive, so
+            // `size/2 < size`.  Thus `left + size/2 < left + size`, which
+            // coupled with the `left + size <= self.len()` invariant means
+            // we have `left + size/2 < self.len()`, and this is in-bounds.
             let cmp = f(unsafe { self.get_unchecked(mid) });
 
             // The reason why we use if/else control flow rather than match
@@ -2452,6 +2457,10 @@ impl<T> [T] {
 
             size = right - left;
         }
+
+        // SAFETY: directly true from the overall invariant.
+        // Note that this is `<=`, unlike the assume in the `Ok` path.
+        unsafe { crate::intrinsics::assume(left <= self.len()) };
         Err(left)
     }
 
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index f1e8bc79bf4..3c5abd215a4 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -188,6 +188,10 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
 ///
 /// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements.
 ///
+/// # Panics
+///
+/// This function panics if `T` is a Zero-Sized Type (“ZST”).
+///
 /// # Caveat
 ///
 /// The lifetime for the returned slice is inferred from its usage. To
@@ -219,9 +223,15 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
     unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
 }
 
-/// Performs the same functionality as [`from_ptr_range`], except that a
+/// Forms a mutable slice from a pointer range.
+///
+/// This is the same functionality as [`from_ptr_range`], except that a
 /// mutable slice is returned.
 ///
+/// This function is useful for interacting with foreign interfaces which
+/// use two pointers to refer to a range of elements in memory, as is
+/// common in C++.
+///
 /// # Safety
 ///
 /// Behavior is undefined if any of the following conditions are violated:
@@ -247,6 +257,18 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
 ///
 /// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements.
 ///
+/// # Panics
+///
+/// This function panics if `T` is a Zero-Sized Type (“ZST”).
+///
+/// # Caveat
+///
+/// The lifetime for the returned slice is inferred from its usage. To
+/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
+/// source lifetime is safe in the context, such as by providing a helper
+/// function taking the lifetime of a host value for the slice, or by explicit
+/// annotation.
+///
 /// # Examples
 ///
 /// ```
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 18f2ce6edc7..d3ed811b157 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -507,7 +507,6 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
 ///
 /// ```
 /// use std::str::FromStr;
-/// use std::num::ParseIntError;
 ///
 /// #[derive(Debug, PartialEq)]
 /// struct Point {
@@ -515,18 +514,21 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
 ///     y: i32
 /// }
 ///
+/// #[derive(Debug, PartialEq, Eq)]
+/// struct ParsePointError;
+///
 /// impl FromStr for Point {
-///     type Err = ParseIntError;
+///     type Err = ParsePointError;
 ///
 ///     fn from_str(s: &str) -> Result<Self, Self::Err> {
 ///         let (x, y) = s
 ///             .strip_prefix('(')
 ///             .and_then(|s| s.strip_suffix(')'))
 ///             .and_then(|s| s.split_once(','))
-///             .unwrap();
+///             .ok_or(ParsePointError)?;
 ///
-///         let x_fromstr = x.parse::<i32>()?;
-///         let y_fromstr = y.parse::<i32>()?;
+///         let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?;
+///         let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?;
 ///
 ///         Ok(Point { x: x_fromstr, y: y_fromstr })
 ///     }
@@ -538,6 +540,8 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
 /// // Implicit calls, through parse
 /// assert_eq!("(1,2)".parse(), expected);
 /// assert_eq!("(1,2)".parse::<Point>(), expected);
+/// // Invalid input string
+/// assert!(Point::from_str("(1 2)").is_err());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait FromStr: Sized {
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 4f29ecc0fba..1d0c51c3c83 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -29,6 +29,20 @@ const NANOS_PER_MICRO: u32 = 1_000;
 const MILLIS_PER_SEC: u64 = 1_000;
 const MICROS_PER_SEC: u64 = 1_000_000;
 
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(999_999_999)]
+struct Nanoseconds(u32);
+
+impl Default for Nanoseconds {
+    #[inline]
+    fn default() -> Self {
+        // SAFETY: 0 is within the valid range
+        unsafe { Nanoseconds(0) }
+    }
+}
+
 /// A `Duration` type to represent a span of time, typically used for system
 /// timeouts.
 ///
@@ -71,7 +85,7 @@ const MICROS_PER_SEC: u64 = 1_000_000;
 #[cfg_attr(not(test), rustc_diagnostic_item = "Duration")]
 pub struct Duration {
     secs: u64,
-    nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
+    nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC
 }
 
 impl Duration {
@@ -188,7 +202,8 @@ impl Duration {
             None => panic!("overflow in Duration::new"),
         };
         let nanos = nanos % NANOS_PER_SEC;
-        Duration { secs, nanos }
+        // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
+        Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
     }
 
     /// Creates a new `Duration` from the specified number of whole seconds.
@@ -208,7 +223,7 @@ impl Duration {
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_secs(secs: u64) -> Duration {
-        Duration { secs, nanos: 0 }
+        Duration::new(secs, 0)
     }
 
     /// Creates a new `Duration` from the specified number of milliseconds.
@@ -228,10 +243,7 @@ impl Duration {
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_millis(millis: u64) -> Duration {
-        Duration {
-            secs: millis / MILLIS_PER_SEC,
-            nanos: ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI,
-        }
+        Duration::new(millis / MILLIS_PER_SEC, ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI)
     }
 
     /// Creates a new `Duration` from the specified number of microseconds.
@@ -251,10 +263,7 @@ impl Duration {
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_micros(micros: u64) -> Duration {
-        Duration {
-            secs: micros / MICROS_PER_SEC,
-            nanos: ((micros % MICROS_PER_SEC) as u32) * NANOS_PER_MICRO,
-        }
+        Duration::new(micros / MICROS_PER_SEC, ((micros % MICROS_PER_SEC) as u32) * NANOS_PER_MICRO)
     }
 
     /// Creates a new `Duration` from the specified number of nanoseconds.
@@ -274,10 +283,7 @@ impl Duration {
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_nanos(nanos: u64) -> Duration {
-        Duration {
-            secs: nanos / (NANOS_PER_SEC as u64),
-            nanos: (nanos % (NANOS_PER_SEC as u64)) as u32,
-        }
+        Duration::new(nanos / (NANOS_PER_SEC as u64), (nanos % (NANOS_PER_SEC as u64)) as u32)
     }
 
     /// Returns true if this `Duration` spans no time.
@@ -301,7 +307,7 @@ impl Duration {
     #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")]
     #[inline]
     pub const fn is_zero(&self) -> bool {
-        self.secs == 0 && self.nanos == 0
+        self.secs == 0 && self.nanos.0 == 0
     }
 
     /// Returns the number of _whole_ seconds contained by this `Duration`.
@@ -352,7 +358,7 @@ impl Duration {
     #[must_use]
     #[inline]
     pub const fn subsec_millis(&self) -> u32 {
-        self.nanos / NANOS_PER_MILLI
+        self.nanos.0 / NANOS_PER_MILLI
     }
 
     /// Returns the fractional part of this `Duration`, in whole microseconds.
@@ -375,7 +381,7 @@ impl Duration {
     #[must_use]
     #[inline]
     pub const fn subsec_micros(&self) -> u32 {
-        self.nanos / NANOS_PER_MICRO
+        self.nanos.0 / NANOS_PER_MICRO
     }
 
     /// Returns the fractional part of this `Duration`, in nanoseconds.
@@ -398,7 +404,7 @@ impl Duration {
     #[must_use]
     #[inline]
     pub const fn subsec_nanos(&self) -> u32 {
-        self.nanos
+        self.nanos.0
     }
 
     /// Returns the total number of whole milliseconds contained by this `Duration`.
@@ -416,7 +422,7 @@ impl Duration {
     #[must_use]
     #[inline]
     pub const fn as_millis(&self) -> u128 {
-        self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
+        self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MILLI) as u128
     }
 
     /// Returns the total number of whole microseconds contained by this `Duration`.
@@ -434,7 +440,7 @@ impl Duration {
     #[must_use]
     #[inline]
     pub const fn as_micros(&self) -> u128 {
-        self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
+        self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MICRO) as u128
     }
 
     /// Returns the total number of nanoseconds contained by this `Duration`.
@@ -452,7 +458,7 @@ impl Duration {
     #[must_use]
     #[inline]
     pub const fn as_nanos(&self) -> u128 {
-        self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
+        self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.0 as u128
     }
 
     /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
@@ -475,7 +481,7 @@ impl Duration {
     #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
     pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
         if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
-            let mut nanos = self.nanos + rhs.nanos;
+            let mut nanos = self.nanos.0 + rhs.nanos.0;
             if nanos >= NANOS_PER_SEC {
                 nanos -= NANOS_PER_SEC;
                 if let Some(new_secs) = secs.checked_add(1) {
@@ -485,7 +491,7 @@ impl Duration {
                 }
             }
             debug_assert!(nanos < NANOS_PER_SEC);
-            Some(Duration { secs, nanos })
+            Some(Duration::new(secs, nanos))
         } else {
             None
         }
@@ -535,16 +541,16 @@ impl Duration {
     #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
     pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
         if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
-            let nanos = if self.nanos >= rhs.nanos {
-                self.nanos - rhs.nanos
+            let nanos = if self.nanos.0 >= rhs.nanos.0 {
+                self.nanos.0 - rhs.nanos.0
             } else if let Some(sub_secs) = secs.checked_sub(1) {
                 secs = sub_secs;
-                self.nanos + NANOS_PER_SEC - rhs.nanos
+                self.nanos.0 + NANOS_PER_SEC - rhs.nanos.0
             } else {
                 return None;
             };
             debug_assert!(nanos < NANOS_PER_SEC);
-            Some(Duration { secs, nanos })
+            Some(Duration::new(secs, nanos))
         } else {
             None
         }
@@ -593,13 +599,13 @@ impl Duration {
     #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
     pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
         // Multiply nanoseconds as u64, because it cannot overflow that way.
-        let total_nanos = self.nanos as u64 * rhs as u64;
+        let total_nanos = self.nanos.0 as u64 * rhs as u64;
         let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
         let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
         if let Some(s) = self.secs.checked_mul(rhs as u64) {
             if let Some(secs) = s.checked_add(extra_secs) {
                 debug_assert!(nanos < NANOS_PER_SEC);
-                return Some(Duration { secs, nanos });
+                return Some(Duration::new(secs, nanos));
             }
         }
         None
@@ -653,9 +659,9 @@ impl Duration {
             let secs = self.secs / (rhs as u64);
             let carry = self.secs - secs * (rhs as u64);
             let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
-            let nanos = self.nanos / rhs + (extra_nanos as u32);
+            let nanos = self.nanos.0 / rhs + (extra_nanos as u32);
             debug_assert!(nanos < NANOS_PER_SEC);
-            Some(Duration { secs, nanos })
+            Some(Duration::new(secs, nanos))
         } else {
             None
         }
@@ -677,7 +683,7 @@ impl Duration {
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
     pub const fn as_secs_f64(&self) -> f64 {
-        (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
+        (self.secs as f64) + (self.nanos.0 as f64) / (NANOS_PER_SEC as f64)
     }
 
     /// Returns the number of seconds contained by this `Duration` as `f32`.
@@ -696,7 +702,7 @@ impl Duration {
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
     pub const fn as_secs_f32(&self) -> f32 {
-        (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
+        (self.secs as f32) + (self.nanos.0 as f32) / (NANOS_PER_SEC as f32)
     }
 
     /// Creates a new `Duration` from the specified number of seconds represented
@@ -987,13 +993,13 @@ macro_rules! sum_durations {
         for entry in $iter {
             total_secs =
                 total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
-            total_nanos = match total_nanos.checked_add(entry.nanos as u64) {
+            total_nanos = match total_nanos.checked_add(entry.nanos.0 as u64) {
                 Some(n) => n,
                 None => {
                     total_secs = total_secs
                         .checked_add(total_nanos / NANOS_PER_SEC as u64)
                         .expect("overflow in iter::sum over durations");
-                    (total_nanos % NANOS_PER_SEC as u64) + entry.nanos as u64
+                    (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.0 as u64
                 }
             };
         }
@@ -1001,7 +1007,7 @@ macro_rules! sum_durations {
             .checked_add(total_nanos / NANOS_PER_SEC as u64)
             .expect("overflow in iter::sum over durations");
         total_nanos = total_nanos % NANOS_PER_SEC as u64;
-        Duration { secs: total_secs, nanos: total_nanos as u32 }
+        Duration::new(total_secs, total_nanos as u32)
     }};
 }
 
@@ -1037,7 +1043,7 @@ impl fmt::Debug for Duration {
         /// to the formatter's `width`, if specified.
         fn fmt_decimal(
             f: &mut fmt::Formatter<'_>,
-            mut integer_part: u64,
+            integer_part: u64,
             mut fractional_part: u32,
             mut divisor: u32,
             prefix: &str,
@@ -1069,7 +1075,7 @@ impl fmt::Debug for Duration {
             // normal floating point numbers. However, we only need to do work
             // when rounding up. This happens if the first digit of the
             // remaining ones is >= 5.
-            if fractional_part > 0 && fractional_part >= divisor * 5 {
+            let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
                 // Round up the number contained in the buffer. We go through
                 // the buffer backwards and keep track of the carry.
                 let mut rev_pos = pos;
@@ -1093,9 +1099,18 @@ impl fmt::Debug for Duration {
                 // the whole buffer to '0's and need to increment the integer
                 // part.
                 if carry {
-                    integer_part += 1;
+                    // If `integer_part == u64::MAX` and precision < 9, any
+                    // carry of the overflow during rounding of the
+                    // `fractional_part` into the `integer_part` will cause the
+                    // `integer_part` itself to overflow. Avoid this by using an
+                    // `Option<u64>`, with `None` representing `u64::MAX + 1`.
+                    integer_part.checked_add(1)
+                } else {
+                    Some(integer_part)
                 }
-            }
+            } else {
+                Some(integer_part)
+            };
 
             // Determine the end of the buffer: if precision is set, we just
             // use as many digits from the buffer (capped to 9). If it isn't
@@ -1105,7 +1120,12 @@ impl fmt::Debug for Duration {
             // This closure emits the formatted duration without emitting any
             // padding (padding is calculated below).
             let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
-                write!(f, "{}{}", prefix, integer_part)?;
+                if let Some(integer_part) = integer_part {
+                    write!(f, "{}{}", prefix, integer_part)?;
+                } else {
+                    // u64::MAX + 1 == 18446744073709551616
+                    write!(f, "{}18446744073709551616", prefix)?;
+                }
 
                 // Write the decimal point and the fractional part (if any).
                 if end > 0 {
@@ -1135,12 +1155,17 @@ impl fmt::Debug for Duration {
                     // 2. The postfix: can be "µs" so we have to count UTF8 characters.
                     let mut actual_w = prefix.len() + postfix.chars().count();
                     // 3. The integer part:
-                    if let Some(log) = integer_part.checked_ilog10() {
-                        // integer_part is > 0, so has length log10(x)+1
-                        actual_w += 1 + log as usize;
+                    if let Some(integer_part) = integer_part {
+                        if let Some(log) = integer_part.checked_ilog10() {
+                            // integer_part is > 0, so has length log10(x)+1
+                            actual_w += 1 + log as usize;
+                        } else {
+                            // integer_part is 0, so has length 1.
+                            actual_w += 1;
+                        }
                     } else {
-                        // integer_part is 0, so has length 1.
-                        actual_w += 1;
+                        // integer_part is u64::MAX + 1, so has length 20
+                        actual_w += 20;
                     }
                     // 4. The fractional part (if any):
                     if end > 0 {
@@ -1166,27 +1191,27 @@ impl fmt::Debug for Duration {
         let prefix = if f.sign_plus() { "+" } else { "" };
 
         if self.secs > 0 {
-            fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10, prefix, "s")
-        } else if self.nanos >= NANOS_PER_MILLI {
+            fmt_decimal(f, self.secs, self.nanos.0, NANOS_PER_SEC / 10, prefix, "s")
+        } else if self.nanos.0 >= NANOS_PER_MILLI {
             fmt_decimal(
                 f,
-                (self.nanos / NANOS_PER_MILLI) as u64,
-                self.nanos % NANOS_PER_MILLI,
+                (self.nanos.0 / NANOS_PER_MILLI) as u64,
+                self.nanos.0 % NANOS_PER_MILLI,
                 NANOS_PER_MILLI / 10,
                 prefix,
                 "ms",
             )
-        } else if self.nanos >= NANOS_PER_MICRO {
+        } else if self.nanos.0 >= NANOS_PER_MICRO {
             fmt_decimal(
                 f,
-                (self.nanos / NANOS_PER_MICRO) as u64,
-                self.nanos % NANOS_PER_MICRO,
+                (self.nanos.0 / NANOS_PER_MICRO) as u64,
+                self.nanos.0 % NANOS_PER_MICRO,
                 NANOS_PER_MICRO / 10,
                 prefix,
                 "µs",
             )
         } else {
-            fmt_decimal(f, self.nanos as u64, 0, 1, prefix, "ns")
+            fmt_decimal(f, self.nanos.0 as u64, 0, 1, prefix, "ns")
         }
     }
 }
@@ -1317,7 +1342,7 @@ macro_rules! try_from_secs {
             return Err(FromFloatSecsError { kind: FromFloatSecsErrorKind::OverflowOrNan });
         };
 
-        Ok(Duration { secs, nanos })
+        Ok(Duration::new(secs, nanos))
     }};
 }
 
diff --git a/library/core/tests/ascii.rs b/library/core/tests/ascii.rs
index 6d2cf3e83bc..f5f2dd04778 100644
--- a/library/core/tests/ascii.rs
+++ b/library/core/tests/ascii.rs
@@ -252,6 +252,23 @@ fn test_is_ascii_digit() {
 }
 
 #[test]
+fn test_is_ascii_octdigit() {
+    assert_all!(is_ascii_octdigit, "", "01234567");
+    assert_none!(
+        is_ascii_octdigit,
+        "abcdefghijklmnopqrstuvwxyz",
+        "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
+        "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+        " \t\n\x0c\r",
+        "\x00\x01\x02\x03\x04\x05\x06\x07",
+        "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+        "\x10\x11\x12\x13\x14\x15\x16\x17",
+        "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+        "\x7f",
+    );
+}
+
+#[test]
 fn test_is_ascii_hexdigit() {
     assert_all!(is_ascii_hexdigit, "", "0123456789", "abcdefABCDEF",);
     assert_none!(
@@ -454,6 +471,7 @@ fn ascii_ctype_const() {
         is_ascii_lowercase    => [true,  false, false, false, false];
         is_ascii_alphanumeric => [true,  true,  true,  false, false];
         is_ascii_digit        => [false, false, true,  false, false];
+        is_ascii_octdigit     => [false, false, false, false, false];
         is_ascii_hexdigit     => [true,  true,  true,  false, false];
         is_ascii_punctuation  => [false, false, false, true,  false];
         is_ascii_graphic      => [true,  true,  true,  true,  false];
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 6d58ed9743d..ca0c7a54b3e 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -100,6 +100,7 @@
 #![feature(slice_flatten)]
 #![feature(provide_any)]
 #![feature(utf8_chunks)]
+#![feature(is_ascii_octdigit)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;
diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs
index fe2d2f2412d..697bf33a8b0 100644
--- a/library/core/tests/time.rs
+++ b/library/core/tests/time.rs
@@ -197,9 +197,31 @@ fn correct_sum() {
 #[test]
 fn debug_formatting_extreme_values() {
     assert_eq!(
-        format!("{:?}", Duration::new(18_446_744_073_709_551_615, 123_456_789)),
+        format!("{:?}", Duration::new(u64::MAX, 123_456_789)),
         "18446744073709551615.123456789s"
     );
+    assert_eq!(format!("{:.0?}", Duration::MAX), "18446744073709551616s");
+    assert_eq!(format!("{:.0?}", Duration::new(u64::MAX, 500_000_000)), "18446744073709551616s");
+    assert_eq!(format!("{:.0?}", Duration::new(u64::MAX, 499_999_999)), "18446744073709551615s");
+    assert_eq!(
+        format!("{:.3?}", Duration::new(u64::MAX, 999_500_000)),
+        "18446744073709551616.000s"
+    );
+    assert_eq!(
+        format!("{:.3?}", Duration::new(u64::MAX, 999_499_999)),
+        "18446744073709551615.999s"
+    );
+    assert_eq!(
+        format!("{:.8?}", Duration::new(u64::MAX, 999_999_995)),
+        "18446744073709551616.00000000s"
+    );
+    assert_eq!(
+        format!("{:.8?}", Duration::new(u64::MAX, 999_999_994)),
+        "18446744073709551615.99999999s"
+    );
+    assert_eq!(format!("{:21.0?}", Duration::MAX), "18446744073709551616s");
+    assert_eq!(format!("{:22.0?}", Duration::MAX), "18446744073709551616s ");
+    assert_eq!(format!("{:24.0?}", Duration::MAX), "18446744073709551616s   ");
 }
 
 #[test]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index d2db4bb7a46..34983b976e3 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -280,7 +280,8 @@ impl<K, V, S> HashMap<K, V, S> {
     /// ```
     #[inline]
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
+    #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")]
+    pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
         HashMap { base: base::HashMap::with_hasher(hash_builder) }
     }
 
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index cb3032719fa..65634f2063f 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -1115,3 +1115,9 @@ fn from_array() {
     // that's a problem!
     let _must_not_require_type_annotation = HashMap::from([(1, 2)]);
 }
+
+#[test]
+fn const_with_hasher() {
+    const X: HashMap<(), (), ()> = HashMap::with_hasher(());
+    assert_eq!(X.len(), 0);
+}
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 5b6a415fadc..c36eeae3388 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -376,7 +376,8 @@ impl<T, S> HashSet<T, S> {
     /// ```
     #[inline]
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
-    pub fn with_hasher(hasher: S) -> HashSet<T, S> {
+    #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")]
+    pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
         HashSet { base: base::HashSet::with_hasher(hasher) }
     }
 
diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs
index 233db276b9e..941a0450cc7 100644
--- a/library/std/src/collections/hash/set/tests.rs
+++ b/library/std/src/collections/hash/set/tests.rs
@@ -496,3 +496,9 @@ fn from_array() {
     // that's a problem!
     let _must_not_require_type_annotation = HashSet::from([1, 2]);
 }
+
+#[test]
+fn const_with_hasher() {
+    const X: HashSet<(), ()> = HashSet::with_hasher(());
+    assert_eq!(X.len(), 0);
+}
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 463f714064c..6eb7cbea626 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -603,7 +603,7 @@ pub fn home_dir() -> Option<PathBuf> {
 /// # Platform-specific behavior
 ///
 /// On Unix, returns the value of the `TMPDIR` environment variable if it is
-/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
+/// set, otherwise for non-Android it returns `/tmp`. On Android, since there
 /// is no global temporary folder (it is usually allocated per-app), it returns
 /// `/data/local/tmp`.
 /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 64b62fd3bba..a497acda4f6 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -251,6 +251,7 @@
 #![feature(doc_notable_trait)]
 #![feature(dropck_eyepatch)]
 #![feature(exhaustive_patterns)]
+#![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
 #![feature(lang_items)]
 #![feature(let_chains)]
@@ -291,7 +292,7 @@
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(int_error_internals)]
-#![feature(is_some_with)]
+#![feature(is_some_and)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_write_slice)]
 #![feature(nonnull_slice_from_raw_parts)]
@@ -350,6 +351,7 @@
 // Only used in tests/benchmarks:
 //
 // Only for const-ness:
+#![feature(const_collections_with_hasher)]
 #![feature(const_io_structs)]
 #![feature(const_ip)]
 #![feature(const_ipv4)]
diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs
index a456947534a..c6aa7c77dbc 100644
--- a/library/std/src/os/fd/mod.rs
+++ b/library/std/src/os/fd/mod.rs
@@ -1,16 +1,25 @@
 //! Owned and borrowed Unix-like file descriptors.
+//!
+//! This module is supported on Unix platforms and WASI, which both use a
+//! similar file descriptor system for referencing OS resources.
 
 #![stable(feature = "io_safety", since = "1.63.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 // `RawFd`, `AsRawFd`, etc.
-pub mod raw;
+mod raw;
 
 // `OwnedFd`, `AsFd`, etc.
-pub mod owned;
+mod owned;
 
 // Implementations for `AsRawFd` etc. for network types.
 mod net;
 
 #[cfg(test)]
 mod tests;
+
+// Export the types and traits for the public API.
+#[unstable(feature = "os_fd", issue = "98699")]
+pub use owned::*;
+#[unstable(feature = "os_fd", issue = "98699")]
+pub use raw::*;
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 71e33fb9ed8..9875c389d8a 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -206,10 +206,8 @@ pub trait AsFd {
     /// ```rust,no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// # #[cfg(target_os = "wasi")]
-    /// # use std::os::wasi::io::{AsFd, BorrowedFd};
-    /// # #[cfg(unix)]
-    /// # use std::os::unix::io::{AsFd, BorrowedFd};
+    /// # #[cfg(any(unix, target_os = "wasi"))]
+    /// # use std::os::fd::{AsFd, BorrowedFd};
     ///
     /// let mut f = File::open("foo.txt")?;
     /// # #[cfg(any(unix, target_os = "wasi"))]
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index 1b3d110426f..f92a0506670 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -42,10 +42,8 @@ pub trait AsRawFd {
     /// ```no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// #[cfg(unix)]
-    /// use std::os::unix::io::{AsRawFd, RawFd};
-    /// #[cfg(target_os = "wasi")]
-    /// use std::os::wasi::io::{AsRawFd, RawFd};
+    /// #[cfg(any(unix, target_os = "wasi"))]
+    /// use std::os::fd::{AsRawFd, RawFd};
     ///
     /// let mut f = File::open("foo.txt")?;
     /// // Note that `raw_fd` is only valid as long as `f` exists.
@@ -83,10 +81,8 @@ pub trait FromRawFd {
     /// ```no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// #[cfg(unix)]
-    /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
-    /// #[cfg(target_os = "wasi")]
-    /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd};
+    /// #[cfg(any(unix, target_os = "wasi"))]
+    /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd};
     ///
     /// let f = File::open("foo.txt")?;
     /// # #[cfg(any(unix, target_os = "wasi"))]
@@ -121,10 +117,8 @@ pub trait IntoRawFd {
     /// ```no_run
     /// use std::fs::File;
     /// # use std::io;
-    /// #[cfg(unix)]
-    /// use std::os::unix::io::{IntoRawFd, RawFd};
-    /// #[cfg(target_os = "wasi")]
-    /// use std::os::wasi::io::{IntoRawFd, RawFd};
+    /// #[cfg(any(unix, target_os = "wasi"))]
+    /// use std::os::fd::{IntoRawFd, RawFd};
     ///
     /// let f = File::open("foo.txt")?;
     /// #[cfg(any(unix, target_os = "wasi"))]
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 18c64b51007..f62f5af774f 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -147,7 +147,7 @@ pub mod solid;
 pub mod vxworks;
 
 #[cfg(any(unix, target_os = "wasi", doc))]
-mod fd;
+pub mod fd;
 
 #[cfg(any(target_os = "linux", target_os = "android", doc))]
 mod net;
diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs
deleted file mode 100644
index d4cb696459b..00000000000
--- a/library/std/src/os/unix/io/fd.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//! Owned and borrowed file descriptors.
-
-// Tests for this module
-#[cfg(test)]
-mod tests;
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-pub use crate::os::fd::owned::*;
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index 3ab5606f889..25b5dbff14f 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -77,10 +77,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-mod fd;
-mod raw;
-
-#[stable(feature = "io_safety", since = "1.63.0")]
-pub use fd::*;
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use raw::*;
+pub use crate::os::fd::*;
+
+// Tests for this module
+#[cfg(test)]
+mod tests;
diff --git a/library/std/src/os/unix/io/raw.rs b/library/std/src/os/unix/io/raw.rs
deleted file mode 100644
index a4d2ba797d9..00000000000
--- a/library/std/src/os/unix/io/raw.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//! Unix-specific extensions to general I/O primitives.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use crate::os::fd::raw::*;
diff --git a/library/std/src/os/unix/io/fd/tests.rs b/library/std/src/os/unix/io/tests.rs
index 84d2a7a1a91..84d2a7a1a91 100644
--- a/library/std/src/os/unix/io/fd/tests.rs
+++ b/library/std/src/os/unix/io/tests.rs
diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs
index 6c884e2eaf4..d528590d75b 100644
--- a/library/std/src/os/wasi/io/mod.rs
+++ b/library/std/src/os/wasi/io/mod.rs
@@ -1,12 +1,6 @@
 //! WASI-specific extensions to general I/O primitives.
 
-#![deny(unsafe_op_in_unsafe_fn)]
 #![unstable(feature = "wasi_ext", issue = "71213")]
 
-mod fd;
-mod raw;
-
-#[unstable(feature = "wasi_ext", issue = "71213")]
-pub use fd::*;
 #[unstable(feature = "wasi_ext", issue = "71213")]
-pub use raw::*;
+pub use crate::os::fd::*;
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index cc347e3586a..57c7bf6a28b 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -313,8 +313,11 @@ pub struct FilePermissions {
     mode: mode_t,
 }
 
-#[derive(Copy, Clone)]
-pub struct FileTimes([libc::timespec; 2]);
+#[derive(Copy, Clone, Debug, Default)]
+pub struct FileTimes {
+    accessed: Option<SystemTime>,
+    modified: Option<SystemTime>,
+}
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType {
@@ -512,45 +515,11 @@ impl FilePermissions {
 
 impl FileTimes {
     pub fn set_accessed(&mut self, t: SystemTime) {
-        self.0[0] = t.t.to_timespec().expect("Invalid system time");
+        self.accessed = Some(t);
     }
 
     pub fn set_modified(&mut self, t: SystemTime) {
-        self.0[1] = t.t.to_timespec().expect("Invalid system time");
-    }
-}
-
-struct TimespecDebugAdapter<'a>(&'a libc::timespec);
-
-impl fmt::Debug for TimespecDebugAdapter<'_> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("timespec")
-            .field("tv_sec", &self.0.tv_sec)
-            .field("tv_nsec", &self.0.tv_nsec)
-            .finish()
-    }
-}
-
-impl fmt::Debug for FileTimes {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("FileTimes")
-            .field("accessed", &TimespecDebugAdapter(&self.0[0]))
-            .field("modified", &TimespecDebugAdapter(&self.0[1]))
-            .finish()
-    }
-}
-
-impl Default for FileTimes {
-    fn default() -> Self {
-        // Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return
-        // an error in `set_times`.
-        // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
-        // the same as for Redox.
-        #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))]
-        let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 };
-        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
-        let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ };
-        Self([omit; 2])
+        self.modified = Some(t);
     }
 }
 
@@ -1084,6 +1053,17 @@ impl File {
     }
 
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
+        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
+        let to_timespec = |time: Option<SystemTime>| {
+            match time {
+                Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
+                Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
+                Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time")),
+                None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
+            }
+        };
+        #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
+        let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
         cfg_if::cfg_if! {
             if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
                 // Redox doesn't appear to support `UTIME_OMIT`.
@@ -1099,7 +1079,7 @@ impl File {
                 cvt(unsafe {
                     weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
                     match futimens.get() {
-                        Some(futimens) => futimens(self.as_raw_fd(), times.0.as_ptr()),
+                        Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()),
                         #[cfg(target_os = "macos")]
                         None => {
                             fn ts_to_tv(ts: &libc::timespec) -> libc::timeval {
@@ -1108,7 +1088,7 @@ impl File {
                                     tv_usec: (ts.tv_nsec / 1000) as _
                                 }
                             }
-                            let timevals = [ts_to_tv(&times.0[0]), ts_to_tv(&times.0[1])];
+                            let timevals = [ts_to_tv(&times[0]), ts_to_tv(&times[1])];
                             libc::futimes(self.as_raw_fd(), timevals.as_ptr())
                         }
                         // futimes requires even newer Android.
@@ -1121,7 +1101,7 @@ impl File {
                 })?;
                 Ok(())
             } else {
-                cvt(unsafe { libc::futimens(self.as_raw_fd(), times.0.as_ptr()) })?;
+                cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?;
                 Ok(())
             }
         }
diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs
index dff973f59d1..cca9c676701 100644
--- a/library/std/src/sys/unix/time.rs
+++ b/library/std/src/sys/unix/time.rs
@@ -7,6 +7,12 @@ const NSEC_PER_SEC: u64 = 1_000_000_000;
 pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(999_999_999)]
+struct Nanoseconds(u32);
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct SystemTime {
     pub(in crate::sys::unix) t: Timespec,
 }
@@ -14,7 +20,7 @@ pub struct SystemTime {
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub(in crate::sys::unix) struct Timespec {
     tv_sec: i64,
-    tv_nsec: i64,
+    tv_nsec: Nanoseconds,
 }
 
 impl SystemTime {
@@ -46,18 +52,20 @@ impl fmt::Debug for SystemTime {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.tv_sec)
-            .field("tv_nsec", &self.t.tv_nsec)
+            .field("tv_nsec", &self.t.tv_nsec.0)
             .finish()
     }
 }
 
 impl Timespec {
     pub const fn zero() -> Timespec {
-        Timespec { tv_sec: 0, tv_nsec: 0 }
+        Timespec::new(0, 0)
     }
 
-    fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
-        Timespec { tv_sec, tv_nsec }
+    const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
+        assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
+        // SAFETY: The assert above checks tv_nsec is within the valid range
+        Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } }
     }
 
     pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
@@ -75,12 +83,12 @@ impl Timespec {
             //
             // Ideally this code could be rearranged such that it more
             // directly expresses the lower-cost behavior we want from it.
-            let (secs, nsec) = if self.tv_nsec >= other.tv_nsec {
-                ((self.tv_sec - other.tv_sec) as u64, (self.tv_nsec - other.tv_nsec) as u32)
+            let (secs, nsec) = if self.tv_nsec.0 >= other.tv_nsec.0 {
+                ((self.tv_sec - other.tv_sec) as u64, self.tv_nsec.0 - other.tv_nsec.0)
             } else {
                 (
                     (self.tv_sec - other.tv_sec - 1) as u64,
-                    self.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.tv_nsec as u32,
+                    self.tv_nsec.0 + (NSEC_PER_SEC as u32) - other.tv_nsec.0,
                 )
             };
 
@@ -102,7 +110,7 @@ impl Timespec {
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
-        let mut nsec = other.subsec_nanos() + self.tv_nsec as u32;
+        let mut nsec = other.subsec_nanos() + self.tv_nsec.0;
         if nsec >= NSEC_PER_SEC as u32 {
             nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
@@ -118,7 +126,7 @@ impl Timespec {
             .and_then(|secs| self.tv_sec.checked_sub(secs))?;
 
         // Similar to above, nanos can't overflow.
-        let mut nsec = self.tv_nsec as i32 - other.subsec_nanos() as i32;
+        let mut nsec = self.tv_nsec.0 as i32 - other.subsec_nanos() as i32;
         if nsec < 0 {
             nsec += NSEC_PER_SEC as i32;
             secs = secs.checked_sub(1)?;
@@ -130,7 +138,7 @@ impl Timespec {
     pub fn to_timespec(&self) -> Option<libc::timespec> {
         Some(libc::timespec {
             tv_sec: self.tv_sec.try_into().ok()?,
-            tv_nsec: self.tv_nsec.try_into().ok()?,
+            tv_nsec: self.tv_nsec.0.try_into().ok()?,
         })
     }
 }
@@ -293,7 +301,7 @@ mod inner {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             f.debug_struct("Instant")
                 .field("tv_sec", &self.t.tv_sec)
-                .field("tv_nsec", &self.t.tv_nsec)
+                .field("tv_nsec", &self.t.tv_nsec.0)
                 .finish()
         }
     }
@@ -334,7 +342,7 @@ mod inner {
                     let mut t = MaybeUninit::uninit();
                     cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
                     let t = unsafe { t.assume_init() };
-                    return Timespec { tv_sec: t.tv_sec, tv_nsec: t.tv_nsec as i64 };
+                    return Timespec::new(t.tv_sec, t.tv_nsec as i64);
                 }
             }
 
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 510cf36b1bf..953fbeb8395 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -65,8 +65,8 @@ pub struct FilePermissions {
 
 #[derive(Copy, Clone, Debug, Default)]
 pub struct FileTimes {
-    accessed: Option<wasi::Timestamp>,
-    modified: Option<wasi::Timestamp>,
+    accessed: Option<SystemTime>,
+    modified: Option<SystemTime>,
 }
 
 #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
@@ -120,11 +120,11 @@ impl FilePermissions {
 
 impl FileTimes {
     pub fn set_accessed(&mut self, t: SystemTime) {
-        self.accessed = Some(t.to_wasi_timestamp_or_panic());
+        self.accessed = Some(t);
     }
 
     pub fn set_modified(&mut self, t: SystemTime) {
-        self.modified = Some(t.to_wasi_timestamp_or_panic());
+        self.modified = Some(t);
     }
 }
 
@@ -476,9 +476,16 @@ impl File {
     }
 
     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
+        let to_timestamp = |time: Option<SystemTime>| {
+            match time {
+                Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
+                Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
+                None => Ok(0),
+            }
+        };
         self.fd.filestat_set_times(
-            times.accessed.unwrap_or(0),
-            times.modified.unwrap_or(0),
+            to_timestamp(times.accessed)?,
+            to_timestamp(times.modified)?,
             times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM)
                 | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM),
         )
diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs
index d2081771b6e..bf045c7841f 100644
--- a/library/std/src/sys/wasi/stdio.rs
+++ b/library/std/src/sys/wasi/stdio.rs
@@ -30,6 +30,15 @@ impl AsFd for Stdin {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl<'a> AsFd for io::StdinLock<'a> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: user code should not close stdin out from under the standard library
+        unsafe { BorrowedFd::borrow_raw(0) }
+    }
+}
+
 impl io::Read for Stdin {
     fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
         self.read_vectored(&mut [IoSliceMut::new(data)])
@@ -65,6 +74,15 @@ impl AsFd for Stdout {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl<'a> AsFd for io::StdoutLock<'a> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: user code should not close stdout out from under the standard library
+        unsafe { BorrowedFd::borrow_raw(1) }
+    }
+}
+
 impl io::Write for Stdout {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         self.write_vectored(&[IoSlice::new(data)])
@@ -103,6 +121,15 @@ impl AsFd for Stderr {
     }
 }
 
+#[stable(feature = "io_safety", since = "1.63.0")]
+impl<'a> AsFd for io::StderrLock<'a> {
+    #[inline]
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: user code should not close stderr out from under the standard library
+        unsafe { BorrowedFd::borrow_raw(2) }
+    }
+}
+
 impl io::Write for Stderr {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         self.write_vectored(&[IoSlice::new(data)])
diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs
index 3d326e49106..016b06efbdc 100644
--- a/library/std/src/sys/wasi/time.rs
+++ b/library/std/src/sys/wasi/time.rs
@@ -47,8 +47,8 @@ impl SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 
-    pub fn to_wasi_timestamp_or_panic(&self) -> wasi::Timestamp {
-        self.0.as_nanos().try_into().expect("time does not fit in WASI timestamp")
+    pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
+        self.0.as_nanos().try_into().ok()
     }
 
     pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index 155d0297e49..ade00750c95 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -572,6 +572,14 @@ impl File {
                 "Cannot set file timestamp to 0",
             ));
         }
+        let is_max =
+            |t: c::FILETIME| t.dwLowDateTime == c::DWORD::MAX && t.dwHighDateTime == c::DWORD::MAX;
+        if times.accessed.map_or(false, is_max) || times.modified.map_or(false, is_max) {
+            return Err(io::const_io_error!(
+                io::ErrorKind::InvalidInput,
+                "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF",
+            ));
+        }
         cvt(unsafe {
             c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref())
         })?;
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index ceea6986e33..2de7da3793f 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -779,6 +779,8 @@ pub fn panicking() -> bool {
     panicking::panicking()
 }
 
+/// Use [`sleep`].
+///
 /// Puts the current thread to sleep for at least the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs
index 7869ba2c041..23925e6ea72 100644
--- a/library/test/src/bench.rs
+++ b/library/test/src/bench.rs
@@ -49,12 +49,12 @@ impl Bencher {
         self.summary = Some(iter(&mut inner));
     }
 
-    pub fn bench<F>(&mut self, mut f: F) -> Option<stats::Summary>
+    pub fn bench<F>(&mut self, mut f: F) -> Result<Option<stats::Summary>, String>
     where
-        F: FnMut(&mut Bencher),
+        F: FnMut(&mut Bencher) -> Result<(), String>,
     {
-        f(self);
-        self.summary
+        let result = f(self);
+        result.map(|_| self.summary)
     }
 }
 
@@ -195,7 +195,7 @@ pub fn benchmark<F>(
     nocapture: bool,
     f: F,
 ) where
-    F: FnMut(&mut Bencher),
+    F: FnMut(&mut Bencher) -> Result<(), String>,
 {
     let mut bs = Bencher { mode: BenchMode::Auto, summary: None, bytes: 0 };
 
@@ -211,14 +211,14 @@ pub fn benchmark<F>(
 
     let test_result = match result {
         //bs.bench(f) {
-        Ok(Some(ns_iter_summ)) => {
+        Ok(Ok(Some(ns_iter_summ))) => {
             let ns_iter = cmp::max(ns_iter_summ.median as u64, 1);
             let mb_s = bs.bytes * 1000 / ns_iter;
 
             let bs = BenchSamples { ns_iter_summ, mb_s: mb_s as usize };
             TestResult::TrBench(bs)
         }
-        Ok(None) => {
+        Ok(Ok(None)) => {
             // iter not called, so no data.
             // FIXME: error in this case?
             let samples: &mut [f64] = &mut [0.0_f64; 1];
@@ -226,6 +226,7 @@ pub fn benchmark<F>(
             TestResult::TrBench(bs)
         }
         Err(_) => TestResult::TrFailed,
+        Ok(Err(_)) => TestResult::TrFailed,
     };
 
     let stdout = data.lock().unwrap().to_vec();
@@ -233,10 +234,10 @@ pub fn benchmark<F>(
     monitor_ch.send(message).unwrap();
 }
 
-pub fn run_once<F>(f: F)
+pub fn run_once<F>(f: F) -> Result<(), String>
 where
-    F: FnMut(&mut Bencher),
+    F: FnMut(&mut Bencher) -> Result<(), String>,
 {
     let mut bs = Bencher { mode: BenchMode::Single, summary: None, bytes: 0 };
-    bs.bench(f);
+    bs.bench(f).map(|_| ())
 }
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 33c6ea58532..c30257fc792 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -6,7 +6,8 @@
 //! benchmarks themselves) should be done via the `#[test]` and
 //! `#[bench]` attributes.
 //!
-//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more details.
+//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more
+//! details.
 
 // Currently, not much of this is meant for users. It is intended to
 // support the simplest interface possible for representing and
@@ -76,6 +77,7 @@ mod types;
 #[cfg(test)]
 mod tests;
 
+use core::any::Any;
 use event::{CompletedTest, TestEvent};
 use helpers::concurrency::get_concurrency;
 use helpers::exit_code::get_exit_code;
@@ -175,17 +177,20 @@ fn make_owned_test(test: &&TestDescAndFn) -> TestDescAndFn {
     }
 }
 
-/// Invoked when unit tests terminate. Should panic if the unit
-/// Tests is considered a failure. By default, invokes `report()`
-/// and checks for a `0` result.
-pub fn assert_test_result<T: Termination>(result: T) {
+/// Invoked when unit tests terminate. Returns `Result::Err` if the test is
+/// considered a failure. By default, invokes `report() and checks for a `0`
+/// result.
+pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> {
     let code = result.report().to_i32();
-    assert_eq!(
-        code, 0,
-        "the test returned a termination value with a non-zero status code ({}) \
-         which indicates a failure",
-        code
-    );
+    if code == 0 {
+        Ok(())
+    } else {
+        Err(format!(
+            "the test returned a termination value with a non-zero status code \
+             ({}) which indicates a failure",
+            code
+        ))
+    }
 }
 
 pub fn run_tests<F>(
@@ -478,7 +483,7 @@ pub fn run_test(
         id: TestId,
         desc: TestDesc,
         monitor_ch: Sender<CompletedTest>,
-        testfn: Box<dyn FnOnce() + Send>,
+        testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
         opts: TestRunOpts,
     ) -> Option<thread::JoinHandle<()>> {
         let concurrency = opts.concurrency;
@@ -567,11 +572,11 @@ pub fn run_test(
 
 /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
 #[inline(never)]
-fn __rust_begin_short_backtrace<F: FnOnce()>(f: F) {
-    f();
+fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
+    let result = f();
 
     // prevent this frame from being tail-call optimised away
-    black_box(());
+    black_box(result)
 }
 
 fn run_test_in_process(
@@ -579,7 +584,7 @@ fn run_test_in_process(
     desc: TestDesc,
     nocapture: bool,
     report_time: bool,
-    testfn: Box<dyn FnOnce() + Send>,
+    testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
     monitor_ch: Sender<CompletedTest>,
     time_opts: Option<time::TestTimeOptions>,
 ) {
@@ -591,7 +596,7 @@ fn run_test_in_process(
     }
 
     let start = report_time.then(Instant::now);
-    let result = catch_unwind(AssertUnwindSafe(testfn));
+    let result = fold_err(catch_unwind(AssertUnwindSafe(testfn)));
     let exec_time = start.map(|start| {
         let duration = start.elapsed();
         TestExecTime(duration)
@@ -608,6 +613,19 @@ fn run_test_in_process(
     monitor_ch.send(message).unwrap();
 }
 
+fn fold_err<T, E>(
+    result: Result<Result<T, E>, Box<dyn Any + Send>>,
+) -> Result<T, Box<dyn Any + Send>>
+where
+    E: Send + 'static,
+{
+    match result {
+        Ok(Err(e)) => Err(Box::new(e)),
+        Ok(Ok(v)) => Ok(v),
+        Err(e) => Err(e),
+    }
+}
+
 fn spawn_test_subprocess(
     id: TestId,
     desc: TestDesc,
@@ -663,7 +681,10 @@ fn spawn_test_subprocess(
     monitor_ch.send(message).unwrap();
 }
 
-fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Send>) -> ! {
+fn run_test_in_spawned_subprocess(
+    desc: TestDesc,
+    testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
+) -> ! {
     let builtin_panic_hook = panic::take_hook();
     let record_result = Arc::new(move |panic_info: Option<&'_ PanicInfo<'_>>| {
         let test_result = match panic_info {
@@ -689,7 +710,9 @@ fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Sen
     });
     let record_result2 = record_result.clone();
     panic::set_hook(Box::new(move |info| record_result2(Some(&info))));
-    testfn();
+    if let Err(message) = testfn() {
+        panic!("{}", message);
+    }
     record_result(None);
     unreachable!("panic=abort callback should have exited the process")
 }
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 0b81aff5907..278cfb15bb1 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -67,7 +67,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
                 no_run: false,
                 test_type: TestType::Unknown,
             },
-            testfn: DynTestFn(Box::new(move || {})),
+            testfn: DynTestFn(Box::new(move || Ok(()))),
         },
         TestDescAndFn {
             desc: TestDesc {
@@ -79,14 +79,14 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
                 no_run: false,
                 test_type: TestType::Unknown,
             },
-            testfn: DynTestFn(Box::new(move || {})),
+            testfn: DynTestFn(Box::new(move || Ok(()))),
         },
     ]
 }
 
 #[test]
 pub fn do_not_run_ignored_tests() {
-    fn f() {
+    fn f() -> Result<(), String> {
         panic!();
     }
     let desc = TestDescAndFn {
@@ -109,7 +109,9 @@ pub fn do_not_run_ignored_tests() {
 
 #[test]
 pub fn ignored_tests_result_in_ignored() {
-    fn f() {}
+    fn f() -> Result<(), String> {
+        Ok(())
+    }
     let desc = TestDescAndFn {
         desc: TestDesc {
             name: StaticTestName("whatever"),
@@ -132,7 +134,7 @@ pub fn ignored_tests_result_in_ignored() {
 #[test]
 #[cfg(not(target_os = "emscripten"))]
 fn test_should_panic() {
-    fn f() {
+    fn f() -> Result<(), String> {
         panic!();
     }
     let desc = TestDescAndFn {
@@ -157,7 +159,7 @@ fn test_should_panic() {
 #[test]
 #[cfg(not(target_os = "emscripten"))]
 fn test_should_panic_good_message() {
-    fn f() {
+    fn f() -> Result<(), String> {
         panic!("an error message");
     }
     let desc = TestDescAndFn {
@@ -183,7 +185,7 @@ fn test_should_panic_good_message() {
 #[cfg(not(target_os = "emscripten"))]
 fn test_should_panic_bad_message() {
     use crate::tests::TrFailedMsg;
-    fn f() {
+    fn f() -> Result<(), String> {
         panic!("an error message");
     }
     let expected = "foobar";
@@ -214,7 +216,7 @@ fn test_should_panic_bad_message() {
 fn test_should_panic_non_string_message_type() {
     use crate::tests::TrFailedMsg;
     use std::any::TypeId;
-    fn f() {
+    fn f() -> Result<(), String> {
         std::panic::panic_any(1i32);
     }
     let expected = "foobar";
@@ -249,7 +251,9 @@ fn test_should_panic_but_succeeds() {
     let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")];
 
     for &should_panic in should_panic_variants.iter() {
-        fn f() {}
+        fn f() -> Result<(), String> {
+            Ok(())
+        }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
@@ -283,7 +287,9 @@ fn test_should_panic_but_succeeds() {
 }
 
 fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
-    fn f() {}
+    fn f() -> Result<(), String> {
+        Ok(())
+    }
     let desc = TestDescAndFn {
         desc: TestDesc {
             name: StaticTestName("whatever"),
@@ -318,7 +324,9 @@ fn test_should_report_time() {
 }
 
 fn time_test_failure_template(test_type: TestType) -> TestResult {
-    fn f() {}
+    fn f() -> Result<(), String> {
+        Ok(())
+    }
     let desc = TestDescAndFn {
         desc: TestDesc {
             name: StaticTestName("whatever"),
@@ -480,7 +488,7 @@ pub fn exclude_should_panic_option() {
             no_run: false,
             test_type: TestType::Unknown,
         },
-        testfn: DynTestFn(Box::new(move || {})),
+        testfn: DynTestFn(Box::new(move || Ok(()))),
     });
 
     let filtered = filter_tests(&opts, tests);
@@ -504,7 +512,7 @@ pub fn exact_filter_match() {
                     no_run: false,
                     test_type: TestType::Unknown,
                 },
-                testfn: DynTestFn(Box::new(move || {})),
+                testfn: DynTestFn(Box::new(move || Ok(()))),
             })
             .collect()
     }
@@ -580,7 +588,9 @@ fn sample_tests() -> Vec<TestDescAndFn> {
         "test::run_include_ignored_option".to_string(),
         "test::sort_tests".to_string(),
     ];
-    fn testfn() {}
+    fn testfn() -> Result<(), String> {
+        Ok(())
+    }
     let mut tests = Vec::new();
     for name in &names {
         let test = TestDescAndFn {
@@ -717,21 +727,26 @@ pub fn test_metricmap_compare() {
 
 #[test]
 pub fn test_bench_once_no_iter() {
-    fn f(_: &mut Bencher) {}
-    bench::run_once(f);
+    fn f(_: &mut Bencher) -> Result<(), String> {
+        Ok(())
+    }
+    bench::run_once(f).unwrap();
 }
 
 #[test]
 pub fn test_bench_once_iter() {
-    fn f(b: &mut Bencher) {
-        b.iter(|| {})
+    fn f(b: &mut Bencher) -> Result<(), String> {
+        b.iter(|| {});
+        Ok(())
     }
-    bench::run_once(f);
+    bench::run_once(f).unwrap();
 }
 
 #[test]
 pub fn test_bench_no_iter() {
-    fn f(_: &mut Bencher) {}
+    fn f(_: &mut Bencher) -> Result<(), String> {
+        Ok(())
+    }
 
     let (tx, rx) = channel();
 
@@ -751,8 +766,9 @@ pub fn test_bench_no_iter() {
 
 #[test]
 pub fn test_bench_iter() {
-    fn f(b: &mut Bencher) {
-        b.iter(|| {})
+    fn f(b: &mut Bencher) -> Result<(), String> {
+        b.iter(|| {});
+        Ok(())
     }
 
     let (tx, rx) = channel();
@@ -821,3 +837,33 @@ fn should_sort_failures_before_printing_them() {
     let bpos = s.find("b").unwrap();
     assert!(apos < bpos);
 }
+
+#[test]
+#[cfg(not(target_os = "emscripten"))]
+fn test_dyn_bench_returning_err_fails_when_run_as_test() {
+    fn f(_: &mut Bencher) -> Result<(), String> {
+        Result::Err("An error".into())
+    }
+    let desc = TestDescAndFn {
+        desc: TestDesc {
+            name: StaticTestName("whatever"),
+            ignore: false,
+            ignore_message: None,
+            should_panic: ShouldPanic::No,
+            compile_fail: false,
+            no_run: false,
+            test_type: TestType::Unknown,
+        },
+        testfn: DynBenchFn(Box::new(f)),
+    };
+    let (tx, rx) = channel();
+    let notify = move |event: TestEvent| {
+        if let TestEvent::TeResult(result) = event {
+            tx.send(result).unwrap();
+        }
+        Ok(())
+    };
+    run_tests(&TestOpts { run_tests: true, ..TestOpts::new() }, vec![desc], notify).unwrap();
+    let result = rx.recv().unwrap().result;
+    assert_eq!(result, TrFailed);
+}
diff --git a/library/test/src/types.rs b/library/test/src/types.rs
index ffb1efe18cc..888afff7921 100644
--- a/library/test/src/types.rs
+++ b/library/test/src/types.rs
@@ -75,14 +75,15 @@ impl fmt::Display for TestName {
 }
 
 // A function that runs a test. If the function returns successfully,
-// the test succeeds; if the function panics then the test fails. We
-// may need to come up with a more clever definition of test in order
-// to support isolation of tests into threads.
+// the test succeeds; if the function panics or returns Result::Err
+// then the test fails. We may need to come up with a more clever
+// definition of test in order to support isolation of tests into
+// threads.
 pub enum TestFn {
-    StaticTestFn(fn()),
-    StaticBenchFn(fn(&mut Bencher)),
-    DynTestFn(Box<dyn FnOnce() + Send>),
-    DynBenchFn(Box<dyn Fn(&mut Bencher) + Send>),
+    StaticTestFn(fn() -> Result<(), String>),
+    StaticBenchFn(fn(&mut Bencher) -> Result<(), String>),
+    DynTestFn(Box<dyn FnOnce() -> Result<(), String> + Send>),
+    DynBenchFn(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>),
 }
 
 impl TestFn {
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
index 85afc1f5f6c..64b74ecc9de 100644
--- a/src/bootstrap/CHANGELOG.md
+++ b/src/bootstrap/CHANGELOG.md
@@ -13,6 +13,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Change the names for `dist` commands to match the component they generate. [#90684](https://github.com/rust-lang/rust/pull/90684)
 - The `build.fast-submodules` option has been removed. Fast submodule checkouts are enabled unconditionally. Automatic submodule handling can still be disabled with `build.submodules = false`.
 - Several unsupported `./configure` options have been removed: `optimize`, `parallel-compiler`. These can still be enabled with `--set`, although it isn't recommended.
+- `remote-test-server`'s `verbose` argument has been removed in favor of the `--verbose` flag
+- `remote-test-server`'s `remote` argument has been removed in favor of the `--bind` flag. Use `--bind 0.0.0.0:12345` to replicate the behavior of the `remote` argument.
 
 ### Non-breaking changes
 
diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index 1932a0017ee..258352a21a4 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -5,10 +5,12 @@
 //! `package_vers`, and otherwise indicating to the compiler what it should
 //! print out as part of its version information.
 
+use std::fs;
 use std::path::Path;
 use std::process::Command;
 
 use crate::util::output;
+use crate::util::t;
 use crate::Build;
 
 pub enum GitInfo {
@@ -18,19 +20,25 @@ pub enum GitInfo {
     /// If the info should be used (`ignore_git` is false), this will be
     /// `Some`, otherwise it will be `None`.
     Present(Option<Info>),
+    /// This is not a git repostory, but the info can be fetched from the
+    /// `git-commit-info` file.
+    RecordedForTarball(Info),
 }
 
 pub struct Info {
-    commit_date: String,
-    sha: String,
-    short_sha: String,
+    pub commit_date: String,
+    pub sha: String,
+    pub short_sha: String,
 }
 
 impl GitInfo {
     pub fn new(ignore_git: bool, dir: &Path) -> GitInfo {
         // See if this even begins to look like a git dir
         if !dir.join(".git").exists() {
-            return GitInfo::Absent;
+            match read_commit_info_file(dir) {
+                Some(info) => return GitInfo::RecordedForTarball(info),
+                None => return GitInfo::Absent,
+            }
         }
 
         // Make sure git commands work
@@ -65,10 +73,11 @@ impl GitInfo {
         }))
     }
 
-    fn info(&self) -> Option<&Info> {
+    pub fn info(&self) -> Option<&Info> {
         match self {
-            GitInfo::Present(info) => info.as_ref(),
             GitInfo::Absent => None,
+            GitInfo::Present(info) => info.as_ref(),
+            GitInfo::RecordedForTarball(info) => Some(info),
         }
     }
 
@@ -96,10 +105,53 @@ impl GitInfo {
         version
     }
 
-    pub fn is_git(&self) -> bool {
+    /// Returns whether this directory has a `.git` directory which should be managed by bootstrap.
+    pub fn is_managed_git_subrepository(&self) -> bool {
         match self {
-            GitInfo::Absent => false,
+            GitInfo::Absent | GitInfo::RecordedForTarball(_) => false,
             GitInfo::Present(_) => true,
         }
     }
+
+    /// Returns whether this is being built from a tarball.
+    pub fn is_from_tarball(&self) -> bool {
+        match self {
+            GitInfo::Absent | GitInfo::Present(_) => false,
+            GitInfo::RecordedForTarball(_) => true,
+        }
+    }
+}
+
+/// Read the commit information from the `git-commit-info` file given the
+/// project root.
+pub fn read_commit_info_file(root: &Path) -> Option<Info> {
+    if let Ok(contents) = fs::read_to_string(root.join("git-commit-info")) {
+        let mut lines = contents.lines();
+        let sha = lines.next();
+        let short_sha = lines.next();
+        let commit_date = lines.next();
+        let info = match (commit_date, sha, short_sha) {
+            (Some(commit_date), Some(sha), Some(short_sha)) => Info {
+                commit_date: commit_date.to_owned(),
+                sha: sha.to_owned(),
+                short_sha: short_sha.to_owned(),
+            },
+            _ => panic!("the `git-comit-info` file is malformed"),
+        };
+        Some(info)
+    } else {
+        None
+    }
+}
+
+/// Write the commit information to the `git-commit-info` file given the project
+/// root.
+pub fn write_commit_info_file(root: &Path, info: &Info) {
+    let commit_info = format!("{}\n{}\n{}\n", info.sha, info.short_sha, info.commit_date);
+    t!(fs::write(root.join("git-commit-info"), &commit_info));
+}
+
+/// Write the commit hash to the `git-commit-hash` file given the project root.
+pub fn write_commit_hash_file(root: &Path, sha: &str) {
+    t!(fs::write(root.join("git-commit-hash"), sha));
 }
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index c13e83f6c86..58cf3edc317 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -299,9 +299,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
 
     // Determine if we're going to compile in optimized C intrinsics to
     // the `compiler-builtins` crate. These intrinsics live in LLVM's
-    // `compiler-rt` repository, but our `src/llvm-project` submodule isn't
-    // always checked out, so we need to conditionally look for this. (e.g. if
-    // an external LLVM is used we skip the LLVM submodule checkout).
+    // `compiler-rt` repository.
     //
     // Note that this shouldn't affect the correctness of `compiler-builtins`,
     // but only its speed. Some intrinsics in C haven't been translated to Rust
@@ -312,8 +310,15 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
     // If `compiler-rt` is available ensure that the `c` feature of the
     // `compiler-builtins` crate is enabled and it's configured to learn where
     // `compiler-rt` is located.
-    let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
-    let compiler_builtins_c_feature = if compiler_builtins_root.exists() {
+    let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins {
+        if !builder.is_rust_llvm(target) {
+            panic!(
+                "need a managed LLVM submodule for optimized intrinsics support; unset `llvm-config` or `optimized-compiler-builtins`"
+            );
+        }
+
+        builder.update_submodule(&Path::new("src").join("llvm-project"));
+        let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
         // Note that `libprofiler_builtins/build.rs` also computes this so if
         // you're changing something here please also change that.
         cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 74530dec97b..8c501f637d9 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -73,6 +73,8 @@ pub struct Config {
     pub color: Color,
     pub patch_binaries_for_nix: bool,
     pub stage0_metadata: Stage0Metadata,
+    /// Whether to use the `c` feature of the `compiler_builtins` crate.
+    pub optimized_compiler_builtins: bool,
 
     pub on_fail: Option<String>,
     pub stage: u32,
@@ -597,6 +599,7 @@ define_config! {
         bench_stage: Option<u32> = "bench-stage",
         patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
         metrics: Option<bool> = "metrics",
+        optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
     }
 }
 
@@ -966,6 +969,7 @@ impl Config {
         set(&mut config.print_step_timings, build.print_step_timings);
         set(&mut config.print_step_rusage, build.print_step_rusage);
         set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix);
+        set(&mut config.optimized_compiler_builtins, build.optimized_compiler_builtins);
 
         config.verbose = cmp::max(config.verbose, flags.verbose);
 
@@ -1330,11 +1334,22 @@ impl Config {
         git
     }
 
-    pub(crate) fn artifact_channel(&self, commit: &str) -> String {
-        let mut channel = self.git();
-        channel.arg("show").arg(format!("{}:src/ci/channel", commit));
-        let channel = output(&mut channel);
-        channel.trim().to_owned()
+    pub(crate) fn artifact_channel(&self, builder: &Builder<'_>, commit: &str) -> String {
+        if builder.rust_info.is_managed_git_subrepository() {
+            let mut channel = self.git();
+            channel.arg("show").arg(format!("{}:src/ci/channel", commit));
+            let channel = output(&mut channel);
+            channel.trim().to_owned()
+        } else if let Ok(channel) = fs::read_to_string(builder.src.join("src/ci/channel")) {
+            channel.trim().to_owned()
+        } else {
+            let src = builder.src.display();
+            eprintln!("error: failed to determine artifact channel");
+            eprintln!(
+                "help: either use git or ensure that {src}/src/ci/channel contains the name of the channel to use"
+            );
+            panic!();
+        }
     }
 
     /// Try to find the relative path of `bindir`, otherwise return it in full.
@@ -1471,7 +1486,7 @@ impl Config {
     }
 
     pub fn submodules(&self, rust_info: &GitInfo) -> bool {
-        self.submodules.unwrap_or(rust_info.is_git())
+        self.submodules.unwrap_or(rust_info.is_managed_git_subrepository())
     }
 }
 
@@ -1576,7 +1591,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> {
 
 fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
     builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
-    let channel = builder.config.artifact_channel(commit);
+    let channel = builder.config.artifact_channel(builder, commit);
     let host = builder.config.build.triple;
     let bin_root = builder.out.join(host).join("ci-rustc");
     let rustc_stamp = bin_root.join(".rustc-stamp");
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index f387496883b..7eb8f8bbb30 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -16,6 +16,7 @@ use std::process::Command;
 
 use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::cache::{Interned, INTERNER};
+use crate::channel;
 use crate::compile;
 use crate::config::TargetSelection;
 use crate::tarball::{GeneratedTarball, OverlayKind, Tarball};
@@ -918,12 +919,13 @@ impl Step for PlainSourceTarball {
 
         // Create the version file
         builder.create(&plain_dst_src.join("version"), &builder.rust_version());
-        if let Some(sha) = builder.rust_sha() {
-            builder.create(&plain_dst_src.join("git-commit-hash"), &sha);
+        if let Some(info) = builder.rust_info.info() {
+            channel::write_commit_hash_file(&plain_dst_src, &info.sha);
+            channel::write_commit_info_file(&plain_dst_src, info);
         }
 
         // If we're building from git sources, we need to vendor a complete distribution.
-        if builder.rust_info.is_git() {
+        if builder.rust_info.is_managed_git_subrepository() {
             // Ensure we have the submodules checked out.
             builder.update_submodule(Path::new("src/tools/rust-analyzer"));
 
@@ -1365,6 +1367,7 @@ impl Step for Extended {
         }
 
         add_component!("rust-docs" => Docs { host: target });
+        add_component!("rust-json-docs" => JsonDocs { host: target });
         add_component!("rust-demangler"=> RustDemangler { compiler, target });
         add_component!("cargo" => Cargo { compiler, target });
         add_component!("rustfmt" => Rustfmt { compiler, target });
@@ -1844,23 +1847,21 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
 ///
 /// Returns whether the files were actually copied.
 fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool {
-    if let Some(config) = builder.config.target_config.get(&target) {
-        if config.llvm_config.is_some() && !builder.config.llvm_from_ci {
-            // If the LLVM was externally provided, then we don't currently copy
-            // artifacts into the sysroot. This is not necessarily the right
-            // choice (in particular, it will require the LLVM dylib to be in
-            // the linker's load path at runtime), but the common use case for
-            // external LLVMs is distribution provided LLVMs, and in that case
-            // they're usually in the standard search path (e.g., /usr/lib) and
-            // copying them here is going to cause problems as we may end up
-            // with the wrong files and isn't what distributions want.
-            //
-            // This behavior may be revisited in the future though.
-            //
-            // If the LLVM is coming from ourselves (just from CI) though, we
-            // still want to install it, as it otherwise won't be available.
-            return false;
-        }
+    if !builder.is_rust_llvm(target) {
+        // If the LLVM was externally provided, then we don't currently copy
+        // artifacts into the sysroot. This is not necessarily the right
+        // choice (in particular, it will require the LLVM dylib to be in
+        // the linker's load path at runtime), but the common use case for
+        // external LLVMs is distribution provided LLVMs, and in that case
+        // they're usually in the standard search path (e.g., /usr/lib) and
+        // copying them here is going to cause problems as we may end up
+        // with the wrong files and isn't what distributions want.
+        //
+        // This behavior may be revisited in the future though.
+        //
+        // If the LLVM is coming from ourselves (just from CI) though, we
+        // still want to install it, as it otherwise won't be available.
+        return false;
     }
 
     // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index c83490316b6..9ada3f315c1 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -229,6 +229,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
     // FIXME: Used by proc-macro2, but we should not be triggering on external dependencies.
     (Some(Mode::Rustc), "span_locations", None),
     (Some(Mode::ToolRustc), "span_locations", None),
+    // Can be passed in RUSTFLAGS to prevent direct syscalls in rustix.
+    (None, "rustix_use_libc", None),
 ];
 
 /// A structure representing a Rust compiler.
@@ -398,7 +400,7 @@ impl Build {
     /// line and the filesystem `config`.
     ///
     /// By default all build output will be placed in the current directory.
-    pub fn new(config: Config) -> Build {
+    pub fn new(mut config: Config) -> Build {
         let src = config.src.clone();
         let out = config.out.clone();
 
@@ -472,6 +474,10 @@ impl Build {
             )
         }
 
+        if rust_info.is_from_tarball() && config.description.is_none() {
+            config.description = Some("built from a source tarball".to_owned());
+        }
+
         let mut build = Build {
             initial_rustc: config.initial_rustc.clone(),
             initial_cargo: config.initial_cargo.clone(),
@@ -571,7 +577,9 @@ impl Build {
 
         // NOTE: The check for the empty directory is here because when running x.py the first time,
         // the submodule won't be checked out. Check it out now so we can build it.
-        if !channel::GitInfo::new(false, &absolute_path).is_git() && !dir_is_empty(&absolute_path) {
+        if !channel::GitInfo::new(false, &absolute_path).is_managed_git_subrepository()
+            && !dir_is_empty(&absolute_path)
+        {
             return;
         }
 
@@ -642,7 +650,7 @@ impl Build {
             // Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
             let submodule = Path::new(line.splitn(2, ' ').nth(1).unwrap());
             // Don't update the submodule unless it's already been cloned.
-            if channel::GitInfo::new(false, submodule).is_git() {
+            if channel::GitInfo::new(false, submodule).is_managed_git_subrepository() {
                 self.update_submodule(submodule);
             }
         }
@@ -668,6 +676,9 @@ impl Build {
             return setup::setup(&self.config, *profile);
         }
 
+        // Download rustfmt early so that it can be used in rust-analyzer configs.
+        let _ = &builder::Builder::new(&self).initial_rustfmt();
+
         {
             let builder = builder::Builder::new(&self);
             if let Some(path) = builder.paths.get(0) {
@@ -1255,7 +1266,7 @@ impl Build {
         match &self.config.channel[..] {
             "stable" => num.to_string(),
             "beta" => {
-                if self.rust_info.is_git() && !self.config.ignore_git {
+                if self.rust_info.is_managed_git_subrepository() && !self.config.ignore_git {
                     format!("{}-beta.{}", num, self.beta_prerelease_version())
                 } else {
                     format!("{}-beta", num)
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index d6ee6d489cf..9045354d0b2 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -17,6 +17,7 @@ use std::path::{Path, PathBuf};
 use std::process::Command;
 
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
+use crate::channel;
 use crate::config::TargetSelection;
 use crate::util::get_clang_cl_resource_dir;
 use crate::util::{self, exe, output, program_out_of_date, t, up_to_date};
@@ -115,24 +116,29 @@ pub fn prebuilt_llvm_config(
 }
 
 /// This retrieves the LLVM sha we *want* to use, according to git history.
-pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String {
-    let mut rev_list = config.git();
-    rev_list.args(&[
-        PathBuf::from("rev-list"),
-        format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
-        "-n1".into(),
-        "--first-parent".into(),
-        "HEAD".into(),
-        "--".into(),
-        config.src.join("src/llvm-project"),
-        config.src.join("src/bootstrap/download-ci-llvm-stamp"),
-        // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
-        config.src.join("src/version"),
-    ]);
-    let llvm_sha = output(&mut rev_list);
-    let llvm_sha = llvm_sha.trim();
-
-    if llvm_sha == "" {
+pub(crate) fn detect_llvm_sha(config: &crate::config::Config, is_git: bool) -> String {
+    let llvm_sha = if is_git {
+        let mut rev_list = config.git();
+        rev_list.args(&[
+            PathBuf::from("rev-list"),
+            format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
+            "-n1".into(),
+            "--first-parent".into(),
+            "HEAD".into(),
+            "--".into(),
+            config.src.join("src/llvm-project"),
+            config.src.join("src/bootstrap/download-ci-llvm-stamp"),
+            // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
+            config.src.join("src/version"),
+        ]);
+        output(&mut rev_list).trim().to_owned()
+    } else if let Some(info) = channel::read_commit_info_file(&config.src) {
+        info.sha.trim().to_owned()
+    } else {
+        "".to_owned()
+    };
+
+    if &llvm_sha == "" {
         eprintln!("error: could not find commit hash for downloading LLVM");
         eprintln!("help: maybe your repository history is too shallow?");
         eprintln!("help: consider disabling `download-ci-llvm`");
@@ -140,7 +146,7 @@ pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String {
         panic!();
     }
 
-    llvm_sha.to_owned()
+    llvm_sha
 }
 
 /// Returns whether the CI-found LLVM is currently usable.
@@ -194,7 +200,9 @@ pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool
     }
 
     if crate::util::CiEnv::is_ci() {
-        let llvm_sha = detect_llvm_sha(config);
+        // We assume we have access to git, so it's okay to unconditionally pass
+        // `true` here.
+        let llvm_sha = detect_llvm_sha(config, true);
         let head_sha = output(config.git().arg("rev-parse").arg("HEAD"));
         let head_sha = head_sha.trim();
         if llvm_sha == head_sha {
@@ -215,7 +223,7 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
     }
     let llvm_root = config.ci_llvm_root();
     let llvm_stamp = llvm_root.join(".llvm-stamp");
-    let llvm_sha = detect_llvm_sha(&config);
+    let llvm_sha = detect_llvm_sha(&config, builder.rust_info.is_managed_git_subrepository());
     let key = format!("{}{}", llvm_sha, config.llvm_assertions);
     if program_out_of_date(&llvm_stamp, &key) && !config.dry_run {
         download_ci_llvm(builder, &llvm_sha);
@@ -260,7 +268,7 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) {
     } else {
         &builder.config.stage0_metadata.config.artifacts_server
     };
-    let channel = builder.config.artifact_channel(llvm_sha);
+    let channel = builder.config.artifact_channel(builder, llvm_sha);
     let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple);
     let tarball = rustc_cache.join(&filename);
     if !tarball.exists() {
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index cae41286f08..e905517253c 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -74,7 +74,7 @@ pub fn check(build: &mut Build) {
     let mut cmd_finder = Finder::new();
     // If we've got a git directory we're gonna need git to update
     // submodules and learn about various other aspects.
-    if build.rust_info.is_git() {
+    if build.rust_info.is_managed_git_subrepository() {
         cmd_finder.must_have("git");
     }
 
diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs
index e30067a5cbe..d999b6c1503 100644
--- a/src/bootstrap/tarball.rs
+++ b/src/bootstrap/tarball.rs
@@ -4,6 +4,7 @@ use std::{
 };
 
 use crate::builder::Builder;
+use crate::channel;
 use crate::util::t;
 
 #[derive(Copy, Clone)]
@@ -297,8 +298,9 @@ impl<'a> Tarball<'a> {
     fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> GeneratedTarball {
         t!(std::fs::create_dir_all(&self.overlay_dir));
         self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder));
-        if let Some(sha) = self.builder.rust_sha() {
-            self.builder.create(&self.overlay_dir.join("git-commit-hash"), &sha);
+        if let Some(info) = self.builder.rust_info.info() {
+            channel::write_commit_hash_file(&self.overlay_dir, &info.sha);
+            channel::write_commit_info_file(&self.overlay_dir, info);
         }
         for file in self.overlay.legal_and_readme() {
             self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index ff6f7909a5a..d6e7f787270 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -870,10 +870,10 @@ tool_extended!((self, builder),
     Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
     Miri, "src/tools/miri", "miri", stable=false, in_tree=true, {};
     CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, in_tree=true, {};
-    Rls, "src/tools/rls", "rls", stable=true, {};
     // FIXME: tool_std is not quite right, we shouldn't allow nightly features.
     // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
     // and this is close enough for now.
+    Rls, "src/tools/rls", "rls", stable=true, in_tree=true, tool_std=true, {};
     RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
     Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
 );
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index b71a348abd9..64faaf4f19b 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -230,6 +230,22 @@ For targets: `aarch64-unknown-linux-gnu`
 - C compiler > gcc version = 8.3.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
 
+### `i586-linux-gnu.config`
+
+For targets: `i586-unknown-linux-gnu`
+
+- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
+- Path and misc options > Patches origin = Bundled only
+- Target options > Target Architecture = x86
+- Target options > Architecture level = i586
+- Target options > Target CFLAGS = -Wa,-mrelax-relocations=no
+- Operating System > Target OS = linux
+- Operating System > Linux kernel version = 3.2.101
+- Binary utilities > Version of binutils = 2.32
+- C-library > glibc version = 2.17.0
+- C compiler > gcc version = 8.3.0
+- C compiler > C++ = ENABLE
+
 ### `powerpc-linux-gnu.config`
 
 For targets: `powerpc-unknown-linux-gnu`
diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
index 5ddd3f18039..637b5fa22f9 100644
--- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
+++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
@@ -47,4 +47,6 @@ ENV RUST_CONFIGURE_ARGS --disable-jemalloc \
   --set=$TARGET.cc=x86_64-unknown-haiku-gcc \
   --set=$TARGET.cxx=x86_64-unknown-haiku-g++ \
   --set=$TARGET.llvm-config=/bin/llvm-config-haiku
+ENV EXTERNAL_LLVM 1
+
 ENV SCRIPT python3 ../x.py dist --host=$HOST --target=$HOST
diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
index b0d65428ec6..26eb69f2eae 100644
--- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
@@ -1,5 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:22.04
 
+ARG DEBIAN_FRONTEND=noninteractive
 RUN apt-get update && apt-get install -y --no-install-recommends \
   g++-multilib \
   make \
@@ -17,6 +18,25 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   libssl-dev \
   pkg-config
 
+COPY scripts/cross-apt-packages.sh /scripts/
+RUN sh /scripts/cross-apt-packages.sh
+
+COPY scripts/crosstool-ng-1.24.sh /scripts/
+RUN sh /scripts/crosstool-ng-1.24.sh
+
+COPY scripts/rustbuild-setup.sh /scripts/
+RUN sh /scripts/rustbuild-setup.sh
+WORKDIR /tmp
+
+COPY host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config \
+     host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh \
+     /tmp/
+RUN su rustbuild -c ./build-i586-gnu-toolchain.sh
+ENV PATH=$PATH:/x-tools/i586-unknown-linux-gnu/bin
+ENV \
+    CC_i586_unknown_linux_gnu=i586-unknown-linux-gnu-gcc \
+    AR_i586_unknown_linux_gnu=i586-unknown-linux-gnu-ar
+
 WORKDIR /build/
 COPY scripts/musl.sh /build/
 RUN CC=gcc CFLAGS="-m32 -Wa,-mrelax-relocations=no" \
@@ -27,17 +47,20 @@ RUN CC=gcc CFLAGS="-m32 -Wa,-mrelax-relocations=no" \
     bash musl.sh i586 --target=i586 && \
     rm -rf /build
 
+# FIXME: musl really shouldn't be linking libgcc_s.so, as it's linked to glibc,
+# but it's required by src/test/ui/proc-macro/crt-static.rs. Ubuntu:16.04 gcc-5
+# had libgcc_s.so as a symlink to the absolute libgcc_s.so.1, but now it's an
+# ld-script that expects to find libgcc_s.so.1 in the library search path.
+# See also https://github.com/rust-lang/rust/issues/82521
+RUN ln -s /usr/lib32/libgcc_s.so.1 /musl-i686/lib/
+
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-i586=/musl-i586 \
       --musl-root-i686=/musl-i686 \
-      --disable-docs \
-      --set llvm.allow-old-toolchain
+      --disable-docs
 
 # Newer binutils broke things on some vms/distros (i.e., linking against
 # unknown relocs disabled by the following flag), so we need to go out of our
diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh
new file mode 100755
index 00000000000..ceab60cfb45
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+set -ex
+
+hide_output() {
+  set +x
+  on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+  trap "$on_err" ERR
+  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+  PING_LOOP_PID=$!
+  "$@" &> /tmp/build.log
+  rm /tmp/build.log
+  trap - ERR
+  kill $PING_LOOP_PID
+  set -x
+}
+
+mkdir build
+cd build
+cp ../i586-linux-gnu.config .config
+hide_output ct-ng build
+cd ..
+rm -rf build
diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config
new file mode 100644
index 00000000000..ef2e9467f4a
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config
@@ -0,0 +1,726 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# crosstool-NG  Configuration
+#
+CT_CONFIGURE_has_static_link=y
+CT_CONFIGURE_has_cxx11=y
+CT_CONFIGURE_has_wget=y
+CT_CONFIGURE_has_curl=y
+CT_CONFIGURE_has_make_3_81_or_newer=y
+CT_CONFIGURE_has_make_4_0_or_newer=y
+CT_CONFIGURE_has_libtool_2_4_or_newer=y
+CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
+CT_CONFIGURE_has_autoconf_2_65_or_newer=y
+CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
+CT_CONFIGURE_has_automake_1_15_or_newer=y
+CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
+CT_CONFIGURE_has_python_3_4_or_newer=y
+CT_CONFIGURE_has_bison_2_7_or_newer=y
+CT_CONFIGURE_has_python=y
+CT_CONFIGURE_has_git=y
+CT_CONFIGURE_has_md5sum=y
+CT_CONFIGURE_has_sha1sum=y
+CT_CONFIGURE_has_sha256sum=y
+CT_CONFIGURE_has_sha512sum=y
+CT_CONFIGURE_has_install_with_strip_program=y
+CT_CONFIG_VERSION_CURRENT="3"
+CT_CONFIG_VERSION="3"
+CT_MODULES=y
+
+#
+# Paths and misc options
+#
+
+#
+# crosstool-NG behavior
+#
+# CT_OBSOLETE is not set
+# CT_EXPERIMENTAL is not set
+# CT_DEBUG_CT is not set
+
+#
+# Paths
+#
+CT_LOCAL_TARBALLS_DIR="${HOME}/src"
+CT_SAVE_TARBALLS=y
+# CT_TARBALLS_BUILDROOT_LAYOUT is not set
+CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
+CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
+CT_RM_RF_PREFIX_DIR=y
+CT_REMOVE_DOCS=y
+CT_INSTALL_LICENSES=y
+CT_PREFIX_DIR_RO=y
+CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
+# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
+
+#
+# Downloading
+#
+CT_DOWNLOAD_AGENT_WGET=y
+# CT_DOWNLOAD_AGENT_CURL is not set
+# CT_DOWNLOAD_AGENT_NONE is not set
+# CT_FORBID_DOWNLOAD is not set
+# CT_FORCE_DOWNLOAD is not set
+CT_CONNECT_TIMEOUT=10
+CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
+# CT_ONLY_DOWNLOAD is not set
+CT_USE_MIRROR=y
+# CT_FORCE_MIRROR is not set
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
+CT_VERIFY_DOWNLOAD_DIGEST=y
+CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
+CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
+# CT_VERIFY_DOWNLOAD_SIGNATURE is not set
+
+#
+# Extracting
+#
+# CT_FORCE_EXTRACT is not set
+CT_OVERRIDE_CONFIG_GUESS_SUB=y
+# CT_ONLY_EXTRACT is not set
+CT_PATCH_BUNDLED=y
+# CT_PATCH_BUNDLED_LOCAL is not set
+CT_PATCH_ORDER="bundled"
+
+#
+# Build behavior
+#
+CT_PARALLEL_JOBS=0
+CT_LOAD=""
+CT_USE_PIPES=y
+CT_EXTRA_CFLAGS_FOR_BUILD=""
+CT_EXTRA_LDFLAGS_FOR_BUILD=""
+CT_EXTRA_CFLAGS_FOR_HOST=""
+CT_EXTRA_LDFLAGS_FOR_HOST=""
+# CT_CONFIG_SHELL_SH is not set
+# CT_CONFIG_SHELL_ASH is not set
+CT_CONFIG_SHELL_BASH=y
+# CT_CONFIG_SHELL_CUSTOM is not set
+CT_CONFIG_SHELL="${bash}"
+
+#
+# Logging
+#
+# CT_LOG_ERROR is not set
+# CT_LOG_WARN is not set
+# CT_LOG_INFO is not set
+CT_LOG_EXTRA=y
+# CT_LOG_ALL is not set
+# CT_LOG_DEBUG is not set
+CT_LOG_LEVEL_MAX="EXTRA"
+# CT_LOG_SEE_TOOLS_WARN is not set
+CT_LOG_PROGRESS_BAR=y
+CT_LOG_TO_FILE=y
+CT_LOG_FILE_COMPRESS=y
+
+#
+# Target options
+#
+# CT_ARCH_ALPHA is not set
+# CT_ARCH_ARC is not set
+# CT_ARCH_ARM is not set
+# CT_ARCH_AVR is not set
+# CT_ARCH_M68K is not set
+# CT_ARCH_MIPS is not set
+# CT_ARCH_NIOS2 is not set
+# CT_ARCH_POWERPC is not set
+# CT_ARCH_S390 is not set
+# CT_ARCH_SH is not set
+# CT_ARCH_SPARC is not set
+CT_ARCH_X86=y
+# CT_ARCH_XTENSA is not set
+CT_ARCH="x86"
+CT_ARCH_CHOICE_KSYM="X86"
+CT_ARCH_CPU=""
+CT_ARCH_TUNE=""
+CT_ARCH_X86_SHOW=y
+
+#
+# Options for x86
+#
+CT_ARCH_X86_PKG_KSYM=""
+CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
+CT_ARCH_SUFFIX=""
+# CT_OMIT_TARGET_VENDOR is not set
+
+#
+# Generic target options
+#
+# CT_MULTILIB is not set
+CT_DEMULTILIB=y
+CT_ARCH_USE_MMU=y
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_BITNESS=32
+CT_ARCH_32=y
+# CT_ARCH_64 is not set
+
+#
+# Target optimisations
+#
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_CPU=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_ARCH="i586"
+CT_TARGET_CFLAGS="-Wa,-mrelax-relocations=no"
+CT_TARGET_LDFLAGS=""
+
+#
+# Toolchain options
+#
+
+#
+# General toolchain options
+#
+CT_FORCE_SYSROOT=y
+CT_USE_SYSROOT=y
+CT_SYSROOT_NAME="sysroot"
+CT_SYSROOT_DIR_PREFIX=""
+CT_WANTS_STATIC_LINK=y
+CT_WANTS_STATIC_LINK_CXX=y
+# CT_STATIC_TOOLCHAIN is not set
+CT_SHOW_CT_VERSION=y
+CT_TOOLCHAIN_PKGVERSION=""
+CT_TOOLCHAIN_BUGURL=""
+
+#
+# Tuple completion and aliasing
+#
+CT_TARGET_VENDOR="unknown"
+CT_TARGET_ALIAS_SED_EXPR=""
+CT_TARGET_ALIAS=""
+
+#
+# Toolchain type
+#
+CT_CROSS=y
+# CT_CANADIAN is not set
+CT_TOOLCHAIN_TYPE="cross"
+
+#
+# Build system
+#
+CT_BUILD=""
+CT_BUILD_PREFIX=""
+CT_BUILD_SUFFIX=""
+
+#
+# Misc options
+#
+# CT_TOOLCHAIN_ENABLE_NLS is not set
+
+#
+# Operating System
+#
+CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+# CT_KERNEL_BARE_METAL is not set
+CT_KERNEL_LINUX=y
+CT_KERNEL="linux"
+CT_KERNEL_CHOICE_KSYM="LINUX"
+CT_KERNEL_LINUX_SHOW=y
+
+#
+# Options for linux
+#
+CT_KERNEL_LINUX_PKG_KSYM="LINUX"
+CT_LINUX_DIR_NAME="linux"
+CT_LINUX_PKG_NAME="linux"
+CT_LINUX_SRC_RELEASE=y
+CT_LINUX_PATCH_ORDER="global"
+# CT_LINUX_V_4_20 is not set
+# CT_LINUX_V_4_19 is not set
+# CT_LINUX_V_4_18 is not set
+# CT_LINUX_V_4_17 is not set
+# CT_LINUX_V_4_16 is not set
+# CT_LINUX_V_4_15 is not set
+# CT_LINUX_V_4_14 is not set
+# CT_LINUX_V_4_13 is not set
+# CT_LINUX_V_4_12 is not set
+# CT_LINUX_V_4_11 is not set
+# CT_LINUX_V_4_10 is not set
+# CT_LINUX_V_4_9 is not set
+# CT_LINUX_V_4_4 is not set
+# CT_LINUX_V_4_1 is not set
+# CT_LINUX_V_3_16 is not set
+# CT_LINUX_V_3_13 is not set
+# CT_LINUX_V_3_12 is not set
+# CT_LINUX_V_3_10 is not set
+# CT_LINUX_V_3_4 is not set
+CT_LINUX_V_3_2=y
+# CT_LINUX_V_2_6_32 is not set
+# CT_LINUX_NO_VERSIONS is not set
+CT_LINUX_VERSION="3.2.101"
+CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
+CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
+CT_LINUX_4_8_or_older=y
+CT_LINUX_older_than_4_8=y
+CT_LINUX_3_7_or_older=y
+CT_LINUX_older_than_3_7=y
+CT_LINUX_later_than_3_2=y
+CT_LINUX_3_2_or_later=y
+CT_KERNEL_LINUX_VERBOSITY_0=y
+# CT_KERNEL_LINUX_VERBOSITY_1 is not set
+# CT_KERNEL_LINUX_VERBOSITY_2 is not set
+CT_KERNEL_LINUX_VERBOSE_LEVEL=0
+CT_KERNEL_LINUX_INSTALL_CHECK=y
+CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
+
+#
+# Binary utilities
+#
+CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS_BINUTILS=y
+CT_BINUTILS="binutils"
+CT_BINUTILS_CHOICE_KSYM="BINUTILS"
+CT_BINUTILS_BINUTILS_SHOW=y
+
+#
+# Options for binutils
+#
+CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
+CT_BINUTILS_DIR_NAME="binutils"
+CT_BINUTILS_USE_GNU=y
+CT_BINUTILS_USE="BINUTILS"
+CT_BINUTILS_PKG_NAME="binutils"
+CT_BINUTILS_SRC_RELEASE=y
+CT_BINUTILS_PATCH_ORDER="global"
+CT_BINUTILS_V_2_32=y
+# CT_BINUTILS_V_2_31 is not set
+# CT_BINUTILS_V_2_30 is not set
+# CT_BINUTILS_V_2_29 is not set
+# CT_BINUTILS_V_2_28 is not set
+# CT_BINUTILS_V_2_27 is not set
+# CT_BINUTILS_V_2_26 is not set
+# CT_BINUTILS_NO_VERSIONS is not set
+CT_BINUTILS_VERSION="2.32"
+CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
+CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
+CT_BINUTILS_later_than_2_30=y
+CT_BINUTILS_2_30_or_later=y
+CT_BINUTILS_later_than_2_27=y
+CT_BINUTILS_2_27_or_later=y
+CT_BINUTILS_later_than_2_25=y
+CT_BINUTILS_2_25_or_later=y
+CT_BINUTILS_later_than_2_23=y
+CT_BINUTILS_2_23_or_later=y
+
+#
+# GNU binutils
+#
+CT_BINUTILS_HAS_HASH_STYLE=y
+CT_BINUTILS_HAS_GOLD=y
+CT_BINUTILS_HAS_PLUGINS=y
+CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
+CT_BINUTILS_GOLD_SUPPORTS_ARCH=y
+CT_BINUTILS_GOLD_SUPPORT=y
+CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
+CT_BINUTILS_LINKER_LD=y
+# CT_BINUTILS_LINKER_LD_GOLD is not set
+CT_BINUTILS_LINKERS_LIST="ld"
+CT_BINUTILS_LINKER_DEFAULT="bfd"
+# CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_RELRO=m
+CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
+# CT_BINUTILS_FOR_TARGET is not set
+CT_ALL_BINUTILS_CHOICES="BINUTILS"
+
+#
+# C-library
+#
+CT_LIBC_GLIBC=y
+# CT_LIBC_UCLIBC is not set
+CT_LIBC="glibc"
+CT_LIBC_CHOICE_KSYM="GLIBC"
+CT_THREADS="nptl"
+CT_LIBC_GLIBC_SHOW=y
+
+#
+# Options for glibc
+#
+CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
+CT_GLIBC_DIR_NAME="glibc"
+CT_GLIBC_USE_GNU=y
+CT_GLIBC_USE="GLIBC"
+CT_GLIBC_PKG_NAME="glibc"
+CT_GLIBC_SRC_RELEASE=y
+CT_GLIBC_PATCH_ORDER="global"
+# CT_GLIBC_V_2_29 is not set
+# CT_GLIBC_V_2_28 is not set
+# CT_GLIBC_V_2_27 is not set
+# CT_GLIBC_V_2_26 is not set
+# CT_GLIBC_V_2_25 is not set
+# CT_GLIBC_V_2_24 is not set
+# CT_GLIBC_V_2_23 is not set
+# CT_GLIBC_V_2_19 is not set
+CT_GLIBC_V_2_17=y
+# CT_GLIBC_V_2_12_1 is not set
+# CT_GLIBC_NO_VERSIONS is not set
+CT_GLIBC_VERSION="2.17"
+CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
+CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
+CT_GLIBC_2_29_or_older=y
+CT_GLIBC_older_than_2_29=y
+CT_GLIBC_2_27_or_older=y
+CT_GLIBC_older_than_2_27=y
+CT_GLIBC_2_26_or_older=y
+CT_GLIBC_older_than_2_26=y
+CT_GLIBC_2_25_or_older=y
+CT_GLIBC_older_than_2_25=y
+CT_GLIBC_2_24_or_older=y
+CT_GLIBC_older_than_2_24=y
+CT_GLIBC_2_23_or_older=y
+CT_GLIBC_older_than_2_23=y
+CT_GLIBC_2_20_or_older=y
+CT_GLIBC_older_than_2_20=y
+CT_GLIBC_2_17_or_later=y
+CT_GLIBC_2_17_or_older=y
+CT_GLIBC_later_than_2_14=y
+CT_GLIBC_2_14_or_later=y
+CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
+CT_GLIBC_DEP_BINUTILS=y
+CT_GLIBC_DEP_GCC=y
+CT_GLIBC_DEP_PYTHON=y
+CT_GLIBC_HAS_NPTL_ADDON=y
+CT_GLIBC_HAS_PORTS_ADDON=y
+CT_GLIBC_HAS_LIBIDN_ADDON=y
+CT_GLIBC_USE_NPTL_ADDON=y
+# CT_GLIBC_USE_LIBIDN_ADDON is not set
+CT_GLIBC_HAS_OBSOLETE_RPC=y
+CT_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_GLIBC_CONFIGPARMS=""
+CT_GLIBC_EXTRA_CFLAGS=""
+CT_GLIBC_ENABLE_OBSOLETE_RPC=y
+# CT_GLIBC_DISABLE_VERSIONING is not set
+CT_GLIBC_OLDEST_ABI=""
+CT_GLIBC_FORCE_UNWIND=y
+# CT_GLIBC_LOCALES is not set
+# CT_GLIBC_KERNEL_VERSION_NONE is not set
+CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y
+# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_GLIBC_MIN_KERNEL="3.2.101"
+CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
+CT_LIBC_SUPPORT_THREADS_ANY=y
+CT_LIBC_SUPPORT_THREADS_NATIVE=y
+
+#
+# Common C library options
+#
+CT_THREADS_NATIVE=y
+# CT_CREATE_LDSO_CONF is not set
+CT_LIBC_XLDD=y
+
+#
+# C compiler
+#
+CT_CC_CORE_PASSES_NEEDED=y
+CT_CC_CORE_PASS_1_NEEDED=y
+CT_CC_CORE_PASS_2_NEEDED=y
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
+CT_CC_GCC=y
+CT_CC="gcc"
+CT_CC_CHOICE_KSYM="GCC"
+CT_CC_GCC_SHOW=y
+
+#
+# Options for gcc
+#
+CT_CC_GCC_PKG_KSYM="GCC"
+CT_GCC_DIR_NAME="gcc"
+CT_GCC_USE_GNU=y
+CT_GCC_USE="GCC"
+CT_GCC_PKG_NAME="gcc"
+CT_GCC_SRC_RELEASE=y
+CT_GCC_PATCH_ORDER="global"
+CT_GCC_V_8=y
+# CT_GCC_V_7 is not set
+# CT_GCC_V_6 is not set
+# CT_GCC_V_5 is not set
+# CT_GCC_V_4_9 is not set
+# CT_GCC_NO_VERSIONS is not set
+CT_GCC_VERSION="8.3.0"
+CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
+CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GCC_SIGNATURE_FORMAT=""
+CT_GCC_later_than_7=y
+CT_GCC_7_or_later=y
+CT_GCC_later_than_6=y
+CT_GCC_6_or_later=y
+CT_GCC_later_than_5=y
+CT_GCC_5_or_later=y
+CT_GCC_later_than_4_9=y
+CT_GCC_4_9_or_later=y
+CT_GCC_later_than_4_8=y
+CT_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_LIBMPX=y
+CT_CC_GCC_ENABLE_CXX_FLAGS=""
+CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_STATIC_LIBSTDCXX=y
+# CT_CC_GCC_SYSTEM_ZLIB is not set
+CT_CC_GCC_CONFIG_TLS=m
+
+#
+# Optimisation features
+#
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_USE_LTO=y
+
+#
+# Settings for libraries running on target
+#
+CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y
+# CT_CC_GCC_LIBMUDFLAP is not set
+# CT_CC_GCC_LIBGOMP is not set
+# CT_CC_GCC_LIBSSP is not set
+# CT_CC_GCC_LIBQUADMATH is not set
+# CT_CC_GCC_LIBSANITIZER is not set
+CT_CC_GCC_LIBMPX=y
+
+#
+# Misc. obscure options.
+#
+CT_CC_CXA_ATEXIT=y
+# CT_CC_GCC_DISABLE_PCH is not set
+CT_CC_GCC_SJLJ_EXCEPTIONS=m
+CT_CC_GCC_LDBL_128=m
+# CT_CC_GCC_BUILD_ID is not set
+CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y
+# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
+# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
+# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
+CT_CC_GCC_LNK_HASH_STYLE=""
+CT_CC_GCC_DEC_FLOAT_AUTO=y
+# CT_CC_GCC_DEC_FLOAT_BID is not set
+# CT_CC_GCC_DEC_FLOAT_DPD is not set
+# CT_CC_GCC_DEC_FLOATS_NO is not set
+CT_ALL_CC_CHOICES="GCC"
+
+#
+# Additional supported languages:
+#
+CT_CC_LANG_CXX=y
+# CT_CC_LANG_FORTRAN is not set
+
+#
+# Debug facilities
+#
+# CT_DEBUG_DUMA is not set
+# CT_DEBUG_GDB is not set
+# CT_DEBUG_LTRACE is not set
+# CT_DEBUG_STRACE is not set
+CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
+
+#
+# Companion libraries
+#
+# CT_COMPLIBS_CHECK is not set
+# CT_COMP_LIBS_CLOOG is not set
+# CT_COMP_LIBS_EXPAT is not set
+CT_COMP_LIBS_GETTEXT=y
+CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
+CT_GETTEXT_DIR_NAME="gettext"
+CT_GETTEXT_PKG_NAME="gettext"
+CT_GETTEXT_SRC_RELEASE=y
+CT_GETTEXT_PATCH_ORDER="global"
+CT_GETTEXT_V_0_19_8_1=y
+# CT_GETTEXT_NO_VERSIONS is not set
+CT_GETTEXT_VERSION="0.19.8.1"
+CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
+CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz"
+CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_GMP=y
+CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
+CT_GMP_DIR_NAME="gmp"
+CT_GMP_PKG_NAME="gmp"
+CT_GMP_SRC_RELEASE=y
+CT_GMP_PATCH_ORDER="global"
+CT_GMP_V_6_1=y
+# CT_GMP_NO_VERSIONS is not set
+CT_GMP_VERSION="6.1.2"
+CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
+CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
+CT_GMP_SIGNATURE_FORMAT="packed/.sig"
+CT_GMP_later_than_5_1_0=y
+CT_GMP_5_1_0_or_later=y
+CT_GMP_later_than_5_0_0=y
+CT_GMP_5_0_0_or_later=y
+CT_GMP_REQUIRE_5_0_0_or_later=y
+CT_COMP_LIBS_ISL=y
+CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
+CT_ISL_DIR_NAME="isl"
+CT_ISL_PKG_NAME="isl"
+CT_ISL_SRC_RELEASE=y
+CT_ISL_PATCH_ORDER="global"
+CT_ISL_V_0_20=y
+# CT_ISL_V_0_19 is not set
+# CT_ISL_V_0_18 is not set
+# CT_ISL_V_0_17 is not set
+# CT_ISL_V_0_16 is not set
+# CT_ISL_V_0_15 is not set
+# CT_ISL_NO_VERSIONS is not set
+CT_ISL_VERSION="0.20"
+CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc"
+CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_ISL_SIGNATURE_FORMAT=""
+CT_ISL_later_than_0_18=y
+CT_ISL_0_18_or_later=y
+CT_ISL_later_than_0_15=y
+CT_ISL_0_15_or_later=y
+CT_ISL_REQUIRE_0_15_or_later=y
+CT_ISL_later_than_0_14=y
+CT_ISL_0_14_or_later=y
+CT_ISL_REQUIRE_0_14_or_later=y
+CT_ISL_later_than_0_13=y
+CT_ISL_0_13_or_later=y
+CT_ISL_later_than_0_12=y
+CT_ISL_0_12_or_later=y
+CT_ISL_REQUIRE_0_12_or_later=y
+# CT_COMP_LIBS_LIBELF is not set
+CT_COMP_LIBS_LIBICONV=y
+CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
+CT_LIBICONV_DIR_NAME="libiconv"
+CT_LIBICONV_PKG_NAME="libiconv"
+CT_LIBICONV_SRC_RELEASE=y
+CT_LIBICONV_PATCH_ORDER="global"
+CT_LIBICONV_V_1_15=y
+# CT_LIBICONV_NO_VERSIONS is not set
+CT_LIBICONV_VERSION="1.15"
+CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
+CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
+CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_MPC=y
+CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
+CT_MPC_DIR_NAME="mpc"
+CT_MPC_PKG_NAME="mpc"
+CT_MPC_SRC_RELEASE=y
+CT_MPC_PATCH_ORDER="global"
+CT_MPC_V_1_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_NO_VERSIONS is not set
+CT_MPC_VERSION="1.1.0"
+CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
+CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_FORMATS=".tar.gz"
+CT_MPC_SIGNATURE_FORMAT="packed/.sig"
+CT_MPC_1_1_0_or_later=y
+CT_MPC_1_1_0_or_older=y
+CT_COMP_LIBS_MPFR=y
+CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
+CT_MPFR_DIR_NAME="mpfr"
+CT_MPFR_PKG_NAME="mpfr"
+CT_MPFR_SRC_RELEASE=y
+CT_MPFR_PATCH_ORDER="global"
+CT_MPFR_V_4_0=y
+# CT_MPFR_V_3_1 is not set
+# CT_MPFR_NO_VERSIONS is not set
+CT_MPFR_VERSION="4.0.2"
+CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
+CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
+CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
+CT_MPFR_later_than_4_0_0=y
+CT_MPFR_4_0_0_or_later=y
+CT_MPFR_later_than_3_0_0=y
+CT_MPFR_3_0_0_or_later=y
+CT_MPFR_REQUIRE_3_0_0_or_later=y
+CT_COMP_LIBS_NCURSES=y
+CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
+CT_NCURSES_DIR_NAME="ncurses"
+CT_NCURSES_PKG_NAME="ncurses"
+CT_NCURSES_SRC_RELEASE=y
+CT_NCURSES_PATCH_ORDER="global"
+CT_NCURSES_V_6_1=y
+# CT_NCURSES_V_6_0 is not set
+# CT_NCURSES_NO_VERSIONS is not set
+CT_NCURSES_VERSION="6.1"
+CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
+CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
+CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
+CT_NCURSES_HOST_CONFIG_ARGS=""
+CT_NCURSES_HOST_DISABLE_DB=y
+CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
+CT_NCURSES_TARGET_CONFIG_ARGS=""
+# CT_NCURSES_TARGET_DISABLE_DB is not set
+CT_NCURSES_TARGET_FALLBACKS=""
+CT_COMP_LIBS_ZLIB=y
+CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB"
+CT_ZLIB_DIR_NAME="zlib"
+CT_ZLIB_PKG_NAME="zlib"
+CT_ZLIB_SRC_RELEASE=y
+CT_ZLIB_PATCH_ORDER="global"
+CT_ZLIB_V_1_2_11=y
+# CT_ZLIB_NO_VERSIONS is not set
+CT_ZLIB_VERSION="1.2.11"
+CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_ZLIB_SIGNATURE_FORMAT="packed/.asc"
+CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
+CT_LIBICONV_NEEDED=y
+CT_GETTEXT_NEEDED=y
+CT_GMP_NEEDED=y
+CT_MPFR_NEEDED=y
+CT_ISL_NEEDED=y
+CT_MPC_NEEDED=y
+CT_NCURSES_NEEDED=y
+CT_ZLIB_NEEDED=y
+CT_LIBICONV=y
+CT_GETTEXT=y
+CT_GMP=y
+CT_MPFR=y
+CT_ISL=y
+CT_MPC=y
+CT_NCURSES=y
+CT_ZLIB=y
+
+#
+# Companion tools
+#
+# CT_COMP_TOOLS_FOR_HOST is not set
+# CT_COMP_TOOLS_AUTOCONF is not set
+# CT_COMP_TOOLS_AUTOMAKE is not set
+# CT_COMP_TOOLS_BISON is not set
+# CT_COMP_TOOLS_DTC is not set
+# CT_COMP_TOOLS_LIBTOOL is not set
+# CT_COMP_TOOLS_M4 is not set
+# CT_COMP_TOOLS_MAKE is not set
+CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 126c292b38e..8250ec0c311 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -129,4 +129,6 @@ ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \
   --set target.wasm32-wasi.wasi-root=/wasm32-wasi \
   --musl-root-armv7=/musl-armv7
 
+ENV EXTERNAL_LLVM 1
+
 ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
index 23f2215c2d9..1289f116fe9 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
@@ -29,6 +29,7 @@ RUN sh /scripts/sccache.sh
 # We are disabling CI LLVM since this builder is intentionally using a host
 # LLVM, rather than the typical src/llvm-project LLVM.
 ENV NO_DOWNLOAD_CI_LLVM 1
+ENV EXTERNAL_LLVM 1
 
 # Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
index 8f6831bc54e..4b89a72baa1 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
@@ -40,6 +40,7 @@ RUN sh /scripts/sccache.sh
 # We are disabling CI LLVM since this builder is intentionally using a host
 # LLVM, rather than the typical src/llvm-project LLVM.
 ENV NO_DOWNLOAD_CI_LLVM 1
+ENV EXTERNAL_LLVM 1
 
 # Using llvm-link-shared due to libffi issues -- see #34486
 ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 9a247fb60a8..9d98ce22498 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -69,6 +69,11 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1"
 # space required for CI artifacts.
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz"
 
+# Enable the `c` feature for compiler_builtins, but only when the `compiler-rt` source is available.
+if [ "$EXTERNAL_LLVM" = "" ]; then
+  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins"
+fi
+
 if [ "$DIST_SRC" = "" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
 fi
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index ea2792c218b..a36518cc8ce 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -144,7 +144,7 @@ target | std | notes
 `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat
 `asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten
 `i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE
-`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
+`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17)
 `i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL
 [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android
 `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD
diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis
index a4e8a57e4b1..624d8cc5cc5 100644
--- a/src/etc/natvis/libcore.natvis
+++ b/src/etc/natvis/libcore.natvis
@@ -154,10 +154,10 @@
   </Type>
 
   <Type Name="core::time::Duration">
-    <DisplayString>{secs,d}s {nanos,d}ns</DisplayString>
+    <DisplayString>{secs,d}s {nanos.__0,d}ns</DisplayString>
     <Expand>
       <Item Name="seconds">secs,d</Item>
-      <Item Name="nanoseconds">nanos,d</Item>
+      <Item Name="nanoseconds">nanos.__0,d</Item>
     </Expand>
   </Type>
 </AutoVisualizer>
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index c8aa51c3a49..7893429f26f 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -718,10 +718,6 @@ pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
     debug!("record_extern_trait: {:?}", did);
     let trait_ = build_external_trait(cx, did);
 
-    let trait_ = clean::TraitWithExtraInfo {
-        trait_,
-        is_notable: clean::utils::has_doc_flag(cx.tcx, did, sym::notable_trait),
-    };
     cx.external_traits.borrow_mut().insert(did, trait_);
     cx.active_extern_traits.remove(&did);
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 704292c1048..c61175ecebf 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1176,6 +1176,15 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
             }
 
             if let ty::TraitContainer = assoc_item.container {
+                // FIXME(fmease): `tcx.explicit_item_bounds` does not contain the bounds of GATs,
+                //                e.g. the bounds `Copy`, `Display` & (implicitly) `Sized` in
+                //                `type Assoc<T: Copy> where T: Display`. This also means that we
+                //                later incorrectly render `where T: ?Sized`.
+                //
+                //                The result of `tcx.explicit_predicates_of` *does* contain them but
+                //                it does not contain the other bounds / predicates we need.
+                //                Either merge those two interned lists somehow or refactor
+                //                `clean_ty_generics` to call `explicit_item_bounds` by itself.
                 let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
                 let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
                 let mut generics =
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index af7813a7740..f82ea8969ab 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -14,7 +14,6 @@
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty;
-use rustc_span::Symbol;
 
 use crate::clean;
 use crate::clean::GenericArgs as PP;
@@ -26,21 +25,17 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     //
     // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to
     // the order of the generated bounds.
-    let mut params: FxIndexMap<Symbol, (Vec<_>, Vec<_>)> = FxIndexMap::default();
+    let mut tybounds = FxIndexMap::default();
     let mut lifetimes = Vec::new();
     let mut equalities = Vec::new();
-    let mut tybounds = Vec::new();
 
     for clause in clauses {
         match clause {
-            WP::BoundPredicate { ty, bounds, bound_params } => match ty {
-                clean::Generic(s) => {
-                    let (b, p) = params.entry(s).or_default();
-                    b.extend(bounds);
-                    p.extend(bound_params);
-                }
-                t => tybounds.push((t, (bounds, bound_params))),
-            },
+            WP::BoundPredicate { ty, bounds, bound_params } => {
+                let (b, p): &mut (Vec<_>, Vec<_>) = tybounds.entry(ty).or_default();
+                b.extend(bounds);
+                p.extend(bound_params);
+            }
             WP::RegionPredicate { lifetime, bounds } => {
                 lifetimes.push((lifetime, bounds));
             }
@@ -49,14 +44,17 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     }
 
     // Look for equality predicates on associated types that can be merged into
-    // general bound predicates
+    // general bound predicates.
     equalities.retain(|&(ref lhs, ref rhs)| {
-        let Some((self_, trait_did, name)) = lhs.projection() else {
-            return true;
-        };
-        let clean::Generic(generic) = self_ else { return true };
-        let Some((bounds, _)) = params.get_mut(generic) else { return true };
-
+        let Some((ty, trait_did, name)) = lhs.projection() else { return true; };
+        // FIXME(fmease): We don't handle HRTBs correctly here.
+        //                Pass `_bound_params` (higher-rank lifetimes) to a modified version of
+        //                `merge_bounds`. That vector is currently always empty though since we
+        //                don't keep track of late-bound lifetimes when cleaning projection
+        //                predicates to cleaned equality predicates while we should first query
+        //                them with `collect_referenced_late_bound_regions` and then store them
+        //                (or something similar). For prior art, see `clean::auto_trait`.
+        let Some((bounds, _bound_params)) = tybounds.get_mut(ty) else { return true };
         merge_bounds(cx, bounds, trait_did, name, rhs)
     });
 
@@ -65,11 +63,6 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     clauses.extend(
         lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
     );
-    clauses.extend(params.into_iter().map(|(k, (bounds, params))| WP::BoundPredicate {
-        ty: clean::Generic(k),
-        bounds,
-        bound_params: params,
-    }));
     clauses.extend(tybounds.into_iter().map(|(ty, (bounds, bound_params))| WP::BoundPredicate {
         ty,
         bounds,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index e53e93c4def..5a4fa05e261 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -119,7 +119,7 @@ pub(crate) struct Crate {
     pub(crate) module: Item,
     pub(crate) primitives: ThinVec<(DefId, PrimitiveType)>,
     /// Only here so that they can be filtered through the rustdoc passes.
-    pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>,
+    pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
 }
 
 impl Crate {
@@ -132,13 +132,6 @@ impl Crate {
     }
 }
 
-/// This struct is used to wrap additional information added by rustdoc on a `trait` item.
-#[derive(Clone, Debug)]
-pub(crate) struct TraitWithExtraInfo {
-    pub(crate) trait_: Trait,
-    pub(crate) is_notable: bool,
-}
-
 #[derive(Copy, Clone, Debug)]
 pub(crate) struct ExternalCrate {
     pub(crate) crate_num: CrateNum,
@@ -689,7 +682,7 @@ impl Item {
                 let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi();
                 hir::FnHeader {
                     unsafety: if abi == Abi::RustIntrinsic {
-                        intrinsic_operation_unsafety(self.name.unwrap())
+                        intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap())
                     } else {
                         hir::Unsafety::Unsafe
                     },
@@ -1530,6 +1523,9 @@ impl Trait {
     pub(crate) fn is_auto(&self, tcx: TyCtxt<'_>) -> bool {
         tcx.trait_is_auto(self.def_id)
     }
+    pub(crate) fn is_notable_trait(&self, tcx: TyCtxt<'_>) -> bool {
+        tcx.is_doc_notable_trait(self.def_id)
+    }
     pub(crate) fn unsafety(&self, tcx: TyCtxt<'_>) -> hir::Unsafety {
         tcx.trait_def(self.def_id).unsafety
     }
@@ -2201,8 +2197,11 @@ impl Path {
     /// Checks if this is a `T::Name` path for an associated type.
     pub(crate) fn is_assoc_ty(&self) -> bool {
         match self.res {
-            Res::SelfTy { .. } if self.segments.len() != 1 => true,
-            Res::Def(DefKind::TyParam, _) if self.segments.len() != 1 => true,
+            Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _)
+                if self.segments.len() != 1 =>
+            {
+                true
+            }
             Res::Def(DefKind::AssocTy, _) => true,
             _ => false,
         }
@@ -2535,11 +2534,11 @@ mod size_asserts {
     // These are in alphabetical order, which is easy to maintain.
     static_assert_size!(Crate, 72); // frequently moved by-value
     static_assert_size!(DocFragment, 32);
-    static_assert_size!(GenericArg, 56);
+    static_assert_size!(GenericArg, 48);
     static_assert_size!(GenericArgs, 32);
     static_assert_size!(GenericParamDef, 56);
     static_assert_size!(Item, 56);
-    static_assert_size!(ItemKind, 96);
+    static_assert_size!(ItemKind, 88);
     static_assert_size!(PathSegment, 40);
-    static_assert_size!(Type, 56);
+    static_assert_size!(Type, 48);
 }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index edcd81061f8..6b844710514 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -454,7 +454,9 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
 
     match path.res {
         Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
-        Res::SelfTy { .. } if path.segments.len() == 1 => Generic(kw::SelfUpper),
+        Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => {
+            Generic(kw::SelfUpper)
+        }
         Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
         _ => {
             let _ = register_res(cx, path.res);
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 09a26cbac3e..b463b934e29 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -25,7 +25,7 @@ use std::rc::Rc;
 use std::sync::LazyLock;
 
 use crate::clean::inline::build_external_trait;
-use crate::clean::{self, ItemId, TraitWithExtraInfo};
+use crate::clean::{self, ItemId};
 use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
 use crate::formats::cache::Cache;
 use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink;
@@ -58,7 +58,7 @@ pub(crate) struct DocContext<'tcx> {
     /// Most of this logic is copied from rustc_lint::late.
     pub(crate) param_env: ParamEnv<'tcx>,
     /// Later on moved through `clean::Crate` into `cache`
-    pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, clean::TraitWithExtraInfo>>>,
+    pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>,
     /// Used while populating `external_traits` to ensure we don't process the same trait twice at
     /// the same time.
     pub(crate) active_extern_traits: FxHashSet<DefId>,
@@ -388,9 +388,7 @@ pub(crate) fn run_global_ctxt(
     // Note that in case of `#![no_core]`, the trait is not available.
     if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() {
         let sized_trait = build_external_trait(&mut ctxt, sized_trait_did);
-        ctxt.external_traits
-            .borrow_mut()
-            .insert(sized_trait_did, TraitWithExtraInfo { trait_: sized_trait, is_notable: false });
+        ctxt.external_traits.borrow_mut().insert(sized_trait_did, sized_trait);
     }
 
     debug!("crate: {:?}", tcx.hir().krate());
@@ -406,12 +404,8 @@ pub(crate) fn run_global_ctxt(
         tcx.struct_lint_node(
             crate::lint::MISSING_CRATE_LEVEL_DOCS,
             DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(),
-            |lint| {
-                let mut diag =
-                    lint.build("no documentation found for this crate's top-level module");
-                diag.help(&help);
-                diag.emit();
-            },
+            "no documentation found for this crate's top-level module",
+            |lint| lint.help(help),
         );
     }
 
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 20ae102bc27..f4ec60735a8 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1134,6 +1134,7 @@ impl Tester for Collector {
 
                     panic::resume_unwind(Box::new(()));
                 }
+                Ok(())
             })),
         });
     }
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index ed702f5c4a9..c6f1f9de51a 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -94,7 +94,7 @@ pub(crate) trait DocFolder: Sized {
 
         let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) };
         for (k, mut v) in external_traits {
-            v.trait_.items = v.trait_.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
+            v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
             c.external_traits.borrow_mut().insert(k, v);
         }
 
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 86392610d2c..2e428cfddcf 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_middle::middle::privacy::AccessLevels;
 use rustc_middle::ty::{self, TyCtxt};
-use rustc_span::{sym, Symbol};
+use rustc_span::Symbol;
 
 use crate::clean::{self, types::ExternalLocation, ExternalCrate, ItemId, PrimitiveType};
 use crate::core::DocContext;
@@ -62,7 +62,7 @@ pub(crate) struct Cache {
     /// Implementations of a crate should inherit the documentation of the
     /// parent trait if no extra documentation is specified, and default methods
     /// should show up in documentation about trait implementations.
-    pub(crate) traits: FxHashMap<DefId, clean::TraitWithExtraInfo>,
+    pub(crate) traits: FxHashMap<DefId, clean::Trait>,
 
     /// When rendering traits, it's often useful to be able to list all
     /// implementors of the trait, and this mapping is exactly, that: a mapping
@@ -225,12 +225,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
         // Propagate a trait method's documentation to all implementors of the
         // trait.
         if let clean::TraitItem(ref t) = *item.kind {
-            self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| {
-                clean::TraitWithExtraInfo {
-                    trait_: *t.clone(),
-                    is_notable: item.attrs.has_doc_flag(sym::notable_trait),
-                }
-            });
+            self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| (**t).clone());
         }
 
         // Collect all the implementors of traits.
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index b499e186cc0..6d46267931b 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1010,15 +1010,25 @@ fn fmt_type<'cx>(
                 write!(f, "]")
             }
         },
-        clean::Array(ref t, ref n) => {
-            primitive_link(f, PrimitiveType::Array, "[", cx)?;
-            fmt::Display::fmt(&t.print(cx), f)?;
-            if f.alternate() {
-                primitive_link(f, PrimitiveType::Array, &format!("; {}]", n), cx)
-            } else {
-                primitive_link(f, PrimitiveType::Array, &format!("; {}]", Escape(n)), cx)
+        clean::Array(ref t, ref n) => match **t {
+            clean::Generic(name) if !f.alternate() => primitive_link(
+                f,
+                PrimitiveType::Array,
+                &format!("[{name}; {n}]", n = Escape(n)),
+                cx,
+            ),
+            _ => {
+                write!(f, "[")?;
+                fmt::Display::fmt(&t.print(cx), f)?;
+                if f.alternate() {
+                    write!(f, "; {n}")?;
+                } else {
+                    write!(f, "; ")?;
+                    primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?;
+                }
+                write!(f, "]")
             }
-        }
+        },
         clean::RawPointer(m, ref t) => {
             let m = match m {
                 hir::Mutability::Mut => "mut",
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 8e53fbbcd19..68eb5008583 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -813,11 +813,8 @@ impl<'tcx> ExtraInfo<'tcx> {
             crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
             hir_id,
             self.sp,
-            |lint| {
-                let mut diag = lint.build(msg);
-                diag.help(help);
-                diag.emit();
-            },
+            msg,
+            |lint| lint.help(help),
         );
     }
 }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 75ac11a3a88..aa9788fad2b 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1294,7 +1294,12 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
                 if let Some(trait_) = &impl_.trait_ {
                     let trait_did = trait_.def_id();
 
-                    if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable) {
+                    if cx
+                        .cache()
+                        .traits
+                        .get(&trait_did)
+                        .map_or(false, |t| t.is_notable_trait(cx.tcx()))
+                    {
                         if out.is_empty() {
                             write!(
                                 &mut out,
@@ -1598,7 +1603,7 @@ fn render_impl(
             link,
             render_mode,
             false,
-            trait_.map(|t| &t.trait_),
+            trait_,
             rendering_params,
         );
     }
@@ -1658,7 +1663,7 @@ fn render_impl(
                 &mut default_impl_items,
                 &mut impl_items,
                 cx,
-                &t.trait_,
+                t,
                 i.inner_impl(),
                 &i.impl_item,
                 parent,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 3e324bbb069..7bd0dbf9325 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -716,9 +716,9 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
         document(&mut content, cx, m, Some(t), HeadingOffset::H5);
         let toggled = !content.is_empty();
         if toggled {
-            write!(w, "<details class=\"rustdoc-toggle\" open><summary>");
+            write!(w, "<details class=\"rustdoc-toggle method-toggle\" open><summary>");
         }
-        write!(w, "<div id=\"{}\" class=\"method has-srclink\">", id);
+        write!(w, "<section id=\"{}\" class=\"method has-srclink\">", id);
         render_rightside(w, cx, m, t, RenderMode::Normal);
         write!(w, "<h4 class=\"code-header\">");
         render_assoc_item(
@@ -730,7 +730,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
             RenderMode::Normal,
         );
         w.write_str("</h4>");
-        w.write_str("</div>");
+        w.write_str("</section>");
         if toggled {
             write!(w, "</summary>");
             w.push_buffer(content);
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 0ea6d9c38b6..140ce3ba9fc 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -138,6 +138,13 @@ h1, h2, h3, h4 {
 .docblock h3, .docblock h4, h5, h6 {
 	margin: 15px 0 5px 0;
 }
+.docblock > h2:first-child,
+.docblock > h3:first-child,
+.docblock > h4:first-child,
+.docblock > h5:first-child,
+.docblock > h6:first-child {
+	margin-top: 0;
+}
 h1.fqn {
 	margin: 0;
 	padding: 0;
@@ -177,36 +184,20 @@ h4.code-header {
 	margin: 0;
 	padding: 0;
 }
-.impl,
-.impl-items .method,
-.methods .method,
-.impl-items .type,
-.methods .type,
-.impl-items .associatedconstant,
-.methods .associatedconstant,
-.impl-items .associatedtype,
-.methods .associatedtype {
-	flex-basis: 100%;
-	font-weight: 600;
-	position: relative;
-}
 
+#crate-search,
 h1, h2, h3, h4, h5, h6,
 .sidebar,
 .mobile-topbar,
-a.source,
 .search-input,
 .search-results .result-name,
 .item-left > a,
 .out-of-band,
 span.since,
-details.rustdoc-toggle > summary::before,
 a.srclink,
 #help-button > button,
 details.rustdoc-toggle.top-doc > summary,
-details.rustdoc-toggle.top-doc > summary::before,
 details.rustdoc-toggle.non-exhaustive > summary,
-details.rustdoc-toggle.non-exhaustive > summary::before,
 .scraped-example-title,
 .more-examples-toggle summary, .more-examples-toggle .hide-more,
 .example-links a,
@@ -304,16 +295,6 @@ summary {
 
 /* Fix some style changes due to normalize.css 8 */
 
-button,
-input,
-optgroup,
-select,
-textarea {
-	color: inherit;
-	font: inherit;
-	margin: 0;
-}
-
 button {
 	/* Buttons on Safari have different default padding than other platforms. Make them the same. */
 	padding: 1px 6px;
@@ -451,7 +432,6 @@ img {
 }
 
 .source .sidebar > *:not(#sidebar-toggle) {
-	opacity: 0;
 	visibility: hidden;
 }
 
@@ -460,7 +440,6 @@ img {
 }
 
 .source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
-	opacity: 1;
 	visibility: visible;
 }
 
@@ -550,6 +529,14 @@ h2.location a {
 	margin: 0;
 }
 
+.sidebar a, .sidebar .current {
+	color: var(--sidebar-link-color);
+}
+.sidebar .current,
+.sidebar a:hover {
+	background-color: var(--sidebar-current-link-background-color);
+}
+
 .sidebar-elems .block {
 	margin-bottom: 2em;
 }
@@ -667,10 +654,6 @@ pre.example-line-numbers {
 	font-weight: normal;
 }
 
-.method > .code-header, .trait-impl > .code-header {
-	display: block;
-}
-
 .in-band {
 	flex-grow: 1;
 	margin: 0px;
@@ -887,6 +870,9 @@ table,
 	/* Removes default arrow from firefox */
 	text-indent: 0.01px;
 	background-color: var(--main-background-color);
+	color: inherit;
+	line-height: 1.5;
+	font-weight: 500;
 }
 /* cancel stylistic differences in padding in firefox
 for "appearance: none"-style (or equivalent) <select>s */
@@ -977,6 +963,11 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	padding-right: 1em;
 }
 
+.search-results a:hover,
+.search-results a:focus {
+	background-color: var(--search-result-link-focus-background-color);
+}
+
 .popover {
 	font-size: 1rem;
 	position: absolute;
@@ -1057,6 +1048,13 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	margin-bottom: 5px;
 	font-size: 0.875rem;
 	font-weight: normal;
+	color: var(--main-color);
+	background-color: var(--stab-background-color);
+}
+
+.stab.portability > code {
+	background: none;
+	color: var(--stab-code-color);
 }
 
 .stab .emoji {
@@ -1247,13 +1245,11 @@ h3.variant {
 	font-weight: 600;
 	font-size: 1.125rem;
 	margin-bottom: 10px;
-	border-bottom: none;
 }
 
 .sub-variant h4 {
 	font-size: 1rem;
 	font-weight: 400;
-	border-bottom: none;
 	margin-top: 0;
 	margin-bottom: 0;
 }
@@ -1322,11 +1318,6 @@ h3.variant {
 	font-size: 1.25rem;
 }
 
-/* Example code has the "Run" button that needs to be positioned relative to the pre */
-pre.rust.rust-example-rendered {
-	position: relative;
-}
-
 pre.rust {
 	tab-size: 4;
 	-moz-tab-size: 4;
@@ -1363,6 +1354,8 @@ pre.rust {
 	border: 0;
 	border-top: 2px solid;
 	flex: 1;
+	line-height: 1.5;
+	color: inherit;
 }
 
 #titles > button > div.count {
@@ -1380,7 +1373,6 @@ pre.rust {
 	position: sticky;
 	top: 0;
 	left: 0;
-	font-weight: bold;
 	font-size: 1.25rem;
 	border-bottom: 1px solid;
 	display: flex;
@@ -1400,6 +1392,8 @@ pre.rust {
 	margin-bottom: 6px;
 }
 #sidebar-toggle > button {
+	font-size: inherit;
+	font-weight: bold;
 	background: none;
 	color: inherit;
 	cursor: pointer;
@@ -1428,6 +1422,7 @@ pre.rust {
 	border: 1px solid var(--border-color);
 	border-radius: 2px;
 	cursor: pointer;
+	line-height: 1.5;
 }
 
 #settings-menu > a, #help-button > button {
@@ -1570,7 +1565,6 @@ details.rustdoc-toggle > summary::before {
 }
 
 details.rustdoc-toggle > summary.hideme > span,
-details.rustdoc-toggle > summary::before,
 .more-examples-toggle summary, .more-examples-toggle .hide-more {
 	color: var(--toggles-color);
 }
@@ -1832,6 +1826,7 @@ in storage.js plus the media query with (min-width: 701px)
 		   as an icon, it's okay to specify its sizes in pixels. */
 		font-size: 32px;
 		border: none;
+		color: var(--main-color);
 	}
 
 	.sidebar-elems {
@@ -1887,7 +1882,6 @@ in storage.js plus the media query with (min-width: 701px)
 		border-top-right-radius: 3px;
 		border-bottom-right-radius: 3px;
 		cursor: pointer;
-		font-weight: bold;
 		border: 1px solid;
 		border-left: 0;
 	}
@@ -2011,7 +2005,11 @@ in storage.js plus the media query with (min-width: 701px)
 
 .method-toggle summary,
 .implementors-toggle summary,
-.impl {
+.impl,
+#implementors-list > .docblock,
+.impl-items > section,
+.methods > section
+{
 	margin-bottom: 0.75em;
 }
 
diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css
index e82ec042637..821c4e978e8 100644
--- a/src/librustdoc/html/static/css/settings.css
+++ b/src/librustdoc/html/static/css/settings.css
@@ -12,7 +12,8 @@
 	margin-right: 0.3em;
 	height: 1.2rem;
 	width: 1.2rem;
-	border: 1px solid;
+	color: inherit;
+	border: 1px solid currentColor;
 	outline: none;
 	-webkit-appearance: none;
 	cursor: pointer;
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 44238ca573d..7245dce6ed6 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -35,6 +35,11 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--keyword-link-color: #39afd7;
 	--mod-link-color: #39afd7;
 	--link-color: #39afd7;
+	--sidebar-link-color: #53b1db;
+	--sidebar-current-link-background-color: transparent;
+	--search-result-link-focus-background-color: #3c3c3c;
+	--stab-background-color: #314559;
+	--stab-code-color: #e6e1cf;
 }
 
 .slider {
@@ -85,7 +90,6 @@ pre, .rustdoc.source .example-wrap {
 
 .sidebar .current,
 .sidebar a:hover {
-	background-color: transparent;
 	color: #ffb44c;
 }
 
@@ -119,9 +123,6 @@ pre, .rustdoc.source .example-wrap {
 
 .content .item-info::before { color: #ccc; }
 
-.sidebar a { color: #53b1db; }
-.sidebar a.current.type { color: #53b1db; }
-
 pre.rust .comment { color: #788797; }
 pre.rust .doccomment { color: #a1ac88; }
 
@@ -157,16 +158,6 @@ details.rustdoc-toggle > summary::before {
 	color: #000;
 }
 
-.stab {
-	color: #c5c5c5;
-	background: #314559 !important;
-}
-
-.stab.portability > code {
-	color: #e6e1cf;
-	background: none;
-}
-
 .result-name .primitive > i, .result-name .keyword > i {
 	color: #788797;
 }
@@ -260,45 +251,6 @@ pre.rust .kw {}
 pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {}
 pre.rust .kw-2, pre.rust .prelude-ty {}
 
-.search-results a:focus span {}
-a.result-trait:focus {}
-a.result-traitalias:focus {}
-a.result-mod:focus,
-a.result-externcrate:focus {}
-a.result-mod:focus {}
-a.result-externcrate:focus {}
-a.result-enum:focus {}
-a.result-struct:focus {}
-a.result-union:focus {}
-a.result-fn:focus,
-a.result-method:focus,
-a.result-tymethod:focus {}
-a.result-type:focus {}
-a.result-associatedtype:focus {}
-a.result-foreigntype:focus {}
-a.result-attr:focus,
-a.result-derive:focus,
-a.result-macro:focus {}
-a.result-constant:focus,
-a.result-static:focus {}
-a.result-primitive:focus {}
-a.result-keyword:focus {}
-
-.sidebar a.current.enum {}
-.sidebar a.current.struct {}
-.sidebar a.current.foreigntype {}
-.sidebar a.current.attr,
-.sidebar a.current.derive,
-.sidebar a.current.macro {}
-.sidebar a.current.union {}
-.sidebar a.current.constant
-.sidebar a.current.static {}
-.sidebar a.current.primitive {}
-.sidebar a.current.trait {}
-.sidebar a.current.traitalias {}
-.sidebar a.current.fn {}
-.sidebar a.current.keyword {}
-
 kbd {
 	color: #c5c5c5;
 	background-color: #314559;
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 858d836c03d..9d5406e65a8 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -30,6 +30,11 @@
 	--keyword-link-color: #d2991d;
 	--mod-link-color:  #d2991d;
 	--link-color: #d2991d;
+	--sidebar-link-color: #fdbf35;
+	--sidebar-current-link-background-color: #444;
+	--search-result-link-focus-background-color: #616161;
+	--stab-background-color: #314559;
+	--stab-code-color: #e6e1cf;
 }
 
 .slider {
@@ -49,65 +54,13 @@ input:focus + .slider {
 		drop-shadow(0 -1px 0 #fff)
 }
 
-.sidebar .current,
-.sidebar a:hover {
-	background: #444;
-}
-
 .src-line-numbers span { color: #3B91E2; }
 .src-line-numbers .line-highlighted {
 	background-color: #0a042f !important;
 }
 
-.search-results a:hover {
-	background-color: #777;
-}
-
-.search-results a:focus {
-	color: #eee !important;
-	background-color: #616161;
-}
-.search-results a:focus span { color: #eee !important; }
-a.result-trait:focus { background-color: #013191; }
-a.result-traitalias:focus { background-color: #013191; }
-a.result-mod:focus,
-a.result-externcrate:focus { background-color: #884719; }
-a.result-enum:focus { background-color: #194e9f; }
-a.result-struct:focus { background-color: #194e9f; }
-a.result-union:focus { background-color: #194e9f; }
-a.result-fn:focus,
-a.result-method:focus,
-a.result-tymethod:focus { background-color: #4950ed; }
-a.result-type:focus { background-color: #194e9f; }
-a.result-associatedtype:focus { background-color: #884719; }
-a.result-foreigntype:focus { background-color: #194e9f; }
-a.result-attr:focus,
-a.result-derive:focus,
-a.result-macro:focus { background-color: #217d1c; }
-a.result-constant:focus,
-a.result-static:focus { background-color: #884719; }
-a.result-primitive:focus { background-color: #194e9f; }
-a.result-keyword:focus { background-color: #884719; }
-
 .content .item-info::before { color: #ccc; }
 
-.sidebar a { color: #fdbf35; }
-.sidebar a.current.enum { color: #12ece2; }
-.sidebar a.current.struct { color: #12ece2; }
-.sidebar a.current.type { color: #12ece2; }
-.sidebar a.current.foreigntype { color: #12ece2; }
-.sidebar a.current.attr,
-.sidebar a.current.derive,
-.sidebar a.current.macro { color: #0be900; }
-.sidebar a.current.union { color: #12ece2; }
-.sidebar a.current.constant
-.sidebar a.current.static { color: #fdbf35; }
-.sidebar a.current.primitive { color: #12ece2; }
-.sidebar a.current.trait { color: #cca7ff; }
-.sidebar a.current.traitalias { color: #cca7ff; }
-.sidebar a.current.fn { color: #32d479; }
-.sidebar a.current.keyword { color: #fdbf35; }
-
 pre.rust .comment { color: #8d8d8b; }
 pre.rust .doccomment { color: #8ca375; }
 
@@ -134,13 +87,6 @@ details.rustdoc-toggle > summary::before {
 	filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
 }
 
-.stab { background: #314559; }
-
-.stab.portability > code {
-	color: #e6e1cf;
-	background: none;
-}
-
 .src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 6fbea6f6c7a..b63895e56c6 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -30,6 +30,11 @@
 	--keyword-link-color: #3873ad;
 	--mod-link-color: #3873ad;
 	--link-color: #3873ad;
+	--sidebar-link-color: #356da4;
+	--sidebar-current-link-background-color: #fff;
+	--search-result-link-focus-background-color: #ccc;
+	--stab-background-color: #fff5d6;
+	--stab-code-color: #000;
 }
 
 .slider {
@@ -48,65 +53,13 @@ input:focus + .slider {
 	 */
 }
 
-.sidebar .current,
-.sidebar a:hover {
-	background-color: #fff;
-}
-
 .src-line-numbers span { color: #c67e2d; }
 .src-line-numbers .line-highlighted {
 	background-color: #FDFFD3 !important;
 }
 
-.search-results a:hover {
-	background-color: #ddd;
-}
-
-.search-results a:focus {
-	color: #000 !important;
-	background-color: #ccc;
-}
-.search-results a:focus span { color: #000 !important; }
-a.result-trait:focus { background-color: #c7b6ff; }
-a.result-traitalias:focus { background-color: #c7b6ff; }
-a.result-mod:focus,
-a.result-externcrate:focus { background-color: #afc6e4; }
-a.result-enum:focus { background-color: #e7b1a0; }
-a.result-struct:focus { background-color: #e7b1a0; }
-a.result-union:focus { background-color: #e7b1a0; }
-a.result-fn:focus,
-a.result-method:focus,
-a.result-tymethod:focus { background-color: #c6afb3; }
-a.result-type:focus { background-color: #e7b1a0; }
-a.result-associatedtype:focus { background-color: #afc6e4; }
-a.result-foreigntype:focus { background-color: #e7b1a0; }
-a.result-attr:focus,
-a.result-derive:focus,
-a.result-macro:focus { background-color: #8ce488; }
-a.result-constant:focus,
-a.result-static:focus { background-color: #afc6e4; }
-a.result-primitive:focus { background-color: #e7b1a0; }
-a.result-keyword:focus { background-color: #afc6e4; }
-
 .content .item-info::before { color: #ccc; }
 
-.sidebar a { color: #356da4; }
-.sidebar a.current.enum { color: #a63283; }
-.sidebar a.current.struct { color: #a63283; }
-.sidebar a.current.type { color: #a63283; }
-.sidebar a.current.foreigntype { color: #356da4; }
-.sidebar a.current.attr,
-.sidebar a.current.derive,
-.sidebar a.current.macro { color: #067901; }
-.sidebar a.current.union { color: #a63283; }
-.sidebar a.current.constant
-.sidebar a.current.static { color: #356da4; }
-.sidebar a.current.primitive { color: #a63283; }
-.sidebar a.current.trait { color: #6849c3; }
-.sidebar a.current.traitalias { color: #4b349e; }
-.sidebar a.current.fn { color: #a67736; }
-.sidebar a.current.keyword { color: #356da4; }
-
 body.source .example-wrap pre.rust a {
 	background: #eee;
 }
@@ -122,9 +75,6 @@ body.source .example-wrap pre.rust a {
 	filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);
 }
 
-.stab { background: #FFF5D6; border-color: #FFC600; }
-.stab.portability > code { background: none; }
-
 .src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 8d6450838c1..d13efe6c113 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -108,7 +108,6 @@ impl<'tcx> JsonRenderer<'tcx> {
             .filter_map(|(&id, trait_item)| {
                 // only need to synthesize items for external traits
                 if !id.is_local() {
-                    let trait_item = &trait_item.trait_;
                     for item in &trait_item.items {
                         trace!("Adding subitem to {id:?}: {:?}", item.item_id);
                         self.item(item.clone()).unwrap();
diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs
index 392e26ea6ac..7ff3ccef945 100644
--- a/src/librustdoc/passes/bare_urls.rs
+++ b/src/librustdoc/passes/bare_urls.rs
@@ -71,16 +71,14 @@ impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> {
             let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
                 let sp = super::source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
                     .unwrap_or_else(|| item.attr_span(cx.tcx));
-                cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, |lint| {
-                    lint.build(msg)
-                        .note("bare URLs are not automatically turned into clickable links")
+                cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
+                    lint.note("bare URLs are not automatically turned into clickable links")
                         .span_suggestion(
                             sp,
                             "use an automatic link instead",
                             format!("<{}>", url),
                             Applicability::MachineApplicable,
                         )
-                        .emit();
                 });
             };
 
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 381ac7a5dee..14a38a760d2 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -2,7 +2,7 @@
 use rustc_data_structures::sync::{Lock, Lrc};
 use rustc_errors::{
     emitter::Emitter, translation::Translate, Applicability, Diagnostic, Handler,
-    LazyFallbackBundle, LintDiagnosticBuilder,
+    LazyFallbackBundle,
 };
 use rustc_parse::parse_stream_from_source_str;
 use rustc_session::parse::ParseSess;
@@ -97,48 +97,10 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
             None => (item.attr_span(self.cx.tcx), false),
         };
 
-        // lambda that will use the lint to start a new diagnostic and add
-        // a suggestion to it when needed.
-        let diag_builder = |lint: LintDiagnosticBuilder<'_, ()>| {
-            let explanation = if is_ignore {
-                "`ignore` code blocks require valid Rust code for syntax highlighting; \
-                    mark blocks that do not contain Rust code as text"
-            } else {
-                "mark blocks that do not contain Rust code as text"
-            };
-            let msg = if buffer.has_errors {
-                "could not parse code block as Rust code"
-            } else {
-                "Rust code block is empty"
-            };
-            let mut diag = lint.build(msg);
-
-            if precise_span {
-                if is_ignore {
-                    // giving an accurate suggestion is hard because `ignore` might not have come first in the list.
-                    // just give a `help` instead.
-                    diag.span_help(
-                        sp.from_inner(InnerSpan::new(0, 3)),
-                        &format!("{}: ```text", explanation),
-                    );
-                } else if empty_block {
-                    diag.span_suggestion(
-                        sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
-                        explanation,
-                        "text",
-                        Applicability::MachineApplicable,
-                    );
-                }
-            } else if empty_block || is_ignore {
-                diag.help(&format!("{}: ```text", explanation));
-            }
-
-            // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
-            for message in buffer.messages.iter() {
-                diag.note(message);
-            }
-
-            diag.emit();
+        let msg = if buffer.has_errors {
+            "could not parse code block as Rust code"
+        } else {
+            "Rust code block is empty"
         };
 
         // Finally build and emit the completed diagnostic.
@@ -148,7 +110,42 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
             crate::lint::INVALID_RUST_CODEBLOCKS,
             hir_id,
             sp,
-            diag_builder,
+            msg,
+            |lint| {
+                let explanation = if is_ignore {
+                    "`ignore` code blocks require valid Rust code for syntax highlighting; \
+                    mark blocks that do not contain Rust code as text"
+                } else {
+                    "mark blocks that do not contain Rust code as text"
+                };
+
+                if precise_span {
+                    if is_ignore {
+                        // giving an accurate suggestion is hard because `ignore` might not have come first in the list.
+                        // just give a `help` instead.
+                        lint.span_help(
+                            sp.from_inner(InnerSpan::new(0, 3)),
+                            &format!("{}: ```text", explanation),
+                        );
+                    } else if empty_block {
+                        lint.span_suggestion(
+                            sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
+                            explanation,
+                            "text",
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                } else if empty_block || is_ignore {
+                    lint.help(&format!("{}: ```text", explanation));
+                }
+
+                // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
+                for message in buffer.messages.iter() {
+                    lint.note(message);
+                }
+
+                lint
+            },
         );
     }
 }
@@ -195,8 +192,11 @@ impl Translate for BufferEmitter {
 impl Emitter for BufferEmitter {
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
         let mut buffer = self.buffer.borrow_mut();
-        // FIXME(davidtwco): need to support translation here eventually
-        buffer.messages.push(format!("error from rustc: {}", diag.message[0].0.expect_str()));
+
+        let fluent_args = self.to_fluent_args(diag.args());
+        let translated_main_message = self.translate_message(&diag.message[0].0, &fluent_args);
+
+        buffer.messages.push(format!("error from rustc: {}", translated_main_message));
         if diag.is_error() {
             buffer.has_errors = true;
         }
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 55d5f303d34..15982b40944 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -125,9 +125,8 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
                 crate::lint::MISSING_DOC_CODE_EXAMPLES,
                 hir_id,
                 sp,
-                |lint| {
-                    lint.build("missing code example in this documentation").emit();
-                },
+                "missing code example in this documentation",
+                |lint| lint,
             );
         }
     } else if tests.found_tests > 0
@@ -137,9 +136,8 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
             crate::lint::PRIVATE_DOC_TESTS,
             hir_id,
             item.attr_span(cx.tcx),
-            |lint| {
-                lint.build("documentation test in private item").emit();
-            },
+            "documentation test in private item",
+            |lint| lint,
         );
     }
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 677c980f63c..3beda708bf2 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1609,9 +1609,7 @@ fn report_diagnostic(
 
     let sp = item.attr_span(tcx);
 
-    tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
-        let mut diag = lint.build(msg);
-
+    tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |lint| {
         let span =
             super::source_span_for_markdown_range(tcx, dox, link_range, &item.attrs).map(|sp| {
                 if dox.as_bytes().get(link_range.start) == Some(&b'`')
@@ -1624,7 +1622,7 @@ fn report_diagnostic(
             });
 
         if let Some(sp) = span {
-            diag.set_span(sp);
+            lint.set_span(sp);
         } else {
             // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
             //                       ^     ~~~~
@@ -1634,7 +1632,7 @@ fn report_diagnostic(
             let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
 
             // Print the line containing the `link_range` and manually mark it with '^'s.
-            diag.note(&format!(
+            lint.note(&format!(
                 "the link appears in this line:\n\n{line}\n\
                      {indicator: <before$}{indicator:^<found$}",
                 line = line,
@@ -1644,9 +1642,9 @@ fn report_diagnostic(
             ));
         }
 
-        decorate(&mut diag, span);
+        decorate(lint, span);
 
-        diag.emit();
+        lint
     });
 }
 
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 885dadb32a8..694b03161d9 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -240,9 +240,8 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
                     Some(sp) => sp,
                     None => item.attr_span(tcx),
                 };
-                tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
+                tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| {
                     use rustc_lint_defs::Applicability;
-                    let mut diag = lint.build(msg);
                     // If a tag looks like `<this>`, it might actually be a generic.
                     // We don't try to detect stuff `<like, this>` because that's not valid HTML,
                     // and we don't try to detect stuff `<like this>` because that's not valid Rust.
@@ -305,11 +304,10 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
                         if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
                             || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
                         {
-                            diag.emit();
-                            return;
+                            return lint;
                         }
                         // multipart form is chosen here because ``Vec<i32>`` would be confusing.
-                        diag.multipart_suggestion(
+                        lint.multipart_suggestion(
                             "try marking as source code",
                             vec![
                                 (generics_sp.shrink_to_lo(), String::from("`")),
@@ -318,7 +316,8 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
                             Applicability::MaybeIncorrect,
                         );
                     }
-                    diag.emit()
+
+                    lint
                 });
             };
 
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
index c40274394f3..d29ceead4f3 100644
--- a/src/librustdoc/visit.rs
+++ b/src/librustdoc/visit.rs
@@ -65,7 +65,7 @@ pub(crate) trait DocVisitor: Sized {
         // FIXME: make this a simple by-ref for loop once external_traits is cleaned up
         let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) };
         for (k, v) in external_traits {
-            v.trait_.items.iter().for_each(|i| self.visit_item(i));
+            v.items.iter().for_each(|i| self.visit_item(i));
             c.external_traits.borrow_mut().insert(k, v);
         }
     }
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 670e5f673acb736acbfce65e0ffe2c8cd115b93
+Subproject 9567f08afc94332d59025744f3a8198104949d3
diff --git a/src/test/assembly/x86-stack-probes.rs b/src/test/assembly/x86-stack-probes.rs
new file mode 100644
index 00000000000..c7141fb208a
--- /dev/null
+++ b/src/test/assembly/x86-stack-probes.rs
@@ -0,0 +1,42 @@
+// min-llvm-version: 16
+// revisions: x86_64 i686
+// assembly-output: emit-asm
+//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//[x86_64] needs-llvm-components: x86
+//[i686] compile-flags: --target i686-unknown-linux-gnu
+//[i686] needs-llvm-components: x86
+// compile-flags: -C llvm-args=-x86-asm-syntax=intel
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for u8 {}
+
+// Check that inline-asm stack probes are generated correctly.
+// To avoid making this test fragile to slight asm changes,
+// we only check that the stack pointer is decremented by a page at a time,
+// instead of matching the whole probe sequence.
+
+// CHECK-LABEL: small_stack_probe:
+#[no_mangle]
+pub fn small_stack_probe(x: u8, f: fn(&mut [u8; 8192])) {
+    // CHECK-NOT: __rust_probestack
+    // x86_64: sub rsp, 4096
+    // i686: sub esp, 4096
+    f(&mut [x; 8192]);
+}
+
+// CHECK-LABEL: big_stack_probe:
+#[no_mangle]
+pub fn big_stack_probe(x: u8, f: fn(&[u8; 65536])) {
+    // CHECK-NOT: __rust_probestack
+    // x86_64: sub rsp, 4096
+    // i686: sub esp, 4096
+    f(&mut [x; 65536]);
+}
diff --git a/src/test/codegen/abi-main-signature-32bit-c-int.rs b/src/test/codegen/abi-main-signature-32bit-c-int.rs
index 31b19a54276..7f22ddcfc12 100644
--- a/src/test/codegen/abi-main-signature-32bit-c-int.rs
+++ b/src/test/codegen/abi-main-signature-32bit-c-int.rs
@@ -7,4 +7,4 @@
 fn main() {
 }
 
-// CHECK: define i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}})
+// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}})
diff --git a/src/test/codegen/binary-search-index-no-bound-check.rs b/src/test/codegen/binary-search-index-no-bound-check.rs
index 2deabcaa6c2..c1766a4a44a 100644
--- a/src/test/codegen/binary-search-index-no-bound-check.rs
+++ b/src/test/codegen/binary-search-index-no-bound-check.rs
@@ -16,3 +16,23 @@ pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 {
         42
     }
 }
+
+// Similarly, check that `partition_point` is known to return a valid fencepost.
+
+// CHECK-LABEL: @unknown_split
+#[no_mangle]
+pub fn unknown_split(x: &[i32], i: usize) -> (&[i32], &[i32]) {
+    // This just makes sure that the subsequent function is looking for the
+    // absence of something that might actually be there.
+
+    // CHECK: call core::panicking::panic
+    x.split_at(i)
+}
+
+// CHECK-LABEL: @partition_point_split_no_bounds_check
+#[no_mangle]
+pub fn partition_point_split_no_bounds_check(x: &[i32], needle: i32) -> (&[i32], &[i32]) {
+    // CHECK-NOT: call core::panicking::panic
+    let i = x.partition_point(|p| p < &needle);
+    x.split_at(i)
+}
diff --git a/src/test/codegen/stack-probes-call.rs b/src/test/codegen/stack-probes-call.rs
new file mode 100644
index 00000000000..a18fd41c28c
--- /dev/null
+++ b/src/test/codegen/stack-probes-call.rs
@@ -0,0 +1,24 @@
+// Check the "probe-stack" attribute for targets with `StackProbeType::Call`,
+// or `StackProbeType::InlineOrCall` when running on older LLVM.
+
+// compile-flags: -C no-prepopulate-passes
+// revisions: i686 x86_64
+//[i686] compile-flags: --target i686-unknown-linux-gnu
+//[i686] needs-llvm-components: x86
+//[i686] ignore-llvm-version: 16 - 99
+//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//[x86_64] needs-llvm-components: x86
+//[x86_64] ignore-llvm-version: 16 - 99
+
+#![crate_type = "rlib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[no_mangle]
+pub fn foo() {
+// CHECK: @foo() unnamed_addr #0
+// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} }
+}
diff --git a/src/test/codegen/stack-probes-inline.rs b/src/test/codegen/stack-probes-inline.rs
new file mode 100644
index 00000000000..a6b781de531
--- /dev/null
+++ b/src/test/codegen/stack-probes-inline.rs
@@ -0,0 +1,32 @@
+// Check the "probe-stack" attribute for targets with `StackProbeType::Inline`,
+// or `StackProbeType::InlineOrCall` when running on newer LLVM.
+
+// compile-flags: -C no-prepopulate-passes
+// revisions: powerpc powerpc64 powerpc64le s390x i686 x86_64
+//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
+//[powerpc] needs-llvm-components: powerpc
+//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
+//[powerpc64] needs-llvm-components: powerpc
+//[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu
+//[powerpc64le] needs-llvm-components: powerpc
+//[s390x] compile-flags: --target s390x-unknown-linux-gnu
+//[s390x] needs-llvm-components: systemz
+//[i686] compile-flags: --target i686-unknown-linux-gnu
+//[i686] needs-llvm-components: x86
+//[i686] min-llvm-version: 16
+//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//[x86_64] needs-llvm-components: x86
+//[x86_64] min-llvm-version: 16
+
+#![crate_type = "rlib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[no_mangle]
+pub fn foo() {
+// CHECK: @foo() unnamed_addr #0
+// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} }
+}
diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs
deleted file mode 100644
index 9bd351df3ea..00000000000
--- a/src/test/codegen/stack-probes.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// ignore-arm
-// ignore-aarch64
-// ignore-mips
-// ignore-mips64
-// ignore-powerpc
-// ignore-powerpc64
-// ignore-powerpc64le
-// ignore-riscv64
-// ignore-s390x
-// ignore-sparc
-// ignore-sparc64
-// ignore-wasm
-// ignore-emscripten
-// ignore-windows
-// compile-flags: -C no-prepopulate-passes
-
-#![crate_type = "lib"]
-
-#[no_mangle]
-pub fn foo() {
-// CHECK: @foo() unnamed_addr #0
-}
diff --git a/src/test/run-make/macos-fat-archive/Makefile b/src/test/run-make/macos-fat-archive/Makefile
new file mode 100644
index 00000000000..cc99375db69
--- /dev/null
+++ b/src/test/run-make/macos-fat-archive/Makefile
@@ -0,0 +1,10 @@
+# only-macos
+
+-include ../../run-make-fulldeps/tools.mk
+
+"$(TMPDIR)"/libnative-library.a: native-library.c
+	$(CC) -arch arm64 -arch x86_64 native-library.c -c -o "$(TMPDIR)"/native-library.o
+	$(AR) crs "$(TMPDIR)"/libnative-library.a "$(TMPDIR)"/native-library.o
+
+all: "$(TMPDIR)"/libnative-library.a
+	$(RUSTC) lib.rs --crate-type=lib -L "native=$(TMPDIR)" -l static=native-library
diff --git a/src/test/run-make/macos-fat-archive/lib.rs b/src/test/run-make/macos-fat-archive/lib.rs
new file mode 100644
index 00000000000..9943a266c3e
--- /dev/null
+++ b/src/test/run-make/macos-fat-archive/lib.rs
@@ -0,0 +1,3 @@
+extern "C" {
+    pub fn native_func();
+}
diff --git a/src/test/run-make/macos-fat-archive/native-library.c b/src/test/run-make/macos-fat-archive/native-library.c
new file mode 100644
index 00000000000..d300fdf1c17
--- /dev/null
+++ b/src/test/run-make/macos-fat-archive/native-library.c
@@ -0,0 +1 @@
+void native_func() {}
diff --git a/src/test/rustdoc-gui/anchor-navigable.goml b/src/test/rustdoc-gui/anchor-navigable.goml
index 424c312233b..14653f0bfc7 100644
--- a/src/test/rustdoc-gui/anchor-navigable.goml
+++ b/src/test/rustdoc-gui/anchor-navigable.goml
@@ -7,5 +7,5 @@
 goto: file://|DOC_PATH|/test_docs/struct.Foo.html
 // We check that ".item-info" is bigger than its content.
 move-cursor-to: ".impl"
-assert-property: (".impl > a.anchor", {"offsetWidth": "9"})
+assert-property: (".impl > a.anchor", {"offsetWidth": "8"})
 assert-css: (".impl > a.anchor", {"left": "-8px"})
diff --git a/src/test/rustdoc-gui/font-weight.goml b/src/test/rustdoc-gui/font-weight.goml
index 13e8ec9fb16..d5c934551a5 100644
--- a/src/test/rustdoc-gui/font-weight.goml
+++ b/src/test/rustdoc-gui/font-weight.goml
@@ -13,7 +13,7 @@ goto: file://|DOC_PATH|/test_docs/type.SomeType.html
 assert-css: (".top-doc .docblock p", {"font-weight": "400"}, ALL)
 
 goto: file://|DOC_PATH|/test_docs/struct.Foo.html
-assert-css: (".impl-items .method", {"font-weight": "600"}, ALL)
+assert-css: (".impl-items .method > .code-header", {"font-weight": "600"}, ALL)
 
 goto: file://|DOC_PATH|/lib2/trait.Trait.html
 
@@ -41,4 +41,4 @@ assert-count: (".methods .associatedtype", 1)
 assert-css: (".methods .associatedtype", {"font-weight": "600"})
 assert-count: (".methods .constant", 1)
 assert-css: (".methods .constant", {"font-weight": "600"})
-assert-css: (".methods .method", {"font-weight": "600"})
+assert-css: (".methods .method > .code-header", {"font-weight": "600"})
diff --git a/src/test/rustdoc-gui/no-docblock.goml b/src/test/rustdoc-gui/no-docblock.goml
new file mode 100644
index 00000000000..2408be4534b
--- /dev/null
+++ b/src/test/rustdoc-gui/no-docblock.goml
@@ -0,0 +1,8 @@
+// This test checks that there are margins applied to methods with no docblocks.
+goto: file://|DOC_PATH|/test_docs/trait.TraitWithNoDocblocks.html
+// Check that the two methods are more than 24px apart.
+compare-elements-position-near-false: ("//*[@id='tymethod.first_fn']", "//*[@id='tymethod.second_fn']", {"y": 24})
+
+goto: file://|DOC_PATH|/test_docs/struct.TypeWithNoDocblocks.html
+// Check that the two methods are more than 24px apart.
+compare-elements-position-near-false: ("//*[@id='method.first_fn']", "//*[@id='method.second_fn']", {"y": 24})
diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml
index c4b5fdf53dd..807646cce37 100644
--- a/src/test/rustdoc-gui/search-result-color.goml
+++ b/src/test/rustdoc-gui/search-result-color.goml
@@ -30,54 +30,243 @@ assert-css: (
 
 // Checking the color of "keyword".
 assert-css: (
-    ".result-name .keyword",
+    ".result-keyword .keyword",
     {"color": "rgb(57, 175, 215)"},
     ALL,
 )
+assert-css: (
+    ".result-keyword",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-keyword"
+assert-css: (
+    ".result-keyword:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-keyword:hover .keyword",
+    {"color": "rgb(57, 175, 215)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-keyword"
+assert-css: (
+    ".result-keyword:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-keyword:focus .keyword",
+    {"color": "rgb(57, 175, 215)"},
+)
+
 // Check the color of "struct".
 assert-css: (
-    ".result-name .struct",
+    ".result-struct .struct",
     {"color": "rgb(255, 160, 165)"},
     ALL,
 )
+assert-css: (
+    ".result-struct",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-struct"
+assert-css: (
+    ".result-struct:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-struct:hover .struct",
+    {"color": "rgb(255, 160, 165)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-struct"
+assert-css: (
+    ".result-struct:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-struct:focus .struct",
+    {"color": "rgb(255, 160, 165)"},
+)
+
 // Check the color of "associated type".
 assert-css: (
-    ".result-name .associatedtype",
+    ".result-associatedtype .associatedtype",
     {"color": "rgb(57, 175, 215)"},
     ALL,
 )
+assert-css: (
+    ".result-associatedtype",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-associatedtype"
+assert-css: (
+    ".result-associatedtype:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-associatedtype:hover .associatedtype",
+    {"color": "rgb(57, 175, 215)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-associatedtype"
+assert-css: (
+    ".result-associatedtype:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-associatedtype:focus .associatedtype",
+    {"color": "rgb(57, 175, 215)"},
+)
+
 // Check the color of "type method".
 assert-css: (
-    ".result-name .tymethod",
+    ".result-tymethod .tymethod",
     {"color": "rgb(253, 214, 135)"},
     ALL,
 )
+assert-css: (
+    ".result-tymethod",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+assert-css: (
+    ".result-tymethod .tymethod",
+    {"color": "rgb(253, 214, 135)"},
+)
+move-cursor-to: ".result-tymethod"
+assert-css: (
+    ".result-tymethod:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-tymethod"
+assert-css: (
+    ".result-tymethod:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+
 // Check the color of "method".
 assert-css: (
-    ".result-name .method",
+    ".result-method .method",
     {"color": "rgb(253, 214, 135)"},
     ALL,
 )
+assert-css: (
+    ".result-method",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-method"
+assert-css: (
+    ".result-method:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-method:hover .method",
+    {"color": "rgb(253, 214, 135)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-method"
+assert-css: (
+    ".result-method:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-method:focus .method",
+    {"color": "rgb(253, 214, 135)"},
+)
+
 // Check the color of "struct field".
 assert-css: (
-    ".result-name .structfield",
+    ".result-structfield .structfield",
     {"color": "rgb(0, 150, 207)"},
     ALL,
 )
+assert-css: (
+    ".result-structfield",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-structfield"
+assert-css: (
+    ".result-structfield:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-structfield:hover .structfield",
+    {"color": "rgb(255, 255, 255)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-structfield"
+assert-css: (
+    ".result-structfield:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-structfield:focus .structfield",
+    {"color": "rgb(255, 255, 255)"},
+)
+
 // Check the color of "macro".
 assert-css: (
-    ".result-name .macro",
+    ".result-macro .macro",
     {"color": "rgb(163, 122, 204)"},
     ALL,
 )
+assert-css: (
+    ".result-macro",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-macro"
+assert-css: (
+    ".result-macro:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-macro:hover .macro",
+    {"color": "rgb(163, 122, 204)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-macro"
+assert-css: (
+    ".result-macro:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-macro:focus .macro",
+    {"color": "rgb(163, 122, 204)"},
+)
+
 // Check the color of "fn".
 assert-css: (
-    ".result-name .fn",
+    ".result-fn .fn",
     {"color": "rgb(253, 214, 135)"},
     ALL,
 )
+assert-css: (
+    ".result-fn",
+    {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-fn"
+assert-css: (
+    ".result-fn:hover",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-fn:hover .fn",
+    {"color": "rgb(253, 214, 135)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-fn"
+assert-css: (
+    ".result-fn:focus",
+    {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"},
+)
+assert-css: (
+    ".result-fn:focus .fn",
+    {"color": "rgb(253, 214, 135)"},
+)
 
 // Checking the `<a>` container.
+move-cursor-to: ".search-input"
+focus: ".search-input" // To ensure the `<a>` container isnt focus or hover.
 assert-css: (
     "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
     {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"},
@@ -113,7 +302,7 @@ assert-css: (
     {"color": "rgb(221, 221, 221)"},
 )
 
-// Checking the color for "keyword".
+// Checking the color for "keyword" text.
 assert-css: (
     "//*[@class='result-name']//*[text()='(keyword)']",
     {"color": "rgb(221, 221, 221)"},
@@ -121,68 +310,250 @@ assert-css: (
 
 // Checking the color of "keyword".
 assert-css: (
-    ".result-name .keyword",
+    ".result-keyword .keyword",
     {"color": "rgb(210, 153, 29)"},
     ALL,
 )
+assert-css: (
+    ".result-keyword",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-keyword"
+assert-css: (
+    ".result-keyword:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-keyword:hover .keyword",
+    {"color": "rgb(210, 153, 29)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-keyword"
+assert-css: (
+    ".result-keyword:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-keyword:focus .keyword",
+    {"color": "rgb(210, 153, 29)"},
+)
+
 // Check the color of "struct".
 assert-css: (
-    ".result-name .struct",
+    ".result-struct .struct",
     {"color": "rgb(45, 191, 184)"},
     ALL,
 )
+assert-css: (
+    ".result-struct",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-struct"
+assert-css: (
+    ".result-struct:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-struct:hover .struct",
+    {"color": "rgb(45, 191, 184)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-struct"
+assert-css: (
+    ".result-struct:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-struct:focus .struct",
+    {"color": "rgb(45, 191, 184)"},
+)
+
 // Check the color of "associated type".
 assert-css: (
-    ".result-name .associatedtype",
+    ".result-associatedtype .associatedtype",
     {"color": "rgb(210, 153, 29)"},
     ALL,
 )
+assert-css: (
+    ".result-associatedtype",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-associatedtype"
+assert-css: (
+    ".result-associatedtype:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-associatedtype:hover .associatedtype",
+    {"color": "rgb(210, 153, 29)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-associatedtype"
+assert-css: (
+    ".result-associatedtype:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-associatedtype:focus .associatedtype",
+    {"color": "rgb(210, 153, 29)"},
+)
+
 // Check the color of "type method".
 assert-css: (
-    ".result-name .tymethod",
+    ".result-tymethod .tymethod",
     {"color": "rgb(43, 171, 99)"},
     ALL,
 )
+assert-css: (
+    ".result-tymethod",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-tymethod"
+assert-css: (
+    ".result-tymethod:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-tymethod:hover .tymethod",
+    {"color": "rgb(43, 171, 99)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-tymethod"
+assert-css: (
+    ".result-tymethod:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-tymethod:focus .tymethod",
+    {"color": "rgb(43, 171, 99)"},
+)
+
 // Check the color of "method".
 assert-css: (
-    ".result-name .method",
+    ".result-method .method",
     {"color": "rgb(43, 171, 99)"},
     ALL,
 )
+assert-css: (
+    ".result-method",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-method"
+assert-css: (
+    ".result-method:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-method:hover .method",
+    {"color": "rgb(43, 171, 99)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-method"
+assert-css: (
+    ".result-method:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-method:focus .method",
+    {"color": "rgb(43, 171, 99)"},
+)
+
 // Check the color of "struct field".
 assert-css: (
-    ".result-name .structfield",
+    ".result-structfield .structfield",
     {"color": "rgb(221, 221, 221)"},
     ALL,
 )
+assert-css: (
+    ".result-structfield",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-structfield"
+assert-css: (
+    ".result-structfield:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-structfield:hover .structfield",
+    {"color": "rgb(221, 221, 221)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-structfield"
+assert-css: (
+    ".result-structfield:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-structfield:focus .structfield",
+    {"color": "rgb(221, 221, 221)"},
+)
+
 // Check the color of "macro".
 assert-css: (
-    ".result-name .macro",
+    ".result-macro .macro",
     {"color": "rgb(9, 189, 0)"},
     ALL,
 )
+assert-css: (
+    ".result-macro",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-macro"
+assert-css: (
+    ".result-macro:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-macro:hover .macro",
+    {"color": "rgb(9, 189, 0)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-macro"
+assert-css: (
+    ".result-macro:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-macro:focus .macro",
+    {"color": "rgb(9, 189, 0)"},
+)
+
 // Check the color of "fn".
 assert-css: (
-    ".result-name .fn",
+    ".result-fn .fn",
     {"color": "rgb(43, 171, 99)"},
     ALL,
 )
-
-// Checking the `<a>` container.
 assert-css: (
-    "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+    ".result-fn",
     {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
 )
-
-// Checking color and background on hover.
-move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
+move-cursor-to: ".result-fn"
 assert-css: (
-    "//*[@class='result-name']/*[text()='test_docs::']",
-    {"color": "rgb(221, 221, 221)"},
+    ".result-fn:hover",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
 )
 assert-css: (
+    ".result-fn:hover .fn",
+    {"color": "rgb(43, 171, 99)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-fn"
+assert-css: (
+    ".result-fn:focus",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"},
+)
+assert-css: (
+    ".result-fn:focus .fn",
+    {"color": "rgb(43, 171, 99)"},
+)
+
+// Checking the `<a>` container.
+move-cursor-to: ".search-input"
+focus: ".search-input" // To ensure the `<a>` container isnt focus or hover.
+assert-css: (
     "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
-    {"color": "rgb(221, 221, 221)", "background-color": "rgb(119, 119, 119)"},
+    {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
 )
 
 // Light theme
@@ -200,7 +571,7 @@ assert-css: (
     {"color": "rgb(0, 0, 0)"},
 )
 
-// Checking the color for "keyword".
+// Checking the color for "keyword" text.
 assert-css: (
     "//*[@class='result-name']//*[text()='(keyword)']",
     {"color": "rgb(0, 0, 0)"},
@@ -208,68 +579,250 @@ assert-css: (
 
 // Checking the color of "keyword".
 assert-css: (
-    ".result-name .keyword",
+    ".result-keyword .keyword",
     {"color": "rgb(56, 115, 173)"},
     ALL,
 )
+assert-css: (
+    ".result-keyword",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-keyword"
+assert-css: (
+    ".result-keyword:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-keyword:hover .keyword",
+    {"color": "rgb(56, 115, 173)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-keyword"
+assert-css: (
+    ".result-keyword:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-keyword:focus .keyword",
+    {"color": "rgb(56, 115, 173)"},
+)
+
 // Check the color of "struct".
 assert-css: (
-    ".result-name .struct",
+    ".result-struct .struct",
     {"color": "rgb(173, 55, 138)"},
     ALL,
 )
+assert-css: (
+    ".result-struct",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-struct"
+assert-css: (
+    ".result-struct:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-struct:hover .struct",
+    {"color": "rgb(173, 55, 138)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-struct"
+assert-css: (
+    ".result-struct:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-struct:focus .struct",
+    {"color": "rgb(173, 55, 138)"},
+)
+
 // Check the color of "associated type".
 assert-css: (
-    ".result-name .associatedtype",
+    ".result-associatedtype .associatedtype",
     {"color": "rgb(56, 115, 173)"},
     ALL,
 )
+assert-css: (
+    ".result-associatedtype",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-associatedtype"
+assert-css: (
+    ".result-associatedtype:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-associatedtype:hover .associatedtype",
+    {"color": "rgb(56, 115, 173)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-associatedtype"
+assert-css: (
+    ".result-associatedtype:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-associatedtype:focus .associatedtype",
+    {"color": "rgb(56, 115, 173)"},
+)
+
 // Check the color of "type method".
 assert-css: (
-    ".result-name .tymethod",
+    ".result-tymethod .tymethod",
     {"color": "rgb(173, 124, 55)"},
     ALL,
 )
+assert-css: (
+    ".result-tymethod",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-tymethod"
+assert-css: (
+    ".result-tymethod:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-tymethod:hover .tymethod",
+    {"color": "rgb(173, 124, 55)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-tymethod"
+assert-css: (
+    ".result-tymethod:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-tymethod:focus .tymethod",
+    {"color": "rgb(173, 124, 55)"},
+)
+
 // Check the color of "method".
 assert-css: (
-    ".result-name .method",
+    ".result-method .method",
     {"color": "rgb(173, 124, 55)"},
     ALL,
 )
+assert-css: (
+    ".result-method",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-method"
+assert-css: (
+    ".result-method:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-method:hover .method",
+    {"color": "rgb(173, 124, 55)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-method"
+assert-css: (
+    ".result-method:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-method:focus .method",
+    {"color": "rgb(173, 124, 55)"},
+)
+
 // Check the color of "struct field".
 assert-css: (
-    ".result-name .structfield",
+    ".result-structfield .structfield",
     {"color": "rgb(0, 0, 0)"},
     ALL,
 )
+assert-css: (
+    ".result-structfield",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-structfield"
+assert-css: (
+    ".result-structfield:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-structfield:hover .structfield",
+    {"color": "rgb(0, 0, 0)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-structfield"
+assert-css: (
+    ".result-structfield:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-structfield:focus .structfield",
+    {"color": "rgb(0, 0, 0)"},
+)
+
 // Check the color of "macro".
 assert-css: (
-    ".result-name .macro",
+    ".result-macro .macro",
     {"color": "rgb(6, 128, 0)"},
     ALL,
 )
+assert-css: (
+    ".result-macro",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".result-macro"
+assert-css: (
+    ".result-macro:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-macro:hover .macro",
+    {"color": "rgb(6, 128, 0)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-macro"
+assert-css: (
+    ".result-macro:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-macro:focus .macro",
+    {"color": "rgb(6, 128, 0)"},
+)
+
 // Check the color of "fn".
 assert-css: (
-    ".result-name .fn",
+    ".result-fn .fn",
     {"color": "rgb(173, 124, 55)"},
     ALL,
 )
-
-// Checking the `<a>` container.
 assert-css: (
-    "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
+    ".result-fn",
     {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
 )
-
-// Checking color and background on hover.
-move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
+move-cursor-to: ".result-fn"
 assert-css: (
-    "//*[@class='result-name']/*[text()='test_docs::']",
-    {"color": "rgb(0, 0, 0)"},
+    ".result-fn:hover",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
 )
 assert-css: (
+    ".result-fn:hover .fn",
+    {"color": "rgb(173, 124, 55)"},
+)
+move-cursor-to: ".search-input"
+focus: ".result-fn"
+assert-css: (
+    ".result-fn:focus",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"},
+)
+assert-css: (
+    ".result-fn:focus .fn",
+    {"color": "rgb(173, 124, 55)"},
+)
+
+// Checking the `<a>` container.
+move-cursor-to: ".search-input"
+focus: ".search-input" // To ensure the `<a>` container isnt focus or hover.
+assert-css: (
     "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a",
-    {"color": "rgb(0, 0, 0)", "background-color": "rgb(221, 221, 221)"},
+    {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
 )
 
 // Check the alias more specifically in the dark theme.
diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml
new file mode 100644
index 00000000000..d2a1688080c
--- /dev/null
+++ b/src/test/rustdoc-gui/sidebar-links-color.goml
@@ -0,0 +1,233 @@
+// This test checks links colors in sidebar before and after hover.
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+
+// This is needed so that the text color is computed.
+show-text: true
+
+// Ayu theme
+local-storage: {
+    "rustdoc-theme": "ayu",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+// Struct
+assert-css: (
+    ".sidebar a.struct:not(.current)",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.struct:not(.current)"
+assert-css: (
+    ".sidebar a.struct:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// Enum
+assert-css: (
+    ".sidebar a.enum",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.enum"
+assert-css: (
+    ".sidebar a.enum:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// Union
+assert-css: (
+    ".sidebar a.union",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.union"
+assert-css: (
+    ".sidebar a.union:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// Trait
+assert-css: (
+    ".sidebar a.trait",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.trait"
+assert-css: (
+    ".sidebar a.trait:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// Function
+assert-css: (
+    ".sidebar a.fn",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.fn"
+assert-css: (
+    ".sidebar a.fn:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// Type definition
+assert-css: (
+    ".sidebar a.type",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.type"
+assert-css: (
+    ".sidebar a.type:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+// Keyword
+assert-css: (
+    ".sidebar a.keyword",
+    {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.keyword"
+assert-css: (
+    ".sidebar a.keyword:hover",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+
+// Dark theme
+local-storage: {"rustdoc-theme": "dark"}
+reload:
+
+// Struct
+assert-css: (
+    ".sidebar a.struct:not(.current)",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.struct:not(.current)"
+assert-css: (
+    ".sidebar a.struct:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+// Enum
+assert-css: (
+    ".sidebar a.enum",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.enum"
+assert-css: (
+    ".sidebar a.enum:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+// Union
+assert-css: (
+    ".sidebar a.union",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.union"
+assert-css: (
+    ".sidebar a.union:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+// Trait
+assert-css: (
+    ".sidebar a.trait",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.trait"
+assert-css: (
+    ".sidebar a.trait:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+// Function
+assert-css: (
+    ".sidebar a.fn",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.fn"
+assert-css: (
+    ".sidebar a.fn:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+// Type definition
+assert-css: (
+    ".sidebar a.type",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.type"
+assert-css: (
+    ".sidebar a.type:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+// Keyword
+assert-css: (
+    ".sidebar a.keyword",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.keyword"
+assert-css: (
+    ".sidebar a.keyword:hover",
+    {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+)
+
+// Light theme
+local-storage: {"rustdoc-theme": "light"}
+reload:
+
+// Struct
+assert-css: (
+    ".sidebar a.struct:not(.current)",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.struct:not(.current)"
+assert-css: (
+    ".sidebar a.struct:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
+// Enum
+assert-css: (
+    ".sidebar a.enum",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.enum"
+assert-css: (
+    ".sidebar a.enum:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
+// Union
+assert-css: (
+    ".sidebar a.union",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.union"
+assert-css: (
+    ".sidebar a.union:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
+// Trait
+assert-css: (
+    ".sidebar a.trait",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.trait"
+assert-css: (
+    ".sidebar a.trait:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
+// Function
+assert-css: (
+    ".sidebar a.fn",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.fn"
+assert-css: (
+    ".sidebar a.fn:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
+// Type definition
+assert-css: (
+    ".sidebar a.type",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.type"
+assert-css: (
+    ".sidebar a.type:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
+// Keyword
+assert-css: (
+    ".sidebar a.keyword",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
+)
+move-cursor-to: ".sidebar a.keyword"
+assert-css: (
+    ".sidebar a.keyword:hover",
+    {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+)
diff --git a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml
index 9af7c636a0c..6cb492cfc64 100644
--- a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml
+++ b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml
@@ -6,7 +6,7 @@ assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
 
 // Scroll down.
 scroll-to: "//h2[@id='blanket-implementations']"
-assert-window-property: {"pageYOffset": "639"}
+assert-window-property: {"pageYOffset": "651"}
 
 // Open the sidebar menu.
 click: ".sidebar-menu-toggle"
@@ -21,11 +21,11 @@ assert-window-property: {"pageYOffset": "0"}
 // Close the sidebar menu. Make sure the scroll position gets restored.
 click: ".sidebar-menu-toggle"
 wait-for-css: (".sidebar", {"left": "-1000px"})
-assert-window-property: {"pageYOffset": "639"}
+assert-window-property: {"pageYOffset": "651"}
 
 // Now test that scrollability returns when the browser window is just resized.
 click: ".sidebar-menu-toggle"
 wait-for-css: (".sidebar", {"left": "0px"})
 assert-window-property: {"pageYOffset": "0"}
 size: (900, 600)
-assert-window-property: {"pageYOffset": "639"}
+assert-window-property: {"pageYOffset": "651"}
diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml
index 033c6578349..04dcb532504 100644
--- a/src/test/rustdoc-gui/sidebar-mobile.goml
+++ b/src/test/rustdoc-gui/sidebar-mobile.goml
@@ -42,23 +42,24 @@ scroll-to: ".block.keyword li:nth-child(1)"
 compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topbar", {"y": 543})
 
 // Now checking the background color of the sidebar.
+show-text: true
 local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
 reload:
 
 // Open the sidebar menu.
 click: ".sidebar-menu-toggle"
-assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)"})
+assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)", "color": "rgb(221, 221, 221)"})
 
 local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "ayu"}
 reload:
 
 // Open the sidebar menu.
 click: ".sidebar-menu-toggle"
-assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)"})
+assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)", "color": "rgb(197, 197, 197)"})
 
 local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "light"}
 reload:
 
 // Open the sidebar menu.
 click: ".sidebar-menu-toggle"
-assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)"})
+assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)", "color": "rgb(0, 0, 0)"})
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
index 4321efcdb17..24d1820ff27 100644
--- a/src/test/rustdoc-gui/sidebar-source-code-display.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -3,20 +3,17 @@ javascript: false
 goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
 // Since the javascript is disabled, there shouldn't be a toggle.
 assert-false: "#sidebar-toggle"
-// For some reason, we need to wait a bit here because it seems like the transition on opacity
-// is being applied whereas it can't be reproduced in a browser...
-wait-for-css: (".sidebar > *", {"visibility": "hidden", "opacity": 0})
+wait-for-css: (".sidebar > *", {"visibility": "hidden"})
 
 // Let's retry with javascript enabled.
 javascript: true
 reload:
 wait-for: "#sidebar-toggle"
-assert-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
-assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden", "opacity": 0})
+assert-css: ("#sidebar-toggle", {"visibility": "visible"})
+assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden"})
 // Let's expand the sidebar now.
 click: "#sidebar-toggle"
-// Because of the transition CSS, we check by using `wait-for-css` instead of `assert-css`.
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
 
 // We now check that opening the sidebar and clicking a link will leave it open.
 // The behavior here on desktop is different than the behavior on mobile,
@@ -36,7 +33,7 @@ show-text: true
 local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
 reload:
 // Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
 assert-css: (
     "#source-sidebar details[open] > .files a.selected",
     {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
@@ -91,7 +88,7 @@ assert-css: (
 local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
 reload:
 // Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
 assert-css: (
     "#source-sidebar details[open] > .files > a.selected",
     {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
@@ -146,7 +143,7 @@ assert-css: (
 local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
 reload:
 // Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
 assert-css: (
     "#source-sidebar details[open] > .files a.selected",
     {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
@@ -201,7 +198,7 @@ assert-css: (
 size: (500, 700)
 reload:
 // Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
+wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
 
 // We now check it takes the full size of the display.
 assert-property: ("body", {"clientWidth": "500", "clientHeight": "700"})
diff --git a/src/test/rustdoc-gui/src-font-size.goml b/src/test/rustdoc-gui/src-font-size.goml
index 9797f196c55..ebb413b8c41 100644
--- a/src/test/rustdoc-gui/src-font-size.goml
+++ b/src/test/rustdoc-gui/src-font-size.goml
@@ -4,8 +4,8 @@
 goto: file://|DOC_PATH|/test_docs/struct.Foo.html
 show-text: true
 // Check the impl headers.
-assert-css: (".impl.has-srclink .srclink", {"font-size": "16px"}, ALL)
-assert-css: (".impl.has-srclink .code-header", {"font-size": "18px"}, ALL)
+assert-css: (".impl.has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
+assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weight": 600}, ALL)
 // Check the impl items.
-assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px"}, ALL)
-assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px"}, ALL)
+assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
+assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index 1c066206c1f..0281973c1ba 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -355,3 +355,15 @@ impl<R: std::io::Read> std::iter::Iterator for NotableStructWithLongName<R> {
 
     fn next(&mut self) -> Option<Self::Item> { () }
 }
+
+pub trait TraitWithNoDocblocks {
+    fn first_fn(&self);
+    fn second_fn(&self);
+}
+
+pub struct TypeWithNoDocblocks;
+
+impl TypeWithNoDocblocks {
+    pub fn first_fn(&self) {}
+    pub fn second_fn(&self) {}
+}
diff --git a/src/test/rustdoc-js-std/asrawfd.js b/src/test/rustdoc-js-std/asrawfd.js
index fd228a59099..369a34f9c6e 100644
--- a/src/test/rustdoc-js-std/asrawfd.js
+++ b/src/test/rustdoc-js-std/asrawfd.js
@@ -6,9 +6,9 @@ const EXPECTED = {
     'others': [
         // Reproduction test for https://github.com/rust-lang/rust/issues/78724
         // Validate that type alias methods get the correct path.
-        { 'path': 'std::os::unix::io::AsRawFd', 'name': 'as_raw_fd' },
-        { 'path': 'std::os::wasi::io::AsRawFd', 'name': 'as_raw_fd' },
+        { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' },
+        { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' },
         { 'path': 'std::os::linux::process::PidFd', 'name': 'as_raw_fd' },
-        { 'path': 'std::os::unix::io::RawFd', 'name': 'as_raw_fd' },
+        { 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' },
     ],
 };
diff --git a/src/test/rustdoc-ui/bare-urls.stderr b/src/test/rustdoc-ui/bare-urls.stderr
index 7097a8ddf3a..ccf52cd0b93 100644
--- a/src/test/rustdoc-ui/bare-urls.stderr
+++ b/src/test/rustdoc-ui/bare-urls.stderr
@@ -4,12 +4,12 @@ error: this URL is not a hyperlink
 LL | /// https://somewhere.com
    |     ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com>`
    |
+   = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
   --> $DIR/bare-urls.rs:3:9
    |
 LL | #![deny(rustdoc::bare_urls)]
    |         ^^^^^^^^^^^^^^^^^^
-   = note: bare URLs are not automatically turned into clickable links
 
 error: this URL is not a hyperlink
   --> $DIR/bare-urls.rs:7:5
diff --git a/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr
index b1fa9edf0e4..01beba1ffc4 100644
--- a/src/test/rustdoc-ui/check-attr-test.stderr
+++ b/src/test/rustdoc-ui/check-attr-test.stderr
@@ -8,12 +8,12 @@ error: unknown attribute `compile-fail`. Did you mean `compile_fail`?
 9 | | /// ```
   | |_______^
   |
+  = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 note: the lint level is defined here
  --> $DIR/check-attr-test.rs:3:9
   |
 3 | #![deny(rustdoc::invalid_codeblock_attributes)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
 error: unknown attribute `compilefail`. Did you mean `compile_fail`?
  --> $DIR/check-attr-test.rs:5:1
diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr
index 370b804c56c..f66e63ab727 100644
--- a/src/test/rustdoc-ui/check-attr.stderr
+++ b/src/test/rustdoc-ui/check-attr.stderr
@@ -10,12 +10,12 @@ LL | | /// boo
 LL | | /// ```
    | |_______^
    |
+   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 note: the lint level is defined here
   --> $DIR/check-attr.rs:1:9
    |
 LL | #![deny(rustdoc::invalid_codeblock_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
 error: unknown attribute `compilefail`. Did you mean `compile_fail`?
   --> $DIR/check-attr.rs:3:1
diff --git a/src/test/rustdoc-ui/check-cfg-test.stderr b/src/test/rustdoc-ui/check-cfg-test.stderr
index dc25205da77..9770be2f191 100644
--- a/src/test/rustdoc-ui/check-cfg-test.stderr
+++ b/src/test/rustdoc-ui/check-cfg-test.stderr
@@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value
 LL | #[cfg(feature = "invalid")]
    |       ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unexpected_cfgs)]` on by default
    = note: expected values for `feature` are: test
+   = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr
index 217b89d935b..d8aeccbfc31 100644
--- a/src/test/rustdoc-ui/check-fail.stderr
+++ b/src/test/rustdoc-ui/check-fail.stderr
@@ -32,8 +32,8 @@ LL | | //! let x = 12;
 LL | | //! ```
    | |_______^
    |
-   = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
+   = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]`
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
   --> $DIR/check-fail.rs:16:1
diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr
index 78ae65d313a..d379f33f2bd 100644
--- a/src/test/rustdoc-ui/check.stderr
+++ b/src/test/rustdoc-ui/check.stderr
@@ -24,14 +24,14 @@ LL | pub fn foo() {}
 
 warning: no documentation found for this crate's top-level module
    |
+   = help: The following guide may be of use:
+           https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 note: the lint level is defined here
   --> $DIR/check.rs:10:9
    |
 LL | #![warn(rustdoc::all)]
    |         ^^^^^^^^^^^^
    = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]`
-   = help: The following guide may be of use:
-           https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 
 warning: missing code example in this documentation
   --> $DIR/check.rs:5:1
diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
index 67d9c3989f5..3e08354a61d 100644
--- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `v2`
 LL | /// [v2]
    |      ^^ no item named `v2` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/deny-intra-link-resolution-failure.rs:1:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/diagnostic-width.stderr b/src/test/rustdoc-ui/diagnostic-width.stderr
index fed049d2b37..1a00d10d3fc 100644
--- a/src/test/rustdoc-ui/diagnostic-width.stderr
+++ b/src/test/rustdoc-ui/diagnostic-width.stderr
@@ -4,12 +4,12 @@ error: this URL is not a hyperlink
 LL | ... a http://link.com
    |       ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://link.com>`
    |
+   = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
   --> $DIR/diagnostic-width.rs:2:9
    |
 LL | ...ny(rustdoc::bare_url...
    |       ^^^^^^^^^^^^^^^^^^
-   = note: bare URLs are not automatically turned into clickable links
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr
index cc2494c92e6..68df2771fd7 100644
--- a/src/test/rustdoc-ui/doc-attr.stderr
+++ b/src/test/rustdoc-ui/doc-attr.stderr
@@ -4,14 +4,14 @@ error: unknown `doc` attribute `as_ptr`
 LL | #[doc(as_ptr)]
    |       ^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/doc-attr.rs:2:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: invalid `doc` attribute
   --> $DIR/doc-attr.rs:12:7
diff --git a/src/test/rustdoc-ui/doc-include-suggestion.stderr b/src/test/rustdoc-ui/doc-include-suggestion.stderr
index 870b7efa2ac..fcc93d0532a 100644
--- a/src/test/rustdoc-ui/doc-include-suggestion.stderr
+++ b/src/test/rustdoc-ui/doc-include-suggestion.stderr
@@ -4,9 +4,9 @@ warning: unknown `doc` attribute `include`
 LL | #[doc(include = "external-cross-doc.md")]
    | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]`
    |
-   = note: `#[warn(invalid_doc_attributes)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: `#[warn(invalid_doc_attributes)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/doc-spotlight.stderr b/src/test/rustdoc-ui/doc-spotlight.stderr
index 8e7831139a8..58612327ff9 100644
--- a/src/test/rustdoc-ui/doc-spotlight.stderr
+++ b/src/test/rustdoc-ui/doc-spotlight.stderr
@@ -4,16 +4,16 @@ error: unknown `doc` attribute `spotlight`
 LL | #[doc(spotlight)]
    |       ^^^^^^^^^ help: use `notable_trait` instead
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: `doc(spotlight)` was renamed to `doc(notable_trait)`
+   = note: `doc(spotlight)` is now a no-op
 note: the lint level is defined here
   --> $DIR/doc-spotlight.rs:2:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-   = note: `doc(spotlight)` was renamed to `doc(notable_trait)`
-   = note: `doc(spotlight)` is now a no-op
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/doc-test-attr.stderr b/src/test/rustdoc-ui/doc-test-attr.stderr
index 7f5e2d6bc70..5e6014954a4 100644
--- a/src/test/rustdoc-ui/doc-test-attr.stderr
+++ b/src/test/rustdoc-ui/doc-test-attr.stderr
@@ -4,13 +4,13 @@ error: `#[doc(test(...)]` takes a list of attributes
 LL | #![doc(test)]
    |        ^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/doc-test-attr.rs:2:9
    |
 LL | #![deny(invalid_doc_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: `#[doc(test(...)]` takes a list of attributes
   --> $DIR/doc-test-attr.rs:7:8
diff --git a/src/test/rustdoc-ui/doctest-edition.stderr b/src/test/rustdoc-ui/doctest-edition.stderr
index 1643d605375..8a3329aa3ed 100644
--- a/src/test/rustdoc-ui/doctest-edition.stderr
+++ b/src/test/rustdoc-ui/doctest-edition.stderr
@@ -7,12 +7,12 @@ LL | | //! foo'b'
 LL | | //! ```
    | |_______^
    |
+   = note: error from rustc: prefix `foo` is unknown
 note: the lint level is defined here
   --> $DIR/doctest-edition.rs:3:9
    |
 LL | #![deny(rustdoc::invalid_rust_codeblocks)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: error from rustc: prefix `foo` is unknown
 help: mark blocks that do not contain Rust code as text
    |
 LL | //! ```text
diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
index 517e08aa7c9..cbe9a3d14af 100644
--- a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
+++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
@@ -4,14 +4,14 @@ error: unknown lint: `rustdoc::missing_doc_code_examples`
 LL | #![allow(rustdoc::missing_doc_code_examples)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+   = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+   = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
 note: the lint level is defined here
   --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9
    |
 LL | #![deny(unknown_lints)]
    |         ^^^^^^^^^^^^^
-   = note: the `rustdoc::missing_doc_code_examples` lint is unstable
-   = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
-   = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
 
 error: unknown lint: `rustdoc::missing_doc_code_examples`
   --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1
diff --git a/src/test/rustdoc-ui/ignore-block-help.stderr b/src/test/rustdoc-ui/ignore-block-help.stderr
index 9c02ff11d19..a30ea51dd8a 100644
--- a/src/test/rustdoc-ui/ignore-block-help.stderr
+++ b/src/test/rustdoc-ui/ignore-block-help.stderr
@@ -7,13 +7,13 @@ LL | | /// let heart = '❤️';
 LL | | /// ```
    | |_______^
    |
-   = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default
 help: `ignore` code blocks require valid Rust code for syntax highlighting; mark blocks that do not contain Rust code as text: ```text
   --> $DIR/ignore-block-help.rs:3:5
    |
 LL | /// ```ignore (to-prevent-tidy-error)
    |     ^^^
    = note: error from rustc: character literal may only contain one codepoint
+   = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr b/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr
index 00fe229da40..7c81044dbf8 100644
--- a/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr
+++ b/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `NonExistentStruct`
 LL | /// This [test][NonExistentStruct<i32>] thing!
    |                 ^^^^^^^^^^^^^^^^^^^^^^ no item named `NonExistentStruct` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/html-as-generics-intra-doc.rs:2:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unresolved link to `NonExistentStruct2`
   --> $DIR/html-as-generics-intra-doc.rs:17:11
diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr
index 8e17323fdde..6ad8084b09c 100644
--- a/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr
+++ b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `before_but_limited_to_module`
 LL | /// [before_but_limited_to_module]
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `before_but_limited_to_module` in scope
    |
+   = note: `macro_rules` named `before_but_limited_to_module` exists in this crate, but it is not in scope at this link's location
 note: the lint level is defined here
   --> $DIR/macro-rules-error.rs:5:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: `macro_rules` named `before_but_limited_to_module` exists in this crate, but it is not in scope at this link's location
 
 error: unresolved link to `after`
   --> $DIR/macro-rules-error.rs:15:6
diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
index 4828a304463..8ec894d101b 100644
--- a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
+++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `T`
 LL | //! [[T]::rotate_left]
    |       ^ no item named `T` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/non-path-primitives.rs:1:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unresolved link to `Z`
   --> $DIR/non-path-primitives.rs:14:5
diff --git a/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr b/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr
index 6172cd2e316..4d5bd70bff6 100644
--- a/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr
+++ b/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr
@@ -4,8 +4,8 @@ warning: public documentation for `private_from_crate_level` links to private it
 LL | //! [my_module]
    |      ^^^^^^^^^ this item is private
    |
-   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link will resolve properly if you pass `--document-private-items`
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/intra-doc/private.private.stderr b/src/test/rustdoc-ui/intra-doc/private.private.stderr
index 392321f9c60..6661e9021f8 100644
--- a/src/test/rustdoc-ui/intra-doc/private.private.stderr
+++ b/src/test/rustdoc-ui/intra-doc/private.private.stderr
@@ -4,8 +4,8 @@ warning: public documentation for `DocMe` links to private item `DontDocMe`
 LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x]
    |           ^^^^^^^^^ this item is private
    |
-   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link resolves only because you passed `--document-private-items`, but will break without
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
 
 warning: public documentation for `DocMe` links to private item `DontDocMe::f`
   --> $DIR/private.rs:7:23
diff --git a/src/test/rustdoc-ui/intra-doc/private.public.stderr b/src/test/rustdoc-ui/intra-doc/private.public.stderr
index 5d1c34b9168..45b51e12edc 100644
--- a/src/test/rustdoc-ui/intra-doc/private.public.stderr
+++ b/src/test/rustdoc-ui/intra-doc/private.public.stderr
@@ -4,8 +4,8 @@ warning: public documentation for `DocMe` links to private item `DontDocMe`
 LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x]
    |           ^^^^^^^^^ this item is private
    |
-   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link will resolve properly if you pass `--document-private-items`
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
 
 warning: public documentation for `DocMe` links to private item `DontDocMe::f`
   --> $DIR/private.rs:7:23
diff --git a/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr
index bf4ab9fdd18..e8ee40ad4e8 100644
--- a/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr
+++ b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `i`
 LL | /// (arr[i])
    |           ^ no item named `i` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/span-ice-55723.rs:1:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr b/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr
index f0a7ed1785b..508d0683d5d 100644
--- a/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr
+++ b/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr
@@ -4,12 +4,12 @@ warning: unresolved link to `Oooops`
 LL |     /// [Oooops]
    |          ^^^^^^ no item named `Oooops` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/through-proc-macro.rs:7:9
    |
 LL | #![warn(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
index d280e6497e0..e7b4c43e790 100644
--- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
@@ -4,13 +4,13 @@ error: unknown disambiguator `foo`
 LL | //! Linking to [foo@banana] and [`bar@banana!()`].
    |                 ^^^
    |
+   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 note: the lint level is defined here
   --> $DIR/unknown-disambiguator.rs:2:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
-   = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
 
 error: unknown disambiguator `bar`
   --> $DIR/unknown-disambiguator.rs:4:35
diff --git a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr
index 5c0df1d1b9e..815324563cb 100644
--- a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `zip`
 LL | /// See [zip] crate.
    |          ^^^ no item named `zip` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/unused-extern-crate.rs:2:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr
index d46df92649d..c309a55f44d 100644
--- a/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr
+++ b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr
@@ -4,8 +4,8 @@ warning: unresolved link to `error`
 LL | /// [error]
    |      ^^^^^ no item named `error` in scope
    |
-   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
 
 warning: unresolved link to `error1`
   --> $DIR/warning-crlf.rs:12:11
diff --git a/src/test/rustdoc-ui/invalid-doc-attr.stderr b/src/test/rustdoc-ui/invalid-doc-attr.stderr
index a4fa3817905..3c66e587b47 100644
--- a/src/test/rustdoc-ui/invalid-doc-attr.stderr
+++ b/src/test/rustdoc-ui/invalid-doc-attr.stderr
@@ -4,15 +4,15 @@ error: this attribute can only be applied at the crate level
 LL | #[doc(test(no_crate_inject))]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 note: the lint level is defined here
   --> $DIR/invalid-doc-attr.rs:2:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 help: to apply to the crate, use an inner attribute
    |
 LL | #![doc(test(no_crate_inject))]
diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs
index b503d1093fd..acb2a6f084f 100644
--- a/src/test/rustdoc-ui/invalid-syntax.rs
+++ b/src/test/rustdoc-ui/invalid-syntax.rs
@@ -99,3 +99,9 @@ pub fn indent_after_fenced() {}
 /// ```
 pub fn invalid() {}
 //~^^^^ WARNING could not parse code block as Rust code
+
+/// ```
+/// fn wook_at_my_beautifuw_bwaces_plz() {);
+/// ```
+pub fn uwu() {}
+//~^^^^ WARNING could not parse code block as Rust code
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index 4c6249cc6d9..597d19e748c 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -7,10 +7,10 @@ LL | | /// \__________pkt->size___________/          \_result->size_/ \__pkt->si
 LL | | /// ```
    | |_______^
    |
-   = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default
    = note: error from rustc: unknown start of token: \
    = note: error from rustc: unknown start of token: \
    = note: error from rustc: unknown start of token: \
+   = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
@@ -150,5 +150,20 @@ help: mark blocks that do not contain Rust code as text
 LL | /// ```text
    |        ++++
 
-warning: 12 warnings emitted
+warning: could not parse code block as Rust code
+  --> $DIR/invalid-syntax.rs:103:5
+   |
+LL |   /// ```
+   |  _____^
+LL | | /// fn wook_at_my_beautifuw_bwaces_plz() {);
+LL | | /// ```
+   | |_______^
+   |
+   = note: error from rustc: mismatched closing delimiter: `)`
+help: mark blocks that do not contain Rust code as text
+   |
+LL | /// ```text
+   |        ++++
+
+warning: 13 warnings emitted
 
diff --git a/src/test/rustdoc-ui/issue-74134.private.stderr b/src/test/rustdoc-ui/issue-74134.private.stderr
index 31d2dbe9637..44c88b6183a 100644
--- a/src/test/rustdoc-ui/issue-74134.private.stderr
+++ b/src/test/rustdoc-ui/issue-74134.private.stderr
@@ -4,8 +4,8 @@ warning: public documentation for `public_item` links to private item `PrivateTy
 LL |     /// [`PrivateType`]
    |           ^^^^^^^^^^^ this item is private
    |
-   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link resolves only because you passed `--document-private-items`, but will break without
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/issue-74134.public.stderr b/src/test/rustdoc-ui/issue-74134.public.stderr
index 6a3173e3e0d..5b1887b8310 100644
--- a/src/test/rustdoc-ui/issue-74134.public.stderr
+++ b/src/test/rustdoc-ui/issue-74134.public.stderr
@@ -4,8 +4,8 @@ warning: public documentation for `public_item` links to private item `PrivateTy
 LL |     /// [`PrivateType`]
    |           ^^^^^^^^^^^ this item is private
    |
-   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link will resolve properly if you pass `--document-private-items`
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr
index 5336c044574..4f2c9658891 100644
--- a/src/test/rustdoc-ui/lint-group.stderr
+++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -35,8 +35,8 @@ error: unresolved link to `error`
 LL | /// what up, let's make an [error]
    |                             ^^^^^ no item named `error` in scope
    |
-   = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]`
 
 error: unclosed HTML tag `unknown`
   --> $DIR/lint-group.rs:28:5
diff --git a/src/test/rustdoc-ui/macro-docs.stderr b/src/test/rustdoc-ui/macro-docs.stderr
index e3cc1731146..2b136f5be16 100644
--- a/src/test/rustdoc-ui/macro-docs.stderr
+++ b/src/test/rustdoc-ui/macro-docs.stderr
@@ -7,13 +7,13 @@ LL |         /// A
 LL | m!();
    | ---- in this macro invocation
    |
-   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
    = note: the link appears in this line:
            
            [`long_cat`] is really long
             ^^^^^^^^^^
    = note: no item named `long_cat` in scope
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 1 warning emitted
diff --git a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
index 1a1f8085a1b..fb3a5e415df 100644
--- a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
+++ b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
@@ -1,12 +1,12 @@
 error: no documentation found for this crate's top-level module
    |
+   = help: The following guide may be of use:
+           https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 note: the lint level is defined here
   --> $DIR/no-crate-level-doc-lint.rs:3:9
    |
 LL | #![deny(rustdoc::missing_crate_level_docs)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: The following guide may be of use:
-           https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/pub-export-lint.stderr b/src/test/rustdoc-ui/pub-export-lint.stderr
index c6be9c6a9f5..81ef799617c 100644
--- a/src/test/rustdoc-ui/pub-export-lint.stderr
+++ b/src/test/rustdoc-ui/pub-export-lint.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `aloha`
 LL | /// [aloha]
    |      ^^^^^ no item named `aloha` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/pub-export-lint.rs:1:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/reference-link-reports-error-once.stderr b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr
index b46a51e93fb..2ab67090f66 100644
--- a/src/test/rustdoc-ui/reference-link-reports-error-once.stderr
+++ b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr
@@ -4,12 +4,12 @@ error: unresolved link to `ref`
 LL | /// [a]: ref
    |          ^^^ no item named `ref` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/reference-link-reports-error-once.rs:1:9
    |
 LL | #![deny(rustdoc::broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unresolved link to `ref2`
   --> $DIR/reference-link-reports-error-once.rs:15:10
diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
index 8e2a2cdd759..ee9b67cb91b 100644
--- a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
+++ b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
@@ -18,12 +18,12 @@ error: unresolved link to `x`
 LL | //! [x]
    |      ^ no item named `x` in scope
    |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 note: the lint level is defined here
   --> $DIR/renamed-lint-still-applies.rs:2:9
    |
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: this URL is not a hyperlink
   --> $DIR/renamed-lint-still-applies.rs:9:5
@@ -31,12 +31,12 @@ error: this URL is not a hyperlink
 LL | //! http://example.com
    |     ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.com>`
    |
+   = note: bare URLs are not automatically turned into clickable links
 note: the lint level is defined here
   --> $DIR/renamed-lint-still-applies.rs:7:9
    |
 LL | #![deny(rustdoc::non_autolinks)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = note: bare URLs are not automatically turned into clickable links
 
 error: aborting due to 2 previous errors; 2 warnings emitted
 
diff --git a/src/test/rustdoc/anchors.no_const_anchor.html b/src/test/rustdoc/anchors.no_const_anchor.html
index 4da1ffead2a..75e67330a3e 100644
--- a/src/test/rustdoc/anchors.no_const_anchor.html
+++ b/src/test/rustdoc/anchors.no_const_anchor.html
@@ -1 +1 @@
-<div id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></div>
\ No newline at end of file
+<section id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
\ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_trait_method_anchor.html b/src/test/rustdoc/anchors.no_trait_method_anchor.html
index 6b78c7c811a..d7bd525ff0f 100644
--- a/src/test/rustdoc/anchors.no_trait_method_anchor.html
+++ b/src/test/rustdoc/anchors.no_trait_method_anchor.html
@@ -1 +1 @@
-<div id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></div>
\ No newline at end of file
+<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></section>
\ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_tymethod_anchor.html b/src/test/rustdoc/anchors.no_tymethod_anchor.html
index c08f4427cf6..e668e5e4db1 100644
--- a/src/test/rustdoc/anchors.no_tymethod_anchor.html
+++ b/src/test/rustdoc/anchors.no_tymethod_anchor.html
@@ -1 +1 @@
-<div id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></div>
\ No newline at end of file
+<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></section>
\ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_type_anchor.html b/src/test/rustdoc/anchors.no_type_anchor.html
index ba8e65443ec..2c66d5aa315 100644
--- a/src/test/rustdoc/anchors.no_type_anchor.html
+++ b/src/test/rustdoc/anchors.no_type_anchor.html
@@ -1 +1 @@
-<div id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></div>
\ No newline at end of file
+<section id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></section>
\ No newline at end of file
diff --git a/src/test/rustdoc/array-links.link_box_generic.html b/src/test/rustdoc/array-links.link_box_generic.html
new file mode 100644
index 00000000000..3481bb6a025
--- /dev/null
+++ b/src/test/rustdoc/array-links.link_box_generic.html
@@ -0,0 +1 @@
+<code>pub fn delta&lt;T&gt;() -&gt; <a class="struct" href="struct.MyBox.html" title="struct foo::MyBox">MyBox</a>&lt;<a class="primitive" href="{{channel}}/core/primitive.array.html">[T; 1]</a>&gt;</code>
\ No newline at end of file
diff --git a/src/test/rustdoc/array-links.link_box_u32.html b/src/test/rustdoc/array-links.link_box_u32.html
new file mode 100644
index 00000000000..e864ae55c9f
--- /dev/null
+++ b/src/test/rustdoc/array-links.link_box_u32.html
@@ -0,0 +1 @@
+<code>pub fn gamma() -&gt; <a class="struct" href="struct.MyBox.html" title="struct foo::MyBox">MyBox</a>&lt;[<a class="primitive" href="{{channel}}/core/primitive.u32.html">u32</a>; <a class="primitive" href="{{channel}}/core/primitive.array.html">1</a>]&gt;</code>
\ No newline at end of file
diff --git a/src/test/rustdoc/array-links.link_slice_generic.html b/src/test/rustdoc/array-links.link_slice_generic.html
new file mode 100644
index 00000000000..f1ca2f59bd7
--- /dev/null
+++ b/src/test/rustdoc/array-links.link_slice_generic.html
@@ -0,0 +1 @@
+<code>pub fn beta&lt;T&gt;() -&gt; &amp;'static <a class="primitive" href="{{channel}}/core/primitive.array.html">[T; 1]</a></code>
\ No newline at end of file
diff --git a/src/test/rustdoc/array-links.link_slice_u32.html b/src/test/rustdoc/array-links.link_slice_u32.html
new file mode 100644
index 00000000000..c3943e8d321
--- /dev/null
+++ b/src/test/rustdoc/array-links.link_slice_u32.html
@@ -0,0 +1 @@
+<code>pub fn alpha() -&gt; &amp;'static [<a class="primitive" href="{{channel}}/core/primitive.u32.html">u32</a>; <a class="primitive" href="{{channel}}/core/primitive.array.html">1</a>]</code>
\ No newline at end of file
diff --git a/src/test/rustdoc/array-links.rs b/src/test/rustdoc/array-links.rs
new file mode 100644
index 00000000000..07f92ac51b9
--- /dev/null
+++ b/src/test/rustdoc/array-links.rs
@@ -0,0 +1,28 @@
+#![crate_name = "foo"]
+#![no_std]
+
+pub struct MyBox<T: ?Sized>(*const T);
+
+// @has 'foo/fn.alpha.html'
+// @snapshot link_slice_u32 - '//pre[@class="rust fn"]/code'
+pub fn alpha() -> &'static [u32; 1] {
+    loop {}
+}
+
+// @has 'foo/fn.beta.html'
+// @snapshot link_slice_generic - '//pre[@class="rust fn"]/code'
+pub fn beta<T>() -> &'static [T; 1] {
+    loop {}
+}
+
+// @has 'foo/fn.gamma.html'
+// @snapshot link_box_u32 - '//pre[@class="rust fn"]/code'
+pub fn gamma() -> MyBox<[u32; 1]> {
+    loop {}
+}
+
+// @has 'foo/fn.delta.html'
+// @snapshot link_box_generic - '//pre[@class="rust fn"]/code'
+pub fn delta<T>() -> MyBox<[T; 1]> {
+    loop {}
+}
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
new file mode 100644
index 00000000000..927a1a42a1f
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
@@ -0,0 +1 @@
+<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds_with_bindings/trait.Support.html" title="trait assoc_item_trait_bounds_with_bindings::Support">Support</a>&lt;Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt;</h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html
new file mode 100644
index 00000000000..69d84e1b2c1
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html
@@ -0,0 +1 @@
+<h4 class="code-header">type <a href="#associatedtype.Out9" class="associatedtype">Out9</a>: <a class="trait" href="{{channel}}/core/ops/function/trait.FnMut.html" title="trait core::ops::function::FnMut">FnMut</a>(<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>) -&gt; <a class="primitive" href="{{channel}}/std/primitive.bool.html">bool</a> + <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a></h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs
new file mode 100644
index 00000000000..b026f399a56
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs
@@ -0,0 +1,40 @@
+// Regression test for issues #77763, #84579 and #102142.
+#![crate_name = "main"]
+
+// aux-build:assoc_item_trait_bounds_with_bindings.rs
+// build-aux-docs
+// ignore-cross-compile
+extern crate assoc_item_trait_bounds_with_bindings as aux;
+
+// FIXME(fmease): Don't render an incorrect `T: ?Sized` where-clause for parameters
+//                of GATs like `Main::Out{2,4}`. Add a snapshot test once it's fixed.
+// FIXME(fmease): Print the `for<>` parameter list in the bounds of
+//                `Main::Out{6,11,12}`.
+
+// @has main/trait.Main.html
+// @has - '//*[@id="associatedtype.Out0"]' 'type Out0: Support<Item = ()>'
+// @has - '//*[@id="associatedtype.Out1"]' 'type Out1: Support<Item = Self::Item>'
+// @has - '//*[@id="associatedtype.Out2"]' 'type Out2<T>: Support<Item = T>'
+// @has - '//*[@id="associatedtype.Out3"]' 'type Out3: Support<Produce<()> = bool>'
+// @has - '//*[@id="associatedtype.Out4"]' 'type Out4<T>: Support<Produce<T> = T>'
+// @has - '//*[@id="associatedtype.Out5"]' "type Out5: Support<Output<'static> = &'static ()>"
+// @has - '//*[@id="associatedtype.Out6"]' "type Out6: Support<Output<'a> = &'a ()>"
+// @has - '//*[@id="associatedtype.Out7"]' "type Out7: Support<Item = String, Produce<i32> = u32> + Unrelated"
+// @has - '//*[@id="associatedtype.Out8"]' "type Out8: Unrelated + Protocol<i16, Q1 = u128, Q0 = ()>"
+// @has - '//*[@id="associatedtype.Out9"]' "type Out9: FnMut(i32) -> bool + Clone"
+// @has - '//*[@id="associatedtype.Out10"]' "type Out10<'q>: Support<Output<'q> = ()>"
+// @has - '//*[@id="associatedtype.Out11"]' "type Out11: Helper<A<'s> = &'s (), B<'r> = ()>"
+// @has - '//*[@id="associatedtype.Out12"]' "type Out12: Helper<B<'w> = Cow<'w, str>, A<'w> = bool>"
+//
+// Snapshots: Check that we do not render any where-clauses for those associated types since all of
+// the trait bounds contained within were moved to the bounds of the respective item.
+//
+// @snapshot out0 - '//*[@id="associatedtype.Out0"]/*[@class="code-header"]'
+// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
+//
+// @has - '//*[@id="tymethod.make"]' \
+// "fn make<F>(F, impl FnMut(&str) -> bool)\
+// where \
+//     F: FnOnce(u32) -> String, \
+//     Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>"
+pub use aux::Main;
diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs
new file mode 100644
index 00000000000..7225f2dca10
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs
@@ -0,0 +1,40 @@
+pub trait Main {
+    type Item;
+
+    type Out0: Support<Item = ()>;
+    type Out1: Support<Item = Self::Item>;
+    type Out2<T>: Support<Item = T>;
+    type Out3: Support<Produce<()> = bool>;
+    type Out4<T>: Support<Produce<T> = T>;
+    type Out5: Support<Output<'static> = &'static ()>;
+    type Out6: for<'a> Support<Output<'a> = &'a ()>;
+    type Out7: Support<Item = String, Produce<i32> = u32> + Unrelated;
+    type Out8: Unrelated + Protocol<i16, Q1 = u128, Q0 = ()>;
+    type Out9: FnMut(i32) -> bool + Clone;
+    type Out10<'q>: Support<Output<'q> = ()>;
+    type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>;
+    type Out12: for<'w> Helper<B<'w> = std::borrow::Cow<'w, str>, A<'w> = bool>;
+
+    fn make<F>(_: F, _: impl FnMut(&str) -> bool)
+    where
+        F: FnOnce(u32) -> String,
+        Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>;
+}
+
+pub trait Support {
+    type Item;
+    type Output<'a>;
+    type Produce<T>;
+}
+
+pub trait Protocol<K> {
+    type Q0;
+    type Q1;
+}
+
+pub trait Unrelated {}
+
+pub trait Helper {
+    type A<'q>;
+    type B<'q>;
+}
diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
index 8bd402291aa..602ee1b1b1f 100644
--- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs
+++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
@@ -18,10 +18,10 @@ pub struct S<T>(T);
 // @has - '//pre[@class="rust trait"]/code/span[@class="where"]' ': Clone'
 #[const_trait]
 pub trait Tr<T> {
-    // @!has - '//div[@id="method.a"]/h4[@class="code-header"]' '~const'
-    // @has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
-    // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
-    // @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
+    // @!has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const'
+    // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
+    // @!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"]' ': Clone'
     fn a<A: ~const Clone + ~const Destruct>()
     where
         Option<A>: ~const Clone + ~const Destruct,
diff --git a/src/test/rustdoc/safe-intrinsic.rs b/src/test/rustdoc/safe-intrinsic.rs
index d3bb8514b7e..d08abdaeb14 100644
--- a/src/test/rustdoc/safe-intrinsic.rs
+++ b/src/test/rustdoc/safe-intrinsic.rs
@@ -1,5 +1,6 @@
 #![feature(intrinsics)]
 #![feature(no_core)]
+#![feature(rustc_attrs)]
 
 #![no_core]
 #![crate_name = "foo"]
@@ -7,6 +8,7 @@
 extern "rust-intrinsic" {
     // @has 'foo/fn.abort.html'
     // @has - '//pre[@class="rust fn"]' 'pub extern "rust-intrinsic" fn abort() -> !'
+    #[rustc_safe_intrinsic]
     pub fn abort() -> !;
     // @has 'foo/fn.unreachable.html'
     // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
diff --git a/src/test/rustdoc/toggle-trait-fn.rs b/src/test/rustdoc/toggle-trait-fn.rs
index 65e8daeb066..e41422ce7c5 100644
--- a/src/test/rustdoc/toggle-trait-fn.rs
+++ b/src/test/rustdoc/toggle-trait-fn.rs
@@ -4,12 +4,12 @@
 // summary. Trait methods with no documentation should not be wrapped.
 //
 // @has foo/trait.Foo.html
-// @has -  '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'is_documented()'
-// @!has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'not_documented()'
-// @has -  '//details[@class="rustdoc-toggle"]//*[@class="docblock"]' 'is_documented is documented'
-// @has -  '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'is_documented_optional()'
-// @!has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'not_documented_optional()'
-// @has -  '//details[@class="rustdoc-toggle"]//*[@class="docblock"]' 'is_documented_optional is documented'
+// @has -  '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'is_documented()'
+// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented()'
+// @has -  '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented is documented'
+// @has -  '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'is_documented_optional()'
+// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented_optional()'
+// @has -  '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented_optional is documented'
 pub trait Foo {
     fn not_documented();
 
diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
index 03da804bd1c..c05443488c3 100644
--- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
+++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs
@@ -49,9 +49,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingAllowedAttrPass {
 
         let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr");
         if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) {
-            cx.lint(MISSING_ALLOWED_ATTR, |lint| {
-                lint.build("Missing 'allowed_attr' attribute").set_span(span).emit();
-            });
+            cx.lint(
+                MISSING_ALLOWED_ATTR,
+                "Missing 'allowed_attr' attribute",
+                |lint| lint.set_span(span)
+            );
         }
     }
 }
diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
index 0b1534939b7..073da688c7c 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs
@@ -29,9 +29,11 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
         let attrs = cx.tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
         let span = cx.tcx.def_span(CRATE_DEF_ID);
         if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) {
-            cx.lint(CRATE_NOT_OKAY, |lint| {
-                lint.build("crate is not marked with #![crate_okay]").set_span(span).emit();
-            });
+            cx.lint(
+                CRATE_NOT_OKAY,
+                "crate is not marked with #![crate_okay]",
+                |lint| lint.set_span(span)
+            );
         }
     }
 }
diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
index 2d41b5f30e9..4a41e7fbb72 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs
@@ -22,12 +22,10 @@ declare_lint_pass!(Pass => [TEST_LINT, PLEASE_LINT]);
 impl<'tcx> LateLintPass<'tcx> for Pass {
     fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) {
         match it.ident.as_str() {
-            "lintme" => cx.lint(TEST_LINT, |lint| {
-                lint.build("item is named 'lintme'").set_span(it.span).emit();
-            }),
-            "pleaselintme" => cx.lint(PLEASE_LINT, |lint| {
-                lint.build("item is named 'pleaselintme'").set_span(it.span).emit();
-            }),
+            "lintme" => cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)),
+            "pleaselintme" => {
+                cx.lint(PLEASE_LINT, "item is named 'pleaselintme'", |lint| lint.set_span(it.span))
+            }
             _ => {}
         }
     }
diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
index 285754928c2..30956deb799 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs
@@ -21,9 +21,7 @@ declare_lint_pass!(Pass => [TEST_LINT]);
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
         if it.ident.name.as_str() == "lintme" {
-            cx.lint(TEST_LINT, |lint| {
-                lint.build("item is named 'lintme'").set_span(it.span).emit();
-            });
+            cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span));
         }
     }
 }
diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
index 3d5dba42b5f..c2c024865e8 100644
--- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs
@@ -31,14 +31,10 @@ declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP, TEST_RUSTC_TOOL_LINT]);
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
         if it.ident.name.as_str() == "lintme" {
-            cx.lint(TEST_LINT, |lint| {
-                lint.build("item is named 'lintme'").set_span(it.span).emit();
-            });
+            cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span));
         }
         if it.ident.name.as_str() == "lintmetoo" {
-            cx.lint(TEST_GROUP, |lint| {
-                lint.build("item is named 'lintmetoo'").set_span(it.span).emit();
-            });
+            cx.lint(TEST_GROUP, "item is named 'lintmetoo'", |lint| lint.set_span(it.span));
         }
     }
 }
diff --git a/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr b/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr
index 9d13ee89bca..3cb13082f25 100644
--- a/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr
+++ b/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr
@@ -4,12 +4,12 @@ error: prefer `FxHashMap` over `HashMap`, it has better performance
 LL |     let _map: HashMap<String, String> = HashMap::default();
    |                                         ^^^^^^^
    |
+   = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 note: the lint level is defined here
   --> $DIR/default_hash_types.rs:4:9
    |
 LL | #![deny(rustc::default_hash_types)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 
 error: prefer `FxHashMap` over `HashMap`, it has better performance
   --> $DIR/default_hash_types.rs:16:15
diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
index 18e39108eca..9a5100ce17f 100644
--- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs
@@ -19,14 +19,14 @@ use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::Span;
 
 #[derive(Diagnostic)]
-#[diag(parser::expect_path)]
+#[diag(compiletest::example)]
 struct DeriveDiagnostic {
     #[primary_span]
     span: Span,
 }
 
 #[derive(Subdiagnostic)]
-#[note(parser::add_paren)]
+#[note(compiletest::example)]
 struct Note {
     #[primary_span]
     span: Span,
@@ -45,7 +45,7 @@ pub struct TranslatableInIntoDiagnostic;
 
 impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic {
     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
-        handler.struct_err(fluent::parser::expect_path)
+        handler.struct_err(fluent::compiletest::example)
     }
 }
 
@@ -62,12 +62,12 @@ pub struct TranslatableInAddToDiagnostic;
 
 impl AddToDiagnostic for TranslatableInAddToDiagnostic {
     fn add_to_diagnostic(self, diag: &mut Diagnostic) {
-        diag.note(fluent::typeck::note);
+        diag.note(fluent::compiletest::note);
     }
 }
 
 pub fn make_diagnostics<'a>(handler: &'a Handler) {
-    let _diag = handler.struct_err(fluent::parser::expect_path);
+    let _diag = handler.struct_err(fluent::compiletest::example);
     //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
 
     let _diag = handler.struct_err("untranslatable diagnostic");
diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr
index 9219d09e9b4..f5f92ac1e7f 100644
--- a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr
+++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr
@@ -19,7 +19,7 @@ LL |         diag.note("untranslatable diagnostic");
 error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
   --> $DIR/diagnostics.rs:70:25
    |
-LL |     let _diag = handler.struct_err(fluent::parser::expect_path);
+LL |     let _diag = handler.struct_err(fluent::compiletest::example);
    |                         ^^^^^^^^^^
    |
 note: the lint level is defined here
diff --git a/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
index bc9fcdd7bc7..4e296fff6d0 100644
--- a/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
+++ b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
@@ -4,12 +4,12 @@ error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]`
 LL | #[doc(keyword = "tadam")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = help: only existing keywords are allowed in core/std
 note: the lint level is defined here
   --> $DIR/existing_doc_keyword.rs:8:9
    |
 LL | #![deny(rustc::existing_doc_keyword)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: only existing keywords are allowed in core/std
 
 error: aborting due to previous error
 
diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
index 9df6be65eb3..ad6e93334cd 100644
--- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
+++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr
@@ -4,12 +4,12 @@ error: implementing `LintPass` by hand
 LL | impl LintPass for Foo {
    |      ^^^^^^^^
    |
+   = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
 note: the lint level is defined here
   --> $DIR/lint_pass_impl_without_macro.rs:4:9
    |
 LL | #![deny(rustc::lint_pass_impl_without_macro)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
 error: implementing `LintPass` by hand
   --> $DIR/lint_pass_impl_without_macro.rs:30:14
diff --git a/src/test/ui-fulldeps/internal-lints/query_stability.stderr b/src/test/ui-fulldeps/internal-lints/query_stability.stderr
index 7e8b448f41a..ee4ef998237 100644
--- a/src/test/ui-fulldeps/internal-lints/query_stability.stderr
+++ b/src/test/ui-fulldeps/internal-lints/query_stability.stderr
@@ -4,12 +4,12 @@ error: using `drain` can result in unstable query results
 LL |     for _ in x.drain() {}
    |                ^^^^^
    |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 note: the lint level is defined here
   --> $DIR/query_stability.rs:4:9
    |
 LL | #![deny(rustc::potential_query_instability)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
 error: using `iter` can result in unstable query results
   --> $DIR/query_stability.rs:16:16
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index 3d363cae473..1dc71abc104 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -28,15 +28,15 @@ use rustc_errors::{Applicability, MultiSpan};
 extern crate rustc_session;
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct Hello {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct HelloWarn {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 //~^ ERROR unsupported type attribute for diagnostic derive enum
 enum DiagnosticOnEnum {
     Foo,
@@ -46,13 +46,13 @@ enum DiagnosticOnEnum {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 #[diag = "E0123"]
 //~^ ERROR `#[diag = ...]` is not a valid attribute
 struct WrongStructAttrStyle {}
 
 #[derive(Diagnostic)]
-#[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[nonsense(compiletest::example, code = "E0123")]
 //~^ ERROR `#[nonsense(...)]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 //~^^^ ERROR cannot find attribute `nonsense` in this scope
@@ -90,12 +90,12 @@ struct InvalidNestedStructAttr2 {}
 struct InvalidNestedStructAttr3 {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
+#[diag(compiletest::example, code = "E0123", slug = "foo")]
 //~^ ERROR `#[diag(slug = ...)]` is not a valid attribute
 struct InvalidNestedStructAttr4 {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct WrongPlaceField {
     #[suggestion = "bar"]
     //~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -103,20 +103,20 @@ struct WrongPlaceField {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
+#[diag(compiletest::example, code = "E0123")]
+#[diag(compiletest::example, code = "E0456")]
 //~^ ERROR specified multiple times
 //~^^ ERROR specified multiple times
 struct DiagSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
+#[diag(compiletest::example, code = "E0456", code = "E0457")]
 //~^ ERROR specified multiple times
 struct CodeSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
-//~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
+#[diag(compiletest::example, compiletest::example, code = "E0456")]
+//~^ ERROR `#[diag(compiletest::example)]` is not a valid attribute
 struct SlugSpecifiedTwice {}
 
 #[derive(Diagnostic)]
@@ -128,11 +128,11 @@ struct KindNotProvided {} //~ ERROR diagnostic slug not specified
 struct SlugNotProvided {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound)]
+#[diag(compiletest::example)]
 struct CodeNotProvided {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct MessageWrongType {
     #[primary_span]
     //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -140,7 +140,7 @@ struct MessageWrongType {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct InvalidPathFieldAttr {
     #[nonsense]
     //~^ ERROR `#[nonsense]` is not a valid attribute
@@ -149,34 +149,34 @@ struct InvalidPathFieldAttr {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithField {
     name: String,
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithMessageAppliedToField {
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
     name: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithNonexistentField {
-    #[suggestion(typeck::suggestion, code = "{name}")]
+    #[suggestion(compiletest::suggestion, code = "{name}")]
     //~^ ERROR `name` doesn't refer to a field on this type
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: expected `'}'`
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorMissingClosingBrace {
-    #[suggestion(typeck::suggestion, code = "{name")]
+    #[suggestion(compiletest::suggestion, code = "{name")]
     suggestion: (Span, Applicability),
     name: String,
     val: usize,
@@ -184,49 +184,49 @@ struct ErrorMissingClosingBrace {
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: unmatched `}`
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorMissingOpeningBrace {
-    #[suggestion(typeck::suggestion, code = "name}")]
+    #[suggestion(compiletest::suggestion, code = "name}")]
     suggestion: (Span, Applicability),
     name: String,
     val: usize,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct LabelOnSpan {
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     sp: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct LabelOnNonSpan {
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
     id: u32,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct Suggest {
-    #[suggestion(typeck::suggestion, code = "This is the suggested code")]
-    #[suggestion_short(typeck::suggestion, code = "This is the suggested code")]
-    #[suggestion_hidden(typeck::suggestion, code = "This is the suggested code")]
-    #[suggestion_verbose(typeck::suggestion, code = "This is the suggested code")]
+    #[suggestion(compiletest::suggestion, code = "This is the suggested code")]
+    #[suggestion_short(compiletest::suggestion, code = "This is the suggested code")]
+    #[suggestion_hidden(compiletest::suggestion, code = "This is the suggested code")]
+    #[suggestion_verbose(compiletest::suggestion, code = "This is the suggested code")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithoutCode {
-    #[suggestion(typeck::suggestion)]
+    #[suggestion(compiletest::suggestion)]
     //~^ ERROR suggestion without `code = "..."`
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithBadKey {
     #[suggestion(nonsense = "bar")]
     //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute
@@ -235,7 +235,7 @@ struct SuggestWithBadKey {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithShorthandMsg {
     #[suggestion(msg = "bar")]
     //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute
@@ -244,52 +244,52 @@ struct SuggestWithShorthandMsg {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithoutMsg {
     #[suggestion(code = "bar")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithTypesSwapped {
-    #[suggestion(typeck::suggestion, code = "This is suggested code")]
+    #[suggestion(compiletest::suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Span),
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithWrongTypeApplicabilityOnly {
-    #[suggestion(typeck::suggestion, code = "This is suggested code")]
+    #[suggestion(compiletest::suggestion, code = "This is suggested code")]
     //~^ ERROR wrong field type for suggestion
     suggestion: Applicability,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithSpanOnly {
-    #[suggestion(typeck::suggestion, code = "This is suggested code")]
+    #[suggestion(compiletest::suggestion, code = "This is suggested code")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithDuplicateSpanAndApplicability {
-    #[suggestion(typeck::suggestion, code = "This is suggested code")]
+    #[suggestion(compiletest::suggestion, code = "This is suggested code")]
     suggestion: (Span, Span, Applicability),
     //~^ ERROR specified multiple times
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct SuggestWithDuplicateApplicabilityAndSpan {
-    #[suggestion(typeck::suggestion, code = "This is suggested code")]
+    #[suggestion(compiletest::suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Applicability, Span),
     //~^ ERROR specified multiple times
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct WrongKindOfAnnotation {
     #[label = "bar"]
     //~^ ERROR `#[label = ...]` is not a valid attribute
@@ -297,38 +297,38 @@ struct WrongKindOfAnnotation {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct OptionsInErrors {
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     label: Option<Span>,
-    #[suggestion(typeck::suggestion, code = "...")]
+    #[suggestion(compiletest::suggestion, code = "...")]
     opt_sugg: Option<(Span, Applicability)>,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
+#[diag(compiletest::example, code = "E0456")]
 struct MoveOutOfBorrowError<'tcx> {
     name: Ident,
     ty: Ty<'tcx>,
     #[primary_span]
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     span: Span,
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     other_span: Span,
-    #[suggestion(typeck::suggestion, code = "{name}.clone()")]
+    #[suggestion(compiletest::suggestion, code = "{name}.clone()")]
     opt_sugg: Option<(Span, Applicability)>,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithLifetime<'a> {
-    #[label(typeck::label)]
+    #[label(compiletest::label)]
     span: Span,
     name: &'a str,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithDefaultLabelAttr<'a> {
     #[label]
     span: Span,
@@ -337,7 +337,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
 
 #[derive(Diagnostic)]
 //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ArgFieldWithoutSkip {
     #[primary_span]
     span: Span,
@@ -345,7 +345,7 @@ struct ArgFieldWithoutSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ArgFieldWithSkip {
     #[primary_span]
     span: Span,
@@ -356,116 +356,116 @@ struct ArgFieldWithSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithSpannedNote {
     #[note]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithSpannedNoteCustom {
-    #[note(typeck::note)]
+    #[note(compiletest::note)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 #[note]
 struct ErrorWithNote {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[note(typeck::note)]
+#[diag(compiletest::example, code = "E0123")]
+#[note(compiletest::note)]
 struct ErrorWithNoteCustom {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithSpannedHelp {
     #[help]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithSpannedHelpCustom {
-    #[help(typeck::help)]
+    #[help(compiletest::help)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 #[help]
 struct ErrorWithHelp {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[help(typeck::help)]
+#[diag(compiletest::example, code = "E0123")]
+#[help(compiletest::help)]
 struct ErrorWithHelpCustom {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[help]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithHelpWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[help(typeck::help)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[help(compiletest::help)]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithHelpCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[note]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithNoteWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[note(typeck::note)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[note(compiletest::note)]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithNoteCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ApplicabilityInBoth {
-    #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
+    #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")]
     //~^ ERROR specified multiple times
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct InvalidApplicability {
-    #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
+    #[suggestion(compiletest::suggestion, code = "...", applicability = "batman")]
     //~^ ERROR invalid applicability
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ValidApplicability {
-    #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
+    #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct NoApplicability {
-    #[suggestion(typeck::suggestion, code = "...")]
+    #[suggestion(compiletest::suggestion, code = "...")]
     suggestion: Span,
 }
 
@@ -474,14 +474,14 @@ struct NoApplicability {
 struct Note;
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound)]
+#[diag(compiletest::example)]
 struct Subdiagnostic {
     #[subdiagnostic]
     note: Note,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct VecField {
     #[primary_span]
     #[label]
@@ -489,58 +489,58 @@ struct VecField {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct UnitField {
     #[primary_span]
     spans: Span,
     #[help]
     foo: (),
-    #[help(typeck::help)]
+    #[help(compiletest::help)]
     bar: (),
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct OptUnitField {
     #[primary_span]
     spans: Span,
     #[help]
     foo: Option<()>,
-    #[help(typeck::help)]
+    #[help(compiletest::help)]
     bar: Option<()>,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct LabelWithTrailingPath {
-    #[label(typeck::label, foo)]
+    #[label(compiletest::label, foo)]
     //~^ ERROR `#[label(foo)]` is not a valid attribute
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct LabelWithTrailingNameValue {
-    #[label(typeck::label, foo = "...")]
+    #[label(compiletest::label, foo = "...")]
     //~^ ERROR `#[label(foo = ...)]` is not a valid attribute
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct LabelWithTrailingList {
-    #[label(typeck::label, foo("..."))]
+    #[label(compiletest::label, foo("..."))]
     //~^ ERROR `#[label(foo(...))]` is not a valid attribute
     span: Span,
 }
 
 #[derive(LintDiagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound)]
+#[diag(compiletest::example)]
 struct LintsGood {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound)]
+#[diag(compiletest::example)]
 struct PrimarySpanOnLint {
     #[primary_span]
     //~^ ERROR `#[primary_span]` is not a valid attribute
@@ -548,97 +548,98 @@ struct PrimarySpanOnLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct ErrorWithMultiSpan {
     #[primary_span]
     span: MultiSpan,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 #[warning]
 struct ErrorWithWarn {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[error(compiletest::example, code = "E0123")]
 //~^ ERROR `#[error(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `error` in this scope
 struct ErrorAttribute {}
 
 #[derive(Diagnostic)]
-#[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[warn_(compiletest::example, code = "E0123")]
 //~^ ERROR `#[warn_(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `warn_` in this scope
 struct WarnAttribute {}
 
 #[derive(Diagnostic)]
-#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[lint(compiletest::example, code = "E0123")]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `lint` in this scope
 struct LintAttributeOnSessionDiag {}
 
 #[derive(LintDiagnostic)]
-#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[lint(compiletest::example, code = "E0123")]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
+//~| ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `lint` in this scope
 struct LintAttributeOnLintDiag {}
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct DuplicatedSuggestionCode {
-    #[suggestion(typeck::suggestion, code = "...", code = ",,,")]
+    #[suggestion(compiletest::suggestion, code = "...", code = ",,,")]
     //~^ ERROR specified multiple times
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct InvalidTypeInSuggestionTuple {
-    #[suggestion(typeck::suggestion, code = "...")]
+    #[suggestion(compiletest::suggestion, code = "...")]
     suggestion: (Span, usize),
     //~^ ERROR wrong types for suggestion
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct MissingApplicabilityInSuggestionTuple {
-    #[suggestion(typeck::suggestion, code = "...")]
+    #[suggestion(compiletest::suggestion, code = "...")]
     suggestion: (Span,),
     //~^ ERROR wrong types for suggestion
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct MissingCodeInSuggestion {
-    #[suggestion(typeck::suggestion)]
+    #[suggestion(compiletest::suggestion)]
     //~^ ERROR suggestion without `code = "..."`
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[multipart_suggestion(typeck::suggestion)]
+#[diag(compiletest::example, code = "E0123")]
+#[multipart_suggestion(compiletest::suggestion)]
 //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
 //~| ERROR cannot find attribute `multipart_suggestion` in this scope
 #[multipart_suggestion()]
 //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
 //~| ERROR cannot find attribute `multipart_suggestion` in this scope
 struct MultipartSuggestion {
-    #[multipart_suggestion(typeck::suggestion)]
+    #[multipart_suggestion(compiletest::suggestion)]
     //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
     //~| ERROR cannot find attribute `multipart_suggestion` in this scope
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-#[suggestion(typeck::suggestion, code = "...")]
+#[diag(compiletest::example, code = "E0123")]
+#[suggestion(compiletest::suggestion, code = "...")]
 //~^ ERROR `#[suggestion(...)]` is not a valid attribute
 struct SuggestionOnStruct {
     #[primary_span]
@@ -646,7 +647,7 @@ struct SuggestionOnStruct {
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 #[label]
 //~^ ERROR `#[label]` is not a valid attribute
 struct LabelOnStruct {
@@ -656,24 +657,24 @@ struct LabelOnStruct {
 
 #[derive(Diagnostic)]
 enum ExampleEnum {
-    #[diag(typeck::ambiguous_lifetime_bound)]
+    #[diag(compiletest::example)]
     Foo {
         #[primary_span]
         sp: Span,
         #[note]
         note_sp: Span,
     },
-    #[diag(typeck::ambiguous_lifetime_bound)]
+    #[diag(compiletest::example)]
     Bar {
         #[primary_span]
         sp: Span,
     },
-    #[diag(typeck::ambiguous_lifetime_bound)]
+    #[diag(compiletest::example)]
     Baz,
 }
 
 #[derive(Diagnostic)]
-#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
+#[diag(compiletest::example, code = "E0123")]
 struct RawIdentDiagnosticArg {
     pub r#type: String,
 }
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 21a402c7b9d..167198b47f2 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,8 +1,8 @@
 error: unsupported type attribute for diagnostic derive enum
   --> $DIR/diagnostic-derive.rs:39:1
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:42:5
@@ -10,7 +10,7 @@ error: diagnostic slug not specified
 LL |     Foo,
    |     ^^^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:44:5
@@ -18,7 +18,7 @@ error: diagnostic slug not specified
 LL |     Bar,
    |     ^^^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[diag = ...]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:50:1
@@ -29,20 +29,20 @@ LL | #[diag = "E0123"]
 error: `#[nonsense(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:55:1
    |
-LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[nonsense(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:55:1
    |
-LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[nonsense(compiletest::example, code = "E0123")]
 LL | |
 LL | |
 LL | |
 LL | | struct InvalidStructAttr {}
    | |___________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[diag("...")]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:62:8
@@ -61,7 +61,7 @@ LL | |
 LL | | struct InvalidLitNestedAttr {}
    | |______________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[diag(nonsense(...))]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:73:8
@@ -80,7 +80,7 @@ LL | |
 LL | | struct InvalidNestedStructAttr1 {}
    | |__________________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[diag(nonsense = ...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:79:8
@@ -108,7 +108,7 @@ LL | |
 LL | | struct InvalidNestedStructAttr2 {}
    | |__________________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[diag(nonsense = ...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:86:8
@@ -134,13 +134,13 @@ LL | |
 LL | | struct InvalidNestedStructAttr3 {}
    | |__________________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[diag(slug = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:93:58
+  --> $DIR/diagnostic-derive.rs:93:46
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")]
-   |                                                          ^^^^^^^^^^^^
+LL | #[diag(compiletest::example, code = "E0123", slug = "foo")]
+   |                                              ^^^^^^^^^^^^
    |
    = help: only `code` is a valid nested attributes following the slug
 
@@ -153,44 +153,44 @@ LL |     #[suggestion = "bar"]
 error: specified multiple times
   --> $DIR/diagnostic-derive.rs:107:8
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(compiletest::example, code = "E0456")]
+   |        ^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
   --> $DIR/diagnostic-derive.rs:106:8
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(compiletest::example, code = "E0123")]
+   |        ^^^^^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:107:49
+  --> $DIR/diagnostic-derive.rs:107:37
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")]
-   |                                                 ^^^^^^^
+LL | #[diag(compiletest::example, code = "E0456")]
+   |                                     ^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:106:49
+  --> $DIR/diagnostic-derive.rs:106:37
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   |                                                 ^^^^^^^
+LL | #[diag(compiletest::example, code = "E0123")]
+   |                                     ^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:113:65
+  --> $DIR/diagnostic-derive.rs:113:53
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
-   |                                                                 ^^^^^^^
+LL | #[diag(compiletest::example, code = "E0456", code = "E0457")]
+   |                                                     ^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:113:49
+  --> $DIR/diagnostic-derive.rs:113:37
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")]
-   |                                                 ^^^^^^^
+LL | #[diag(compiletest::example, code = "E0456", code = "E0457")]
+   |                                     ^^^^^^^
 
-error: `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:118:42
+error: `#[diag(compiletest::example)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:118:30
    |
-LL | #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")]
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(compiletest::example, compiletest::example, code = "E0456")]
+   |                              ^^^^^^^^^^^^^^^^^^^^
    |
    = help: diagnostic slug must be the first argument
 
@@ -200,7 +200,7 @@ error: diagnostic slug not specified
 LL | struct KindNotProvided {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:126:1
@@ -210,7 +210,7 @@ LL | |
 LL | | struct SlugNotProvided {}
    | |_________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
   --> $DIR/diagnostic-derive.rs:137:5
@@ -227,14 +227,14 @@ LL |     #[nonsense]
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
   --> $DIR/diagnostic-derive.rs:162:5
    |
-LL |     #[label(typeck::label)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[label(compiletest::label)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `name` doesn't refer to a field on this type
-  --> $DIR/diagnostic-derive.rs:170:45
+  --> $DIR/diagnostic-derive.rs:170:50
    |
-LL |     #[suggestion(typeck::suggestion, code = "{name}")]
-   |                                             ^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion, code = "{name}")]
+   |                                                  ^^^^^^^^
 
 error: invalid format string: expected `'}'` but string was terminated
   --> $DIR/diagnostic-derive.rs:175:10
@@ -257,14 +257,14 @@ LL | #[derive(Diagnostic)]
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
   --> $DIR/diagnostic-derive.rs:205:5
    |
-LL |     #[label(typeck::label)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[label(compiletest::label)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: suggestion without `code = "..."`
   --> $DIR/diagnostic-derive.rs:223:5
    |
-LL |     #[suggestion(typeck::suggestion)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion(nonsense = ...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:231:18
@@ -297,7 +297,7 @@ LL |     #[suggestion(msg = "bar")]
 error: wrong field type for suggestion
   --> $DIR/diagnostic-derive.rs:263:5
    |
-LL | /     #[suggestion(typeck::suggestion, code = "This is suggested code")]
+LL | /     #[suggestion(compiletest::suggestion, code = "This is suggested code")]
 LL | |
 LL | |     suggestion: Applicability,
    | |_____________________________^
@@ -335,10 +335,10 @@ LL |     #[label = "bar"]
    |     ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:445:52
+  --> $DIR/diagnostic-derive.rs:445:57
    |
-LL |     #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
-   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")]
+   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
   --> $DIR/diagnostic-derive.rs:447:24
@@ -347,30 +347,30 @@ LL |     suggestion: (Span, Applicability),
    |                        ^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/diagnostic-derive.rs:453:52
+  --> $DIR/diagnostic-derive.rs:453:57
    |
-LL |     #[suggestion(typeck::suggestion, code = "...", applicability = "batman")]
-   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion, code = "...", applicability = "batman")]
+   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[label(foo)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:516:28
+  --> $DIR/diagnostic-derive.rs:516:33
    |
-LL |     #[label(typeck::label, foo)]
-   |                            ^^^
+LL |     #[label(compiletest::label, foo)]
+   |                                 ^^^
    |
    = help: a diagnostic slug must be the first argument to the attribute
 
 error: `#[label(foo = ...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:524:28
+  --> $DIR/diagnostic-derive.rs:524:33
    |
-LL |     #[label(typeck::label, foo = "...")]
-   |                            ^^^^^^^^^^^
+LL |     #[label(compiletest::label, foo = "...")]
+   |                                 ^^^^^^^^^^^
 
 error: `#[label(foo(...))]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:532:28
+  --> $DIR/diagnostic-derive.rs:532:33
    |
-LL |     #[label(typeck::label, foo("..."))]
-   |                            ^^^^^^^^^^
+LL |     #[label(compiletest::label, foo("..."))]
+   |                                 ^^^^^^^^^^
 
 error: `#[primary_span]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:545:5
@@ -383,89 +383,96 @@ LL |     #[primary_span]
 error: `#[error(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:565:1
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:565:1
    |
-LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[error(compiletest::example, code = "E0123")]
 LL | |
 LL | |
 LL | |
 LL | | struct ErrorAttribute {}
    | |________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[warn_(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:572:1
    |
-LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[warn_(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:572:1
    |
-LL | / #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[warn_(compiletest::example, code = "E0123")]
 LL | |
 LL | |
 LL | |
 LL | | struct WarnAttribute {}
    | |_______________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[lint(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:579:1
    |
-LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:579:1
    |
-LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[lint(compiletest::example, code = "E0123")]
 LL | |
 LL | |
 LL | |
 LL | | struct LintAttributeOnSessionDiag {}
    | |____________________________________^
    |
-   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]`
 
 error: `#[lint(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:586:1
    |
-LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[lint(...)]` is not a valid attribute
+  --> $DIR/diagnostic-derive.rs:586:1
+   |
+LL | #[lint(compiletest::example, code = "E0123")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
   --> $DIR/diagnostic-derive.rs:586:1
    |
-LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | / #[lint(compiletest::example, code = "E0123")]
+LL | |
 LL | |
 LL | |
 LL | |
 LL | | struct LintAttributeOnLintDiag {}
    | |_________________________________^
    |
-   = help: specify the slug as the first argument to the attribute, such as `#[diag(typeck::example_error)]`
+   = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest::example)]`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:595:52
+  --> $DIR/diagnostic-derive.rs:596:57
    |
-LL |     #[suggestion(typeck::suggestion, code = "...", code = ",,,")]
-   |                                                    ^^^^^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion, code = "...", code = ",,,")]
+   |                                                         ^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:595:38
+  --> $DIR/diagnostic-derive.rs:596:43
    |
-LL |     #[suggestion(typeck::suggestion, code = "...", code = ",,,")]
-   |                                      ^^^^^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion, code = "...", code = ",,,")]
+   |                                           ^^^^^^^^^^^^
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:604:24
+  --> $DIR/diagnostic-derive.rs:605:24
    |
 LL |     suggestion: (Span, usize),
    |                        ^^^^^
@@ -473,7 +480,7 @@ LL |     suggestion: (Span, usize),
    = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:612:17
+  --> $DIR/diagnostic-derive.rs:613:17
    |
 LL |     suggestion: (Span,),
    |                 ^^^^^^^
@@ -481,21 +488,21 @@ LL |     suggestion: (Span,),
    = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:619:5
+  --> $DIR/diagnostic-derive.rs:620:5
    |
-LL |     #[suggestion(typeck::suggestion)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[suggestion(compiletest::suggestion)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:626:1
+  --> $DIR/diagnostic-derive.rs:627:1
    |
-LL | #[multipart_suggestion(typeck::suggestion)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[multipart_suggestion(compiletest::suggestion)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:629:1
+  --> $DIR/diagnostic-derive.rs:630:1
    |
 LL | #[multipart_suggestion()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -503,23 +510,23 @@ LL | #[multipart_suggestion()]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:633:5
+  --> $DIR/diagnostic-derive.rs:634:5
    |
-LL |     #[multipart_suggestion(typeck::suggestion)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[multipart_suggestion(compiletest::suggestion)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:641:1
+  --> $DIR/diagnostic-derive.rs:642:1
    |
-LL | #[suggestion(typeck::suggestion, code = "...")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(compiletest::suggestion, code = "...")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `#[label]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:650:1
+  --> $DIR/diagnostic-derive.rs:651:1
    |
 LL | #[label]
    | ^^^^^^^^
@@ -529,7 +536,7 @@ LL | #[label]
 error: cannot find attribute `nonsense` in this scope
   --> $DIR/diagnostic-derive.rs:55:3
    |
-LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | #[nonsense(compiletest::example, code = "E0123")]
    |   ^^^^^^^^
 
 error: cannot find attribute `nonsense` in this scope
@@ -541,43 +548,43 @@ LL |     #[nonsense]
 error: cannot find attribute `error` in this scope
   --> $DIR/diagnostic-derive.rs:565:3
    |
-LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | #[error(compiletest::example, code = "E0123")]
    |   ^^^^^
 
 error: cannot find attribute `warn_` in this scope
   --> $DIR/diagnostic-derive.rs:572:3
    |
-LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | #[warn_(compiletest::example, code = "E0123")]
    |   ^^^^^ help: a built-in attribute with a similar name exists: `warn`
 
 error: cannot find attribute `lint` in this scope
   --> $DIR/diagnostic-derive.rs:579:3
    |
-LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | #[lint(compiletest::example, code = "E0123")]
    |   ^^^^ help: a built-in attribute with a similar name exists: `link`
 
 error: cannot find attribute `lint` in this scope
   --> $DIR/diagnostic-derive.rs:586:3
    |
-LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")]
+LL | #[lint(compiletest::example, code = "E0123")]
    |   ^^^^ help: a built-in attribute with a similar name exists: `link`
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:626:3
+  --> $DIR/diagnostic-derive.rs:627:3
    |
-LL | #[multipart_suggestion(typeck::suggestion)]
+LL | #[multipart_suggestion(compiletest::suggestion)]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:629:3
+  --> $DIR/diagnostic-derive.rs:630:3
    |
 LL | #[multipart_suggestion()]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:633:7
+  --> $DIR/diagnostic-derive.rs:634:7
    |
-LL |     #[multipart_suggestion(typeck::suggestion)]
+LL |     #[multipart_suggestion(compiletest::suggestion)]
    |       ^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent`
@@ -600,7 +607,7 @@ LL |         arg: impl IntoDiagnosticArg,
    |                   ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg`
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 74 previous errors
+error: aborting due to 75 previous errors
 
 Some errors have detailed explanations: E0277, E0425.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/abi/stack-probes-lto.rs b/src/test/ui/abi/stack-probes-lto.rs
index 74b5e843f77..6d934538f4c 100644
--- a/src/test/ui/abi/stack-probes-lto.rs
+++ b/src/test/ui/abi/stack-probes-lto.rs
@@ -3,8 +3,6 @@
 // ignore-aarch64
 // ignore-mips
 // ignore-mips64
-// ignore-powerpc
-// ignore-s390x
 // ignore-sparc
 // ignore-sparc64
 // ignore-wasm
diff --git a/src/test/ui/abi/stack-probes.rs b/src/test/ui/abi/stack-probes.rs
index b497af7abad..e7b91644b3b 100644
--- a/src/test/ui/abi/stack-probes.rs
+++ b/src/test/ui/abi/stack-probes.rs
@@ -3,8 +3,6 @@
 // ignore-aarch64
 // ignore-mips
 // ignore-mips64
-// ignore-powerpc
-// ignore-s390x
 // ignore-sparc
 // ignore-sparc64
 // ignore-wasm
@@ -27,8 +25,9 @@ fn main() {
     let args = env::args().skip(1).collect::<Vec<_>>();
     if args.len() > 0 {
         match &args[0][..] {
-            "main-thread" => recurse(&MaybeUninit::uninit()),
-            "child-thread" => thread::spawn(|| recurse(&MaybeUninit::uninit())).join().unwrap(),
+            "main-recurse" => overflow_recurse(),
+            "child-recurse" => thread::spawn(overflow_recurse).join().unwrap(),
+            "child-frame" => overflow_frame(),
             _ => panic!(),
         }
         return;
@@ -41,9 +40,10 @@ fn main() {
     // that we report stack overflow on the main thread, see #43052 for some
     // details
     if cfg!(not(target_os = "linux")) {
-        assert_overflow(Command::new(&me).arg("main-thread"));
+        assert_overflow(Command::new(&me).arg("main-recurse"));
     }
-    assert_overflow(Command::new(&me).arg("child-thread"));
+    assert_overflow(Command::new(&me).arg("child-recurse"));
+    assert_overflow(Command::new(&me).arg("child-frame"));
 }
 
 #[allow(unconditional_recursion)]
@@ -55,6 +55,23 @@ fn recurse(array: &MaybeUninit<[u64; 1024]>) {
     recurse(&local);
 }
 
+#[inline(never)]
+fn overflow_recurse() {
+    recurse(&MaybeUninit::uninit());
+}
+
+fn overflow_frame() {
+    // By using a 1MiB stack frame with only 512KiB stack, we'll jump over any
+    // guard page, even with 64K pages -- but stack probes should catch it.
+    const STACK_SIZE: usize = 512 * 1024;
+    thread::Builder::new().stack_size(STACK_SIZE).spawn(|| {
+        let local: MaybeUninit<[u8; 2 * STACK_SIZE]> = MaybeUninit::uninit();
+        unsafe {
+            black_box(local.as_ptr() as u64);
+        }
+    }).unwrap().join().unwrap();
+}
+
 fn assert_overflow(cmd: &mut Command) {
     let output = cmd.output().unwrap();
     assert!(!output.status.success());
diff --git a/src/test/ui/abi/unsupported.aarch64.stderr b/src/test/ui/abi/unsupported.aarch64.stderr
index a948947dbdb..e86a73ea60f 100644
--- a/src/test/ui/abi/unsupported.aarch64.stderr
+++ b/src/test/ui/abi/unsupported.aarch64.stderr
@@ -52,9 +52,9 @@ warning: use of calling convention not supported on this target
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 error: aborting due to 8 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/abi/unsupported.arm.stderr b/src/test/ui/abi/unsupported.arm.stderr
index 297354c2828..f7569c8cdd7 100644
--- a/src/test/ui/abi/unsupported.arm.stderr
+++ b/src/test/ui/abi/unsupported.arm.stderr
@@ -46,9 +46,9 @@ warning: use of calling convention not supported on this target
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 error: aborting due to 7 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/abi/unsupported.x64.stderr b/src/test/ui/abi/unsupported.x64.stderr
index 49b88cd3fac..26023a4584e 100644
--- a/src/test/ui/abi/unsupported.x64.stderr
+++ b/src/test/ui/abi/unsupported.x64.stderr
@@ -46,9 +46,9 @@ warning: use of calling convention not supported on this target
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
 
 error: aborting due to 7 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/abi/x86stdcall.rs b/src/test/ui/abi/x86stdcall.rs
index 868923e5932..d1cf1319fb0 100644
--- a/src/test/ui/abi/x86stdcall.rs
+++ b/src/test/ui/abi/x86stdcall.rs
@@ -1,17 +1,15 @@
 // run-pass
-// ignore-wasm32-bare no libc to test ffi with
-// ignore-sgx no libc
+// only-windows
 // GetLastError doesn't seem to work with stack switching
 
 #[cfg(windows)]
 mod kernel32 {
-  extern "system" {
-    pub fn SetLastError(err: usize);
-    pub fn GetLastError() -> usize;
-  }
+    extern "system" {
+        pub fn SetLastError(err: usize);
+        pub fn GetLastError() -> usize;
+    }
 }
 
-
 #[cfg(windows)]
 pub fn main() {
     unsafe {
@@ -22,17 +20,3 @@ pub fn main() {
         assert_eq!(expected, actual);
     }
 }
-
-#[cfg(any(target_os = "android",
-          target_os = "dragonfly",
-          target_os = "emscripten",
-          target_os = "freebsd",
-          target_os = "fuchsia",
-          target_os = "illumos",
-          target_os = "linux",
-          target_os = "macos",
-          target_os = "netbsd",
-          target_os = "openbsd",
-          target_os = "solaris",
-          target_os = "vxworks"))]
-pub fn main() { }
diff --git a/src/test/ui/abi/x86stdcall2.rs b/src/test/ui/abi/x86stdcall2.rs
index 563e3aba632..4d508ecb242 100644
--- a/src/test/ui/abi/x86stdcall2.rs
+++ b/src/test/ui/abi/x86stdcall2.rs
@@ -1,4 +1,5 @@
 // run-pass
+// only-windows
 
 #![allow(non_camel_case_types)]
 pub type HANDLE = usize;
@@ -7,20 +8,16 @@ pub type SIZE_T = u32;
 pub type LPVOID = usize;
 pub type BOOL = u8;
 
-#[cfg(windows)]
 mod kernel32 {
-    use super::{HANDLE, DWORD, SIZE_T, LPVOID, BOOL};
+    use super::{BOOL, DWORD, HANDLE, LPVOID, SIZE_T};
 
     extern "system" {
         pub fn GetProcessHeap() -> HANDLE;
-        pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T)
-                      -> LPVOID;
+        pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
         pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
     }
 }
 
-
-#[cfg(windows)]
 pub fn main() {
     let heap = unsafe { kernel32::GetProcessHeap() };
     let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) };
@@ -28,6 +25,3 @@ pub fn main() {
     let res = unsafe { kernel32::HeapFree(heap, 0, mem) };
     assert!(res != 0);
 }
-
-#[cfg(not(windows))]
-pub fn main() { }
diff --git a/src/test/ui/anon-params/anon-params-deprecated.stderr b/src/test/ui/anon-params/anon-params-deprecated.stderr
index 474b14f59e3..691e2c79512 100644
--- a/src/test/ui/anon-params/anon-params-deprecated.stderr
+++ b/src/test/ui/anon-params/anon-params-deprecated.stderr
@@ -4,13 +4,13 @@ warning: anonymous parameters are deprecated and will be removed in the next edi
 LL |     fn foo(i32);
    |            ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
 note: the lint level is defined here
   --> $DIR/anon-params-deprecated.rs:1:9
    |
 LL | #![warn(anonymous_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
 
 warning: anonymous parameters are deprecated and will be removed in the next edition
   --> $DIR/anon-params-deprecated.rs:12:30
diff --git a/src/test/ui/array-slice-vec/array_const_index-0.stderr b/src/test/ui/array-slice-vec/array_const_index-0.stderr
index 4832398713d..154872915d6 100644
--- a/src/test/ui/array-slice-vec/array_const_index-0.stderr
+++ b/src/test/ui/array-slice-vec/array_const_index-0.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const B: i32 = (&A)[1];
    | ------------   ^^^^^^^ index out of bounds: the length is 0 but the index is 1
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -17,7 +17,7 @@ error: any use of this value will cause an error
 LL | const B: i32 = (&A)[1];
    | ------------   ^^^^^^^ index out of bounds: the length is 0 but the index is 1
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/array-slice-vec/array_const_index-1.stderr b/src/test/ui/array-slice-vec/array_const_index-1.stderr
index 361f518c052..a13b5b4ccc1 100644
--- a/src/test/ui/array-slice-vec/array_const_index-1.stderr
+++ b/src/test/ui/array-slice-vec/array_const_index-1.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const B: i32 = A[1];
    | ------------   ^^^^ index out of bounds: the length is 0 but the index is 1
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -17,7 +17,7 @@ error: any use of this value will cause an error
 LL | const B: i32 = A[1];
    | ------------   ^^^^ index out of bounds: the length is 0 but the index is 1
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/asm/aarch64/type-check-3.stderr b/src/test/ui/asm/aarch64/type-check-3.stderr
index 49292982eec..f710df2dcde 100644
--- a/src/test/ui/asm/aarch64/type-check-3.stderr
+++ b/src/test/ui/asm/aarch64/type-check-3.stderr
@@ -4,9 +4,9 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{}", in(reg) 0u8);
    |               ^^           --- for this argument
    |
-   = note: `#[warn(asm_sub_register)]` on by default
    = help: use `{0:w}` to have the register formatted as `w0`
    = help: or use `{0:x}` to keep the default formatting of `x0`
+   = note: `#[warn(asm_sub_register)]` on by default
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:50:15
diff --git a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
index 5dac693cc27..bb6a222b22e 100644
--- a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
@@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
    |
-   = note: `#[warn(asm_sub_register)]` on by default
    = help: use `{0:w}` to have the register formatted as `w0`
    = help: or use `{0:x}` to keep the default formatting of `x0`
+   = note: `#[warn(asm_sub_register)]` on by default
 
 error: aborting due to 21 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
index 5dac693cc27..bb6a222b22e 100644
--- a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
@@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
    |
-   = note: `#[warn(asm_sub_register)]` on by default
    = help: use `{0:w}` to have the register formatted as `w0`
    = help: or use `{0:x}` to keep the default formatting of `x0`
+   = note: `#[warn(asm_sub_register)]` on by default
 
 error: aborting due to 21 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
index b29b74bac80..903b5e959f3 100644
--- a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
@@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
    |
-   = note: `#[warn(asm_sub_register)]` on by default
    = help: use `{0:e}` to have the register formatted as `eax`
    = help: or use `{0:r}` to keep the default formatting of `rax`
+   = note: `#[warn(asm_sub_register)]` on by default
 
 error: aborting due to 21 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
index b29b74bac80..903b5e959f3 100644
--- a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
@@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
    |
-   = note: `#[warn(asm_sub_register)]` on by default
    = help: use `{0:e}` to have the register formatted as `eax`
    = help: or use `{0:r}` to keep the default formatting of `rax`
+   = note: `#[warn(asm_sub_register)]` on by default
 
 error: aborting due to 21 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/asm/naked-functions-ffi.stderr b/src/test/ui/asm/naked-functions-ffi.stderr
index ac743551311..908881b1949 100644
--- a/src/test/ui/asm/naked-functions-ffi.stderr
+++ b/src/test/ui/asm/naked-functions-ffi.stderr
@@ -4,9 +4,9 @@ warning: `extern` fn uses type `char`, which is not FFI-safe
 LL | pub extern "C" fn naked(p: char) -> u128 {
    |                            ^^^^ not FFI-safe
    |
-   = note: `#[warn(improper_ctypes_definitions)]` on by default
    = help: consider using `u32` or `libc::wchar_t` instead
    = note: the `char` type has no C equivalent
+   = note: `#[warn(improper_ctypes_definitions)]` on by default
 
 warning: `extern` fn uses type `u128`, which is not FFI-safe
   --> $DIR/naked-functions-ffi.rs:9:37
diff --git a/src/test/ui/asm/named-asm-labels.stderr b/src/test/ui/asm/named-asm-labels.stderr
index 001601497a2..c8380629e12 100644
--- a/src/test/ui/asm/named-asm-labels.stderr
+++ b/src/test/ui/asm/named-asm-labels.stderr
@@ -4,9 +4,9 @@ error: avoid using named labels in inline assembly
 LL |         asm!("bar: nop");
    |               ^^^
    |
-   = note: `#[deny(named_asm_labels)]` on by default
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
+   = note: `#[deny(named_asm_labels)]` on by default
 
 error: avoid using named labels in inline assembly
   --> $DIR/named-asm-labels.rs:27:15
@@ -259,13 +259,13 @@ warning: avoid using named labels in inline assembly
 LL |             asm!("warned: nop");
    |                   ^^^^^^
    |
+   = help: only local labels of the form `<number>:` should be used in inline asm
+   = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
 note: the lint level is defined here
   --> $DIR/named-asm-labels.rs:132:16
    |
 LL |         #[warn(named_asm_labels)]
    |                ^^^^^^^^^^^^^^^^
-   = help: only local labels of the form `<number>:` should be used in inline asm
-   = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
   --> $DIR/named-asm-labels.rs:143:20
diff --git a/src/test/ui/asm/x86_64/type-check-3.stderr b/src/test/ui/asm/x86_64/type-check-3.stderr
index 366038fea23..1baf50ff6e0 100644
--- a/src/test/ui/asm/x86_64/type-check-3.stderr
+++ b/src/test/ui/asm/x86_64/type-check-3.stderr
@@ -44,9 +44,9 @@ warning: formatting may not be suitable for sub-register argument
 LL |         asm!("{0} {0}", in(reg) 0i16);
    |               ^^^ ^^^           ---- for this argument
    |
-   = note: `#[warn(asm_sub_register)]` on by default
    = help: use `{0:x}` to have the register formatted as `ax`
    = help: or use `{0:r}` to keep the default formatting of `rax`
+   = note: `#[warn(asm_sub_register)]` on by default
 
 warning: formatting may not be suitable for sub-register argument
   --> $DIR/type-check-3.rs:36:15
diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
index 66ee6031c71..8a7c16e6117 100644
--- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
+++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL |     const B: u8 = Self::A + 1;
    |     -----------   ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/defaults-not-assumed-fail.rs:34:16
@@ -34,9 +34,9 @@ error: any use of this value will cause an error
 LL |     const B: u8 = Self::A + 1;
    |     -----------   ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: erroneous constant used
@@ -45,8 +45,8 @@ error: erroneous constant used
 LL |     assert_eq!(<() as Tr>::B, 0);    // causes the error above
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/associated-types/defaults-specialization.stderr b/src/test/ui/associated-types/defaults-specialization.stderr
index 2d61b2a647b..8df326351fa 100644
--- a/src/test/ui/associated-types/defaults-specialization.stderr
+++ b/src/test/ui/associated-types/defaults-specialization.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(associated_type_defaults, specialization)]
    |                                      ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:19:18
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
index 50a82c08c3f..d99967eb23c 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
+++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
@@ -4,13 +4,13 @@ error: `await` is a keyword in the 2018 edition
 LL |     pub mod await {
    |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/2015-edition-error-various-positions.rs:2:9
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
   --> $DIR/2015-edition-error-various-positions.rs:7:20
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
index 1c4c19ea45f..bf5c4d8d6aa 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
+++ b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
@@ -4,13 +4,13 @@ error: `await` is a keyword in the 2018 edition
 LL |     pub mod await {
    |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/2015-edition-warning.rs:4:9
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
   --> $DIR/2015-edition-warning.rs:10:20
diff --git a/src/test/ui/async-await/large_moves.attribute.stderr b/src/test/ui/async-await/large_moves.attribute.stderr
index 8d3f0b77f43..da34f44b2d6 100644
--- a/src/test/ui/async-await/large_moves.attribute.stderr
+++ b/src/test/ui/async-await/large_moves.attribute.stderr
@@ -10,12 +10,12 @@ LL | |         dbg!(y);
 LL | |     };
    | |_____^ value moved from here
    |
+   = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
 note: the lint level is defined here
   --> $DIR/large_moves.rs:1:9
    |
 LL | #![deny(large_assignments)]
    |         ^^^^^^^^^^^^^^^^^
-   = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
 
 error: moving 10024 bytes
   --> $DIR/large_moves.rs:18:14
diff --git a/src/test/ui/async-await/large_moves.option.stderr b/src/test/ui/async-await/large_moves.option.stderr
index 8d3f0b77f43..da34f44b2d6 100644
--- a/src/test/ui/async-await/large_moves.option.stderr
+++ b/src/test/ui/async-await/large_moves.option.stderr
@@ -10,12 +10,12 @@ LL | |         dbg!(y);
 LL | |     };
    | |_____^ value moved from here
    |
+   = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
 note: the lint level is defined here
   --> $DIR/large_moves.rs:1:9
    |
 LL | #![deny(large_assignments)]
    |         ^^^^^^^^^^^^^^^^^
-   = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
 
 error: moving 10024 bytes
   --> $DIR/large_moves.rs:18:14
diff --git a/src/test/ui/attributes/doc-attr.stderr b/src/test/ui/attributes/doc-attr.stderr
index cc2494c92e6..68df2771fd7 100644
--- a/src/test/ui/attributes/doc-attr.stderr
+++ b/src/test/ui/attributes/doc-attr.stderr
@@ -4,14 +4,14 @@ error: unknown `doc` attribute `as_ptr`
 LL | #[doc(as_ptr)]
    |       ^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/doc-attr.rs:2:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: invalid `doc` attribute
   --> $DIR/doc-attr.rs:12:7
diff --git a/src/test/ui/attributes/invalid-doc-attr.stderr b/src/test/ui/attributes/invalid-doc-attr.stderr
index a4fa3817905..3c66e587b47 100644
--- a/src/test/ui/attributes/invalid-doc-attr.stderr
+++ b/src/test/ui/attributes/invalid-doc-attr.stderr
@@ -4,15 +4,15 @@ error: this attribute can only be applied at the crate level
 LL | #[doc(test(no_crate_inject))]
    |       ^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 note: the lint level is defined here
   --> $DIR/invalid-doc-attr.rs:2:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 help: to apply to the crate, use an inner attribute
    |
 LL | #![doc(test(no_crate_inject))]
diff --git a/src/test/ui/auto-traits/suspicious-impls-lint.stderr b/src/test/ui/auto-traits/suspicious-impls-lint.stderr
index 97b2d7221fd..9cd4e79f851 100644
--- a/src/test/ui/auto-traits/suspicious-impls-lint.stderr
+++ b/src/test/ui/auto-traits/suspicious-impls-lint.stderr
@@ -4,11 +4,6 @@ error: cross-crate traits with a default impl, like `Send`, should not be specia
 LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/suspicious-impls-lint.rs:1:9
-   |
-LL | #![deny(suspicious_auto_trait_impls)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
    = note: `&T` is not a generic parameter
@@ -17,6 +12,11 @@ note: try using the same sequence of generic parameters as the struct definition
    |
 LL | struct MayImplementSendErr<T>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/suspicious-impls-lint.rs:1:9
+   |
+LL | #![deny(suspicious_auto_trait_impls)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cross-crate traits with a default impl, like `Send`, should not be specialized
   --> $DIR/suspicious-impls-lint.rs:21:1
diff --git a/src/test/ui/binding/issue-53114-safety-checks.stderr b/src/test/ui/binding/issue-53114-safety-checks.stderr
index f3840273cfa..57a065d6d4d 100644
--- a/src/test/ui/binding/issue-53114-safety-checks.stderr
+++ b/src/test/ui/binding/issue-53114-safety-checks.stderr
@@ -4,11 +4,11 @@ error: reference to packed field is unaligned
 LL |     let _ = &p.b;
    |             ^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 error: reference to packed field is unaligned
   --> $DIR/issue-53114-safety-checks.rs:29:17
@@ -109,11 +109,11 @@ error: reference to packed field is unaligned
 LL |     let _ = &p.b;
    |             ^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -122,11 +122,11 @@ error: reference to packed field is unaligned
 LL |     let (_,) = (&p.b,);
    |                 ^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -135,11 +135,11 @@ error: reference to packed field is unaligned
 LL |     match &p.b  { _ => { } }
    |           ^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -148,9 +148,9 @@ error: reference to packed field is unaligned
 LL |     match (&p.b,)  { (_,) => { } }
    |            ^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr
index 2412dcd32f7..9be0367ae38 100644
--- a/src/test/ui/block-result/consider-removing-last-semi.stderr
+++ b/src/test/ui/block-result/consider-removing-last-semi.stderr
@@ -7,7 +7,7 @@ LL | pub fn f() -> String {
    |        implicitly returns `()` as its body has no tail or `return` expression
 LL |     0u8;
 LL |     "bla".to_string();
-   |                      - help: remove this semicolon
+   |                      - help: remove this semicolon to return this value
 
 error[E0308]: mismatched types
   --> $DIR/consider-removing-last-semi.rs:8:15
@@ -18,7 +18,7 @@ LL | pub fn g() -> String {
    |        implicitly returns `()` as its body has no tail or `return` expression
 LL |     "this won't work".to_string();
 LL |     "removeme".to_string();
-   |                           - help: remove this semicolon
+   |                           - help: remove this semicolon to return this value
 
 error[E0308]: mismatched types
   --> $DIR/consider-removing-last-semi.rs:13:25
@@ -29,7 +29,7 @@ LL | pub fn macro_tests() -> u32 {
    |        implicitly returns `()` as its body has no tail or `return` expression
 ...
 LL |     mac!();
-   |           - help: remove this semicolon
+   |           - help: remove this semicolon to return this value
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr
index 5b8d96fd4eb..42fb3d3d43d 100644
--- a/src/test/ui/block-result/issue-11714.stderr
+++ b/src/test/ui/block-result/issue-11714.stderr
@@ -7,7 +7,7 @@ LL | fn blah() -> i32 {
    |    implicitly returns `()` as its body has no tail or `return` expression
 ...
 LL |     ;
-   |     - help: remove this semicolon
+   |     - help: remove this semicolon to return this value
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr
index a33448edff2..2b386d10c53 100644
--- a/src/test/ui/block-result/issue-13428.stderr
+++ b/src/test/ui/block-result/issue-13428.stderr
@@ -15,7 +15,7 @@ LL | fn bar() -> String {
    |    implicitly returns `()` as its body has no tail or `return` expression
 LL |     "foobar".to_string()
 LL |     ;
-   |     - help: remove this semicolon
+   |     - help: remove this semicolon to return this value
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/issue-102209.rs b/src/test/ui/borrowck/issue-102209.rs
new file mode 100644
index 00000000000..37628bff7df
--- /dev/null
+++ b/src/test/ui/borrowck/issue-102209.rs
@@ -0,0 +1,28 @@
+use std::marker::PhantomData;
+
+pub struct NfaBuilder<'brand> {
+    brand: PhantomData<&'brand mut &'brand mut ()>,
+}
+
+impl NfaBuilder<'_> {
+    pub fn with<R, F: FnOnce(NfaBuilder<'_>) -> R>(f: F) -> R {
+        Brand::with(|brand| {
+            f(Self { brand: brand.lt })
+            //~^ ERROR lifetime may not live long enough
+            //~| ERROR lifetime may not live long enough
+        })
+    }
+}
+
+#[derive(Clone, Copy)]
+pub struct Brand<'brand> {
+    lt: PhantomData<&'brand mut &'brand mut ()>,
+}
+
+impl Brand<'_> {
+    pub fn with<R, F: FnOnce(Brand<'_>) -> R>(f: F) -> R {
+        f(Self { lt: PhantomData })
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/issue-102209.stderr b/src/test/ui/borrowck/issue-102209.stderr
new file mode 100644
index 00000000000..351de8217b2
--- /dev/null
+++ b/src/test/ui/borrowck/issue-102209.stderr
@@ -0,0 +1,22 @@
+error: lifetime may not live long enough
+  --> $DIR/issue-102209.rs:10:29
+   |
+LL | impl NfaBuilder<'_> {
+   |                 -- lifetime `'2` appears in the `impl`'s self type
+LL |     pub fn with<R, F: FnOnce(NfaBuilder<'_>) -> R>(f: F) -> R {
+LL |         Brand::with(|brand| {
+   |                      ----- has type `Brand<'1>`
+LL |             f(Self { brand: brand.lt })
+   |                             ^^^^^^^^ this usage requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/issue-102209.rs:10:29
+   |
+LL | impl NfaBuilder<'_> {
+   |                 -- lifetime `'1` appears in the `impl`'s self type
+...
+LL |             f(Self { brand: brand.lt })
+   |                             ^^^^^^^^ this usage requires that `'1` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr
index fd591c7b563..19cd323ce57 100644
--- a/src/test/ui/borrowck/issue-81899.stderr
+++ b/src/test/ui/borrowck/issue-81899.stderr
@@ -18,9 +18,9 @@ error: any use of this value will cause an error
 LL | const _CONST: &[u8] = &f(&[], |_| {});
    | -------------------   ^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 2 previous errors
 
@@ -32,7 +32,7 @@ error: any use of this value will cause an error
 LL | const _CONST: &[u8] = &f(&[], |_| {});
    | -------------------   ^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr
index a3582e78041..4492af7ec6b 100644
--- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr
+++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr
@@ -18,9 +18,9 @@ error: any use of this value will cause an error
 LL | const _CONST: &() = &f(&|_| {});
    | -----------------   ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 2 previous errors
 
@@ -32,7 +32,7 @@ error: any use of this value will cause an error
 LL | const _CONST: &() = &f(&|_| {});
    | -----------------   ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
index a6c65b302db..a889e67f4ea 100644
--- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
+++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
@@ -18,9 +18,9 @@ error: any use of this value will cause an error
 LL | const _CONST: &[u8] = &f(&[], |_| {});
    | -------------------   ^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 2 previous errors
 
@@ -32,7 +32,7 @@ error: any use of this value will cause an error
 LL | const _CONST: &[u8] = &f(&[], |_| {});
    | -------------------   ^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/cenum_impl_drop_cast.stderr b/src/test/ui/cenum_impl_drop_cast.stderr
index 98c33105733..b3f921c14ed 100644
--- a/src/test/ui/cenum_impl_drop_cast.stderr
+++ b/src/test/ui/cenum_impl_drop_cast.stderr
@@ -4,13 +4,13 @@ error: cannot cast enum `E` into integer `u32` because it implements `Drop`
 LL |     let i = e as u32;
    |             ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>
 note: the lint level is defined here
   --> $DIR/cenum_impl_drop_cast.rs:1:9
    |
 LL | #![deny(cenum_impl_drop_cast)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>
 
 error: aborting due to previous error
 
@@ -21,11 +21,11 @@ error: cannot cast enum `E` into integer `u32` because it implements `Drop`
 LL |     let i = e as u32;
    |             ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>
 note: the lint level is defined here
   --> $DIR/cenum_impl_drop_cast.rs:1:9
    |
 LL | #![deny(cenum_impl_drop_cast)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>
 
diff --git a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr
index b52535ffdba..9ce4710d69b 100644
--- a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr
+++ b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr
@@ -4,9 +4,9 @@ error: `crate_type` within an `#![cfg_attr] attribute is deprecated`
 LL | #![cfg_attr(foo, crate_type="bin")]
    |                  ^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #91632 <https://github.com/rust-lang/rust/issues/91632>
+   = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` on by default
 
 error: `crate_name` within an `#![cfg_attr] attribute is deprecated`
   --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:9:18
diff --git a/src/test/ui/check-cfg/compact-values.stderr b/src/test/ui/check-cfg/compact-values.stderr
index a196e1537df..9864aa385f9 100644
--- a/src/test/ui/check-cfg/compact-values.stderr
+++ b/src/test/ui/check-cfg/compact-values.stderr
@@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value
 LL | #[cfg(target(os = "linux", arch = "X"))]
    |                            ^^^^^^^^^^
    |
-   = note: `#[warn(unexpected_cfgs)]` on by default
    = note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64
+   = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/check-cfg/empty-values.stderr b/src/test/ui/check-cfg/empty-values.stderr
index 10dab503489..a0168b2caa8 100644
--- a/src/test/ui/check-cfg/empty-values.stderr
+++ b/src/test/ui/check-cfg/empty-values.stderr
@@ -6,8 +6,8 @@ LL | #[cfg(test = "value")]
    |           |
    |           help: remove the value
    |
-   = note: `#[warn(unexpected_cfgs)]` on by default
    = note: no expected value for `test`
+   = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr
index 7db2aadec17..60abcb18824 100644
--- a/src/test/ui/check-cfg/invalid-cfg-value.stderr
+++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr
@@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value
 LL | #[cfg(feature = "sedre")]
    |       ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unexpected_cfgs)]` on by default
    = note: expected values for `feature` are: full, serde
+   = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value
   --> $DIR/invalid-cfg-value.rs:14:7
diff --git a/src/test/ui/check-cfg/no-values.stderr b/src/test/ui/check-cfg/no-values.stderr
index 7025b4cd7ba..8c926d187fe 100644
--- a/src/test/ui/check-cfg/no-values.stderr
+++ b/src/test/ui/check-cfg/no-values.stderr
@@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value
 LL | #[cfg(feature = "foo")]
    |       ^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unexpected_cfgs)]` on by default
    = note: no expected value for `feature`
+   = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value
   --> $DIR/no-values.rs:10:7
diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr
index 24ce2280c8a..4ec74494fe0 100644
--- a/src/test/ui/check-cfg/well-known-values.stderr
+++ b/src/test/ui/check-cfg/well-known-values.stderr
@@ -6,8 +6,8 @@ LL | #[cfg(target_os = "linuz")]
    |                   |
    |                   help: did you mean: `"linux"`
    |
-   = note: `#[warn(unexpected_cfgs)]` on by default
    = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous
+   = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value
   --> $DIR/well-known-values.rs:14:7
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
index 7e767cba3cc..cf414adc0b9 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
@@ -4,13 +4,13 @@ warning: value captured by `a` is never read
 LL |         a = 1;
    |         ^
    |
+   = help: did you mean to capture by reference instead?
 note: the lint level is defined here
   --> $DIR/liveness.rs:5:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
-   = help: did you mean to capture by reference instead?
 
 warning: unused variable: `a`
   --> $DIR/liveness.rs:33:9
@@ -18,8 +18,8 @@ warning: unused variable: `a`
 LL |         a += 1;
    |         ^
    |
-   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
    = help: did you mean to capture by reference instead?
+   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
 
 warning: value assigned to `a` is never read
   --> $DIR/liveness.rs:53:9
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
index 2ac801b49f1..0410de4c798 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
@@ -4,13 +4,13 @@ warning: value assigned to `a` is never read
 LL |         a = s;
    |         ^
    |
+   = help: maybe it is overwritten before being read?
 note: the lint level is defined here
   --> $DIR/liveness_unintentional_copy.rs:4:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
-   = help: maybe it is overwritten before being read?
 
 warning: unused variable: `a`
   --> $DIR/liveness_unintentional_copy.rs:20:9
@@ -18,8 +18,8 @@ warning: unused variable: `a`
 LL |         a = s;
    |         ^
    |
-   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
    = help: did you mean to capture by reference instead?
+   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `a`
   --> $DIR/liveness_unintentional_copy.rs:36:9
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
index 93abbecf4e4..508c4b911b7 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
@@ -4,11 +4,11 @@ error: reference to packed field is unaligned
 LL |         println!("{}", foo.x);
    |                        ^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
@@ -20,10 +20,10 @@ error: reference to packed field is unaligned
 LL |         println!("{}", foo.x);
    |                        ^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr
index 15689023d81..b3cb558f976 100644
--- a/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr
@@ -4,9 +4,9 @@ warning: irrefutable `if let` guard pattern
 LL |             Registry if let _ = registry.try_find_description() => { }
    |                             ^
    |
-   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this pattern will always match, so the guard is useless
    = help: consider removing the guard and adding a `let` inside the match arm
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr b/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr
index 3e921dc0f8a..c1679c6b637 100644
--- a/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr
@@ -10,12 +10,12 @@ LL |         let _ = f0;
 LL | }
    | - in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/issue-90465.rs:3:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `f0` to be fully captured
    |
 LL ~     let c0 = move || {
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
index 2a49ed4b5ff..38401085971 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
@@ -18,8 +18,8 @@ LL | |         Variant::B => (),
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: closures are lazy and do nothing unless called
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: unused closure that must be used
   --> $DIR/issue-87097.rs:26:5
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
index d7104bafeb1..3a42cc8b843 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
@@ -7,12 +7,12 @@ LL |     thread::spawn(move || unsafe {
 LL |         *fptr.0 = 20;
    |         ------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0`
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/auto_traits.rs:2:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `fptr` to be fully captured
    |
 LL ~     thread::spawn(move || { let _ = &fptr; unsafe {
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
index c611daf13fd..bb17e3a34af 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
@@ -15,13 +15,13 @@ LL | |         println!("{:?}", x);
 LL | |     });
    | |______- in this macro invocation
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/closure-body-macro-fragment.rs:4:9
    |
 LL | #![warn(rust_2021_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(rust_2021_incompatible_closure_captures)]` implied by `#[warn(rust_2021_compatibility)]`
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: add a dummy let to cause `a` to be fully captured
    |
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
index 832a81711b1..a0795c12928 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
@@ -10,12 +10,12 @@ LL |         let _t = t.0;
 LL | }
    | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/insignificant_drop_attr_migrations.rs:3:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL ~     let c = || {
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
index 41b675f7960..36a80e694e8 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
@@ -4,9 +4,9 @@ warning: irrefutable `if let` pattern
 LL |     if let a = "" {
    |        ^^^^^^^^^^
    |
-   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this pattern will always match, so the `if let` is useless
    = help: consider replacing the `if let` with a `let`
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr
index 2d0c56aad8d..c17edce72f9 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr
@@ -7,12 +7,12 @@ LL |     let _ = || dbg!(a.0);
 LL | }
    | - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/macro.rs:5:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `a` to be fully captured
    |
 LL |     let _ = || { let _ = &a; dbg!(a.0) };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
index 12760cc7256..94526487e67 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
@@ -10,12 +10,12 @@ LL |         let _t = t.0;
 LL | }
    | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/migrations_rustfix.rs:2:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL ~     let c = || {
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
index 62cfcbe95bc..e10898f9844 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
@@ -10,12 +10,12 @@ LL |     let result = panic::catch_unwind(move || {
 LL |         f.0()
    |         --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/mir_calls_to_shims.rs:4:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `f` to be fully captured
    |
 LL ~     let result = panic::catch_unwind(move || {
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
index 96d5c936fa5..efb264447f6 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
@@ -13,12 +13,12 @@ LL |         let _f_2 = f2.1;
 LL | }
    | - in Rust 2018, `f2` is dropped here, but in Rust 2021, only `f2.1` will be dropped here as part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/multi_diagnostics.rs:2:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `f1`, `f2` to be fully captured
    |
 LL ~     let c = || {
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
index aa9b8672a0f..eff26a4d6f5 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
@@ -10,12 +10,12 @@ LL |         let _t = t.0;
 LL | }
    | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/precise.rs:3:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL ~     let c = || {
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
index 0d9f09ee354..54ad20f8983 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
@@ -20,12 +20,12 @@ LL | }
    | in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
    | in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 note: the lint level is defined here
   --> $DIR/significant_drop.rs:2:9
    |
 LL | #![deny(rust_2021_incompatible_closure_captures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
    |
 LL ~     let c = || {
diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed b/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed
index 623e917da07..8aa9e952b99 100644
--- a/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed
+++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed
@@ -7,6 +7,6 @@ fn foo() -> i32 {
 fn main() {
     let _x: i32 = {
         //~^ ERROR mismatched types
-        foo() //~ HELP remove this semicolon
+        foo() //~ HELP remove this semicolon to return this value
     };
 }
diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.rs b/src/test/ui/closures/old-closure-expression-remove-semicolon.rs
index 4974b086649..912c7a3314a 100644
--- a/src/test/ui/closures/old-closure-expression-remove-semicolon.rs
+++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.rs
@@ -7,6 +7,6 @@ fn foo() -> i32 {
 fn main() {
     let _x: i32 = {
         //~^ ERROR mismatched types
-        foo(); //~ HELP remove this semicolon
+        foo(); //~ HELP remove this semicolon to return this value
     };
 }
diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr b/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr
index 9b73ce4fee3..bc54ab4d511 100644
--- a/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr
+++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr
@@ -5,7 +5,7 @@ LL |       let _x: i32 = {
    |  ___________________^
 LL | |
 LL | |         foo();
-   | |              - help: remove this semicolon
+   | |              - help: remove this semicolon to return this value
 LL | |     };
    | |_____^ expected `i32`, found `()`
 
diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr
index a4843bca58c..4c04bb11351 100644
--- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr
+++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr
@@ -6,7 +6,7 @@ LL | fn plus_one(x: i32) -> i32 {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 LL |     x + 1;
-   |          - help: remove this semicolon
+   |          - help: remove this semicolon to return this value
 
 error[E0308]: mismatched types
   --> $DIR/coercion-missing-tail-expected-type.rs:8:13
@@ -16,7 +16,7 @@ LL | fn foo() -> Result<u8, u64> {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 LL |     Ok(1);
-   |          - help: remove this semicolon
+   |          - help: remove this semicolon to return this value
    |
    = note:   expected enum `Result<u8, u64>`
            found unit type `()`
diff --git a/src/test/ui/coherence/coherence-fn-implied-bounds.stderr b/src/test/ui/coherence/coherence-fn-implied-bounds.stderr
index 8612ce60d18..2018712043e 100644
--- a/src/test/ui/coherence/coherence-fn-implied-bounds.stderr
+++ b/src/test/ui/coherence/coherence-fn-implied-bounds.stderr
@@ -7,14 +7,14 @@ LL |
 LL | impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32`
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
+   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 note: the lint level is defined here
   --> $DIR/coherence-fn-implied-bounds.rs:15:9
    |
 LL | #![deny(coherence_leak_check)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-free-vs-bound-region.stderr b/src/test/ui/coherence/coherence-free-vs-bound-region.stderr
index af18655b06f..e2d84b83320 100644
--- a/src/test/ui/coherence/coherence-free-vs-bound-region.stderr
+++ b/src/test/ui/coherence/coherence-free-vs-bound-region.stderr
@@ -7,14 +7,14 @@ LL |
 LL | impl TheTrait for fn(&u8) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(&u8)`
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
+   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 note: the lint level is defined here
   --> $DIR/coherence-free-vs-bound-region.rs:10:9
    |
 LL | #![deny(coherence_leak_check)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
index 97f3c759355..7bd50649d6d 100644
--- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
+++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0391]: cycle detected when building specialization graph of trait `Trait`
   --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1
diff --git a/src/test/ui/coherence/coherence-subtyping.stderr b/src/test/ui/coherence/coherence-subtyping.stderr
index 25d8c875653..9d90019a50f 100644
--- a/src/test/ui/coherence/coherence-subtyping.stderr
+++ b/src/test/ui/coherence/coherence-subtyping.stderr
@@ -7,10 +7,10 @@ LL |
 LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
    |
-   = note: `#[warn(coherence_leak_check)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
+   = note: `#[warn(coherence_leak_check)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/coherence/coherence-wasm-bindgen.stderr b/src/test/ui/coherence/coherence-wasm-bindgen.stderr
index aa74e231539..cfcc21240e4 100644
--- a/src/test/ui/coherence/coherence-wasm-bindgen.stderr
+++ b/src/test/ui/coherence/coherence-wasm-bindgen.stderr
@@ -7,15 +7,15 @@ LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b)
 LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn std::ops::Fn(&_) -> _`
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
+   = note: downstream crates may implement trait `FromWasmAbi` for type `&_`
+   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 note: the lint level is defined here
   --> $DIR/coherence-wasm-bindgen.rs:10:9
    |
 LL | #![deny(coherence_leak_check)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
-   = note: downstream crates may implement trait `FromWasmAbi` for type `&_`
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/conflicting-repr-hints.stderr b/src/test/ui/conflicting-repr-hints.stderr
index 0c7c50d6730..4dcd8f4fc28 100644
--- a/src/test/ui/conflicting-repr-hints.stderr
+++ b/src/test/ui/conflicting-repr-hints.stderr
@@ -4,9 +4,9 @@ error[E0566]: conflicting representation hints
 LL | #[repr(C, u64)]
    |        ^  ^^^
    |
-   = note: `#[deny(conflicting_repr_hints)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
 
 error[E0566]: conflicting representation hints
   --> $DIR/conflicting-repr-hints.rs:19:8
diff --git a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
index 4cd86fecd7e..828f0988a03 100644
--- a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
@@ -22,9 +22,9 @@ warning: cannot use constants which depend on generic parameters in types
 LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(const_evaluatable_unchecked)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 warning: cannot use constants which depend on generic parameters in types
   --> $DIR/dependence_lint.rs:16:9
diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr
index b5719b3fe1d..8eb1fccc5f8 100644
--- a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr
@@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to
 LL | #![feature(generic_const_exprs)]
    |            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr
index 0d8463714e8..796dc01043c 100644
--- a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr
@@ -4,9 +4,9 @@ warning: cannot use constants which depend on generic parameters in types
 LL |     let _ = [0; foo::<T>()];
    |                 ^^^^^^^^^^
    |
-   = note: `#[warn(const_evaluatable_unchecked)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-102074.rs b/src/test/ui/const-generics/generic_const_exprs/issue-102074.rs
new file mode 100644
index 00000000000..66d15cf1215
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-102074.rs
@@ -0,0 +1,23 @@
+// check-pass
+// Checks that the NoopMethodCall lint doesn't call Instance::resolve on unresolved consts
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+#[derive(Debug, Clone)]
+pub struct Aes128CipherKey([u8; Aes128Cipher::KEY_LEN]);
+
+impl Aes128CipherKey {
+    pub fn new(key: &[u8; Aes128Cipher::KEY_LEN]) -> Self {
+        Self(key.clone())
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Aes128Cipher;
+
+impl Aes128Cipher {
+    const KEY_LEN: usize = 16;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr
index b5b2b0e405a..1cceaece715 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr
@@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use
 LL | #![feature(adt_const_params, generic_const_exprs)]
    |            ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/issue-97047-ice-1.rs:3:30
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr
index 5dfbd87ccd4..774e842bcbe 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr
@@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use
 LL | #![feature(adt_const_params, generic_const_exprs)]
    |            ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/issue-97047-ice-2.rs:3:30
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr
index 45c7d835f33..440cf457e19 100644
--- a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr
@@ -4,11 +4,6 @@ error: the trait `Foo` cannot be made into an object
 LL |     fn test(&self) where [u8; bar::<Self>()]: Sized;
    |        ^^^^
    |
-note: the lint level is defined here
-  --> $DIR/object-safety-err-where-bounds.rs:3:9
-   |
-LL | #![deny(where_clauses_object_safety)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
@@ -19,6 +14,11 @@ LL | trait Foo {
 LL |     fn test(&self) where [u8; bar::<Self>()]: Sized;
    |        ^^^^ ...because method `test` references the `Self` type in its `where` clause
    = help: consider moving `test` to another trait
+note: the lint level is defined here
+  --> $DIR/object-safety-err-where-bounds.rs:3:9
+   |
+LL | #![deny(where_clauses_object_safety)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/invariant.stderr b/src/test/ui/const-generics/invariant.stderr
index ce0fad10471..aabe4c93b36 100644
--- a/src/test/ui/const-generics/invariant.stderr
+++ b/src/test/ui/const-generics/invariant.stderr
@@ -7,10 +7,10 @@ LL | impl SadBee for for<'a> fn(&'a ()) {
 LL | impl SadBee for fn(&'static ()) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a ())`
    |
-   = note: `#[warn(coherence_leak_check)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
+   = note: `#[warn(coherence_leak_check)]` on by default
 
 error[E0308]: mismatched types
   --> $DIR/invariant.rs:27:5
diff --git a/src/test/ui/const-generics/issue-80471.stderr b/src/test/ui/const-generics/issue-80471.stderr
index dbcc0b7b600..b89706710bc 100644
--- a/src/test/ui/const-generics/issue-80471.stderr
+++ b/src/test/ui/const-generics/issue-80471.stderr
@@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use
 LL | #![feature(adt_const_params)]
    |            ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0741]: `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
   --> $DIR/issue-80471.rs:10:17
diff --git a/src/test/ui/const-generics/issues/issue-83466.stderr b/src/test/ui/const-generics/issues/issue-83466.stderr
index a60f71ea614..bcfd7063989 100644
--- a/src/test/ui/const-generics/issues/issue-83466.stderr
+++ b/src/test/ui/const-generics/issues/issue-83466.stderr
@@ -7,9 +7,9 @@ LL |     fn func<'a, U>(self) -> U {
 LL |     S.func::<'a, 10_u32>()
    |              ^^
    |
-   = note: `#[warn(late_bound_lifetime_arguments)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
+   = note: `#[warn(late_bound_lifetime_arguments)]` on by default
 
 error[E0747]: constant provided when a type was expected
   --> $DIR/issue-83466.rs:11:18
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
index bf0d0f352eb..0b051c6131b 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
@@ -67,9 +67,9 @@ warning: cannot use constants which depend on generic parameters in types
 LL |     let _ = [0; size_of::<*mut T>() + 1];
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(const_evaluatable_unchecked)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 error: aborting due to 7 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
index f9f6660f6b8..f0ba7a39d1e 100644
--- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
+++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
@@ -4,9 +4,9 @@ warning: cannot use constants which depend on generic parameters in types
 LL |     [0; std::mem::size_of::<*mut T>()];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(const_evaluatable_unchecked)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 warning: cannot use constants which depend on generic parameters in types
   --> $DIR/const-evaluatable-unchecked.rs:16:21
diff --git a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr
index f9b56bd387a..fe3f24a67a2 100644
--- a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr
+++ b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr
@@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to
 LL | #![feature(generic_const_exprs)]
    |            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const_prop/issue-102553.rs b/src/test/ui/const_prop/issue-102553.rs
new file mode 100644
index 00000000000..523a9d7ac72
--- /dev/null
+++ b/src/test/ui/const_prop/issue-102553.rs
@@ -0,0 +1,24 @@
+// compile-flags: --crate-type=lib
+// check-pass
+
+pub trait Widget<E> {
+    fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w>
+    where
+        Self: Sized + 'w;
+}
+
+pub trait WidgetDyn<E> {}
+
+impl<T, E> WidgetDyn<E> for T where T: Widget<E> {}
+
+impl<E> Widget<E> for dyn WidgetDyn<E> + '_ {
+    fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w>
+    where
+        Self: Sized + 'w,
+    {
+        // Even though this is illegal to const evaluate, this should never
+        // trigger an ICE because it can never be called from actual code
+        // (due to the trivially false where-clause predicate).
+        Box::new(self)
+    }
+}
diff --git a/src/test/ui/consts/assert-type-intrinsics.rs b/src/test/ui/consts/assert-type-intrinsics.rs
index 3ce3e1bdbac..6b5612dda90 100644
--- a/src/test/ui/consts/assert-type-intrinsics.rs
+++ b/src/test/ui/consts/assert-type-intrinsics.rs
@@ -11,12 +11,15 @@ fn main() {
     use std::mem::MaybeUninit;
 
     const _BAD1: () = unsafe {
-        MaybeUninit::<!>::uninit().assume_init();
+        intrinsics::assert_inhabited::<!>(); //~ERROR: any use of this value will cause an error
+        //~^WARN: previously accepted
     };
     const _BAD2: () = {
-        intrinsics::assert_uninit_valid::<bool>();
+        intrinsics::assert_uninit_valid::<!>(); //~ERROR: any use of this value will cause an error
+        //~^WARN: previously accepted
     };
     const _BAD3: () = {
-        intrinsics::assert_zero_valid::<&'static i32>();
+        intrinsics::assert_zero_valid::<&'static i32>(); //~ERROR: any use of this value will cause an error
+        //~^WARN: previously accepted
     };
 }
diff --git a/src/test/ui/consts/assert-type-intrinsics.stderr b/src/test/ui/consts/assert-type-intrinsics.stderr
index 6eab10197b8..9f97d836705 100644
--- a/src/test/ui/consts/assert-type-intrinsics.stderr
+++ b/src/test/ui/consts/assert-type-intrinsics.stderr
@@ -3,26 +3,26 @@ error: any use of this value will cause an error
    |
 LL |     const _BAD1: () = unsafe {
    |     ---------------
-LL |         MaybeUninit::<!>::uninit().assume_init();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
+LL |         intrinsics::assert_inhabited::<!>();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
-  --> $DIR/assert-type-intrinsics.rs:17:9
+  --> $DIR/assert-type-intrinsics.rs:18:9
    |
 LL |     const _BAD2: () = {
    |     ---------------
-LL |         intrinsics::assert_uninit_valid::<bool>();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
+LL |         intrinsics::assert_uninit_valid::<!>();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: any use of this value will cause an error
-  --> $DIR/assert-type-intrinsics.rs:20:9
+  --> $DIR/assert-type-intrinsics.rs:22:9
    |
 LL |     const _BAD3: () = {
    |     ---------------
@@ -40,36 +40,36 @@ error: any use of this value will cause an error
    |
 LL |     const _BAD1: () = unsafe {
    |     ---------------
-LL |         MaybeUninit::<!>::uninit().assume_init();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
+LL |         intrinsics::assert_inhabited::<!>();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
-  --> $DIR/assert-type-intrinsics.rs:17:9
+  --> $DIR/assert-type-intrinsics.rs:18:9
    |
 LL |     const _BAD2: () = {
    |     ---------------
-LL |         intrinsics::assert_uninit_valid::<bool>();
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
+LL |         intrinsics::assert_uninit_valid::<!>();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
-  --> $DIR/assert-type-intrinsics.rs:20:9
+  --> $DIR/assert-type-intrinsics.rs:22:9
    |
 LL |     const _BAD3: () = {
    |     ---------------
 LL |         intrinsics::assert_zero_valid::<&'static i32>();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/assoc_const_generic_impl.stderr b/src/test/ui/consts/assoc_const_generic_impl.stderr
index 17cbaef1f06..ca6db350c75 100644
--- a/src/test/ui/consts/assoc_const_generic_impl.stderr
+++ b/src/test/ui/consts/assoc_const_generic_impl.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL |     const I_AM_ZERO_SIZED: ()  = [()][std::mem::size_of::<Self>()];
    |     -------------------------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/assoc_const_generic_impl.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: erroneous constant encountered
   --> $DIR/assoc_const_generic_impl.rs:14:18
@@ -27,11 +27,11 @@ warning: any use of this value will cause an error
 LL |     const I_AM_ZERO_SIZED: ()  = [()][std::mem::size_of::<Self>()];
    |     -------------------------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/assoc_const_generic_impl.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-err-early.stderr b/src/test/ui/consts/const-err-early.stderr
index 1b94aa080dd..fce8f051061 100644
--- a/src/test/ui/consts/const-err-early.stderr
+++ b/src/test/ui/consts/const-err-early.stderr
@@ -4,13 +4,13 @@ error: any use of this value will cause an error
 LL | pub const A: i8 = -i8::MIN;
    | ---------------   ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-early.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: any use of this value will cause an error
   --> $DIR/const-err-early.rs:5:19
@@ -57,13 +57,13 @@ error: any use of this value will cause an error
 LL | pub const A: i8 = -i8::MIN;
    | ---------------   ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-early.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -72,13 +72,13 @@ error: any use of this value will cause an error
 LL | pub const B: u8 = 200u8 + 200u8;
    | ---------------   ^^^^^^^^^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-early.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -87,13 +87,13 @@ error: any use of this value will cause an error
 LL | pub const C: u8 = 200u8 * 4;
    | ---------------   ^^^^^^^^^ attempt to compute `200_u8 * 4_u8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-early.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -102,13 +102,13 @@ error: any use of this value will cause an error
 LL | pub const D: u8 = 42u8 - (42u8 + 1);
    | ---------------   ^^^^^^^^^^^^^^^^^ attempt to compute `42_u8 - 43_u8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-early.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -117,11 +117,11 @@ error: any use of this value will cause an error
 LL | pub const E: u8 = [5u8][1];
    | ---------------   ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-early.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr
index f179843654e..16b912695a6 100644
--- a/src/test/ui/consts/const-err-multi.stderr
+++ b/src/test/ui/consts/const-err-multi.stderr
@@ -4,13 +4,13 @@ error: any use of this value will cause an error
 LL | pub const A: i8 = -i8::MIN;
    | ---------------   ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-multi.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: any use of this value will cause an error
   --> $DIR/const-err-multi.rs:6:19
@@ -48,13 +48,13 @@ error: any use of this value will cause an error
 LL | pub const A: i8 = -i8::MIN;
    | ---------------   ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-multi.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -63,13 +63,13 @@ error: any use of this value will cause an error
 LL | pub const B: i8 = A;
    | ---------------   ^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-multi.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -78,13 +78,13 @@ error: any use of this value will cause an error
 LL | pub const C: u8 = A as u8;
    | ---------------   ^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-multi.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -93,11 +93,11 @@ error: any use of this value will cause an error
 LL | pub const D: i8 = 50 - A;
    | ---------------        ^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err-multi.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-err.stderr b/src/test/ui/consts/const-err.stderr
index e3b0d29c853..f83a2cbb190 100644
--- a/src/test/ui/consts/const-err.stderr
+++ b/src/test/ui/consts/const-err.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL | const FOO: u8 = [5u8][1];
    | -------------   ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err.rs:5:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error[E0080]: erroneous constant used
   --> $DIR/const-err.rs:16:16
@@ -34,11 +34,11 @@ warning: any use of this value will cause an error
 LL | const FOO: u8 = [5u8][1];
    | -------------   ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-err.rs:5:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr
index 2953406ee40..84061e52d31 100644
--- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr
+++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    | --------------    ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/conditional_array_execution.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/conditional_array_execution.rs:12:20
@@ -38,13 +38,13 @@ warning: any use of this value will cause an error
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    | --------------    ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/conditional_array_execution.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: erroneous constant used
@@ -53,12 +53,12 @@ warning: erroneous constant used
 LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/conditional_array_execution.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr
index cf50c19caa7..b6d0898bb92 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr
@@ -19,11 +19,11 @@ warning: any use of this value will cause an error
 LL | const NEG_NEG_128: i8 = -NEG_128;
    | ---------------------   ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow-2.rs:4:36
    |
 LL | #![allow(unused_imports, warnings, const_err)]
    |                                    ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr
index dab9a76c7d4..8e3028c50f3 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr
@@ -7,13 +7,13 @@ LL |     (
 LL |      i8::MIN - 1,
    |      ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: any use of this value will cause an error
   --> $DIR/const-eval-overflow2.rs:21:6
@@ -109,13 +109,13 @@ LL |     (
 LL |      i8::MIN - 1,
    |      ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -127,13 +127,13 @@ LL |     (
 LL |      i16::MIN - 1,
    |      ^^^^^^^^^^^^ attempt to compute `i16::MIN - 1_i16`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -145,13 +145,13 @@ LL |     (
 LL |      i32::MIN - 1,
    |      ^^^^^^^^^^^^ attempt to compute `i32::MIN - 1_i32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -163,13 +163,13 @@ LL |     (
 LL |      i64::MIN - 1,
    |      ^^^^^^^^^^^^ attempt to compute `i64::MIN - 1_i64`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -181,13 +181,13 @@ LL |     (
 LL |      u8::MIN - 1,
    |      ^^^^^^^^^^^ attempt to compute `0_u8 - 1_u8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -198,13 +198,13 @@ LL | const VALS_U16: (u16,) = (
 LL |      u16::MIN - 1,
    |      ^^^^^^^^^^^^ attempt to compute `0_u16 - 1_u16`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -215,13 +215,13 @@ LL | const VALS_U32: (u32,) = (
 LL |      u32::MIN - 1,
    |      ^^^^^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -233,11 +233,11 @@ LL |     (
 LL |      u64::MIN - 1,
    |      ^^^^^^^^^^^^ attempt to compute `0_u64 - 1_u64`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr
index 5fe9917437e..b6dc85f416b 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr
@@ -7,13 +7,13 @@ LL |     (
 LL |      i8::MAX + 1,
    |      ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: any use of this value will cause an error
   --> $DIR/const-eval-overflow2b.rs:21:6
@@ -109,13 +109,13 @@ LL |     (
 LL |      i8::MAX + 1,
    |      ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -127,13 +127,13 @@ LL |     (
 LL |      i16::MAX + 1,
    |      ^^^^^^^^^^^^ attempt to compute `i16::MAX + 1_i16`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -145,13 +145,13 @@ LL |     (
 LL |      i32::MAX + 1,
    |      ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -163,13 +163,13 @@ LL |     (
 LL |      i64::MAX + 1,
    |      ^^^^^^^^^^^^ attempt to compute `i64::MAX + 1_i64`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -181,13 +181,13 @@ LL |     (
 LL |      u8::MAX + 1,
    |      ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -198,13 +198,13 @@ LL | const VALS_U16: (u16,) = (
 LL |      u16::MAX + 1,
    |      ^^^^^^^^^^^^ attempt to compute `u16::MAX + 1_u16`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -215,13 +215,13 @@ LL | const VALS_U32: (u32,) = (
 LL |      u32::MAX + 1,
    |      ^^^^^^^^^^^^ attempt to compute `u32::MAX + 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -233,11 +233,11 @@ LL |     (
 LL |      u64::MAX + 1,
    |      ^^^^^^^^^^^^ attempt to compute `u64::MAX + 1_u64`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2b.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr
index d5f3a0fb1c3..df66fe1e5de 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr
@@ -7,13 +7,13 @@ LL |     (
 LL |      i8::MIN * 2,
    |      ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: any use of this value will cause an error
   --> $DIR/const-eval-overflow2c.rs:21:6
@@ -109,13 +109,13 @@ LL |     (
 LL |      i8::MIN * 2,
    |      ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -127,13 +127,13 @@ LL |     (
 LL |      i16::MIN * 2,
    |      ^^^^^^^^^^^^ attempt to compute `i16::MIN * 2_i16`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -145,13 +145,13 @@ LL |     (
 LL |      i32::MIN * 2,
    |      ^^^^^^^^^^^^ attempt to compute `i32::MIN * 2_i32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -163,13 +163,13 @@ LL |     (
 LL |      i64::MIN * 2,
    |      ^^^^^^^^^^^^ attempt to compute `i64::MIN * 2_i64`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -181,13 +181,13 @@ LL |     (
 LL |      u8::MAX * 2,
    |      ^^^^^^^^^^^ attempt to compute `u8::MAX * 2_u8`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -198,13 +198,13 @@ LL | const VALS_U16: (u16,) = (
 LL |      u16::MAX * 2,
    |      ^^^^^^^^^^^^ attempt to compute `u16::MAX * 2_u16`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -215,13 +215,13 @@ LL | const VALS_U32: (u32,) = (
 LL |      u32::MAX * 2,
    |      ^^^^^^^^^^^^ attempt to compute `u32::MAX * 2_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -233,11 +233,11 @@ LL |     (
 LL |      u64::MAX * 2,
    |      ^^^^^^^^^^^^ attempt to compute `u64::MAX * 2_u64`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-overflow2c.rs:8:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr
index 0ae7bfa86bc..67d290bbcaa 100644
--- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL | const X: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-query-stack.rs:18:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/const-eval-query-stack.rs:23:28
@@ -24,9 +24,9 @@ error: erroneous constant used
 LL |     let x: &'static i32 = &X;
    |                           ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 query stack during panic:
 #0 [mir_drops_elaborated_and_const_checked] elaborating drops for `main`
@@ -40,13 +40,13 @@ warning: any use of this value will cause an error
 LL | const X: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const-eval-query-stack.rs:18:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 error: erroneous constant used
@@ -55,7 +55,7 @@ error: erroneous constant used
 LL |     let x: &'static i32 = &X;
    |                           ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
index 12d5b7bd6bb..de717899dd8 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
@@ -4,11 +4,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
    |     --------------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:30:43
@@ -318,11 +318,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
    |     --------------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -331,11 +331,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
    |     --------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -344,11 +344,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -357,11 +357,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -370,11 +370,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -383,11 +383,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
    |     --------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -396,11 +396,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -409,11 +409,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -422,11 +422,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -435,11 +435,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -448,11 +448,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
    |     ----------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -461,11 +461,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
    |     ------------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -474,11 +474,11 @@ error: any use of this value will cause an error
 LL |     const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
    |     ------------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -487,11 +487,11 @@ error: any use of this value will cause an error
 LL |     const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
    |     ----------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -500,11 +500,11 @@ error: any use of this value will cause an error
 LL |     const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -513,11 +513,11 @@ error: any use of this value will cause an error
 LL |     const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -526,11 +526,11 @@ error: any use of this value will cause an error
 LL |     const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -539,11 +539,11 @@ error: any use of this value will cause an error
 LL |     const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
    |     --------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -552,11 +552,11 @@ error: any use of this value will cause an error
 LL |     const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
    |     ----------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -565,11 +565,11 @@ error: any use of this value will cause an error
 LL |     const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -578,11 +578,11 @@ error: any use of this value will cause an error
 LL |     const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -591,11 +591,11 @@ error: any use of this value will cause an error
 LL |     const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -604,11 +604,11 @@ error: any use of this value will cause an error
 LL |     const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
    |     --------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -617,11 +617,11 @@ error: any use of this value will cause an error
 LL |     const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -630,11 +630,11 @@ error: any use of this value will cause an error
 LL |     const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
    |     ------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -643,11 +643,11 @@ error: any use of this value will cause an error
 LL |     const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
    |     --------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -656,9 +656,9 @@ error: any use of this value will cause an error
 LL |     const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
    |     --------------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
index f6ffa1ef296..6aacc6cffc9 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -35,13 +35,13 @@ LL |     x(y)
 LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
    | --------------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_fn_ptr_fail2.rs:4:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -57,13 +57,13 @@ LL |     x(y)
 LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
    | --------------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_fn_ptr_fail2.rs:4:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: erroneous constant used
@@ -72,13 +72,13 @@ warning: erroneous constant used
 LL |     assert_eq!(Y, 4);
    |     ^^^^^^^^^^^^^^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_fn_ptr_fail2.rs:4:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -88,12 +88,12 @@ warning: erroneous constant used
 LL |     assert_eq!(Z, 4);
    |     ^^^^^^^^^^^^^^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_fn_ptr_fail2.rs:4:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr
index f06dedc2298..3553a18d388 100644
--- a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr
+++ b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr
@@ -4,9 +4,9 @@ warning: panic message is not a string literal
 LL |     panic!({ "foo" });
    |            ^^^^^^^^^
    |
-   = note: `#[warn(non_fmt_panics)]` on by default
    = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+   = note: `#[warn(non_fmt_panics)]` on by default
 help: add a "{}" format string to `Display` the message
    |
 LL |     panic!("{}", { "foo" });
diff --git a/src/test/ui/consts/const-eval/erroneous-const.stderr b/src/test/ui/consts/const-eval/erroneous-const.stderr
index adfb4cc61cc..24428732a42 100644
--- a/src/test/ui/consts/const-eval/erroneous-const.stderr
+++ b/src/test/ui/consts/const-eval/erroneous-const.stderr
@@ -16,13 +16,13 @@ warning: any use of this value will cause an error
 LL |     const VOID: () = [()][2];
    |     --------------   ^^^^^^^ index out of bounds: the length is 1 but the index is 2
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/erroneous-const.rs:2:9
    |
 LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/erroneous-const.rs:15:17
@@ -46,11 +46,11 @@ warning: any use of this value will cause an error
 LL |     const VOID: () = [()][2];
    |     --------------   ^^^^^^^ index out of bounds: the length is 1 but the index is 2
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/erroneous-const.rs:2:9
    |
 LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/erroneous-const2.stderr b/src/test/ui/consts/const-eval/erroneous-const2.stderr
index e947d93e405..0eea5648a64 100644
--- a/src/test/ui/consts/const-eval/erroneous-const2.stderr
+++ b/src/test/ui/consts/const-eval/erroneous-const2.stderr
@@ -16,13 +16,13 @@ warning: any use of this value will cause an error
 LL |     const VOID: () = [()][2];
    |     --------------   ^^^^^^^ index out of bounds: the length is 1 but the index is 2
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/erroneous-const2.rs:2:9
    |
 LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/erroneous-const2.rs:15:17
@@ -40,11 +40,11 @@ warning: any use of this value will cause an error
 LL |     const VOID: () = [()][2];
    |     --------------   ^^^^^^^ index out of bounds: the length is 1 but the index is 2
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/erroneous-const2.rs:2:9
    |
 LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr
index a476b0f587f..f3f6f2bb028 100644
--- a/src/test/ui/consts/const-eval/format.stderr
+++ b/src/test/ui/consts/const-eval/format.stderr
@@ -40,9 +40,9 @@ error: erroneous constant used
 LL |     panic!("{:?}", 0);
    |            ^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: erroneous constant used
   --> $DIR/format.rs:2:20
@@ -83,9 +83,9 @@ error: erroneous constant used
 LL |     panic!("{:?}", 0);
    |            ^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: erroneous constant used
@@ -94,9 +94,9 @@ error: erroneous constant used
 LL |     panic!("{:?}", 0);
    |                    ^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -106,9 +106,9 @@ error: erroneous constant used
 LL |     println!("{:?}", 0);
    |              ^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: erroneous constant used
@@ -117,8 +117,8 @@ error: erroneous constant used
 LL |     println!("{:?}", 0);
    |                      ^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
index da4a21e08ab..3f4739c56f0 100644
--- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
+++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL |     const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
    |     -------------                                           ^^^^^ index out of bounds: the length is 0 but the index is 0
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/index-out-of-bounds-never-type.rs:4:9
    |
 LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: erroneous constant encountered
   --> $DIR/index-out-of-bounds-never-type.rs:17:13
@@ -27,11 +27,11 @@ warning: any use of this value will cause an error
 LL |     const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
    |     -------------                                           ^^^^^ index out of bounds: the length is 0 but the index is 0
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/index-out-of-bounds-never-type.rs:4:9
    |
 LL | #![warn(const_err, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr
index 3f67c38f82e..ceeaa1baece 100644
--- a/src/test/ui/consts/const-eval/issue-43197.stderr
+++ b/src/test/ui/consts/const-eval/issue-43197.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL |     const X: u32 = 0 - 1;
    |     ------------   ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-43197.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 warning: any use of this value will cause an error
   --> $DIR/issue-43197.rs:13:24
@@ -63,13 +63,13 @@ warning: any use of this value will cause an error
 LL |     const X: u32 = 0 - 1;
    |     ------------   ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-43197.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -78,13 +78,13 @@ warning: any use of this value will cause an error
 LL |     const Y: u32 = foo(0 - 1);
    |     ------------       ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-43197.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: erroneous constant used
@@ -93,13 +93,13 @@ warning: erroneous constant used
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-43197.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -109,12 +109,12 @@ warning: erroneous constant used
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-43197.rs:3:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr
index 4c27ceea19b..c3a794d2fe3 100644
--- a/src/test/ui/consts/const-eval/issue-44578.stderr
+++ b/src/test/ui/consts/const-eval/issue-44578.stderr
@@ -14,13 +14,13 @@ warning: any use of this value will cause an error
 LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
    |     ----------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-44578.rs:3:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: erroneous constant used
@@ -29,12 +29,12 @@ warning: erroneous constant used
 LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/issue-44578.rs:3:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr
index cc19caca724..bd860197720 100644
--- a/src/test/ui/consts/const-eval/issue-50814-2.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL |     const BAR: usize = [5, 6, 7][T::BOO];
    |     ----------------   ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error[E0080]: evaluation of `foo::<()>` failed
   --> $DIR/issue-50814-2.rs:19:6
@@ -30,7 +30,7 @@ error: any use of this value will cause an error
 LL |     const BAR: usize = [5, 6, 7][T::BOO];
    |     ----------------   ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr
index 6ceef91a042..c8e5a169ff9 100644
--- a/src/test/ui/consts/const-eval/issue-50814.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL |     const MAX: u8 = A::MAX + B::MAX;
    |     -------------   ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error[E0080]: evaluation of `foo::<i32>` failed
   --> $DIR/issue-50814.rs:21:6
@@ -30,7 +30,7 @@ error: any use of this value will cause an error
 LL |     const MAX: u8 = A::MAX + B::MAX;
    |     -------------   ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr
index 75e50a27b3a..f41fa1c1ee0 100644
--- a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr
+++ b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr
@@ -7,11 +7,11 @@ LL | const PARTIAL_OVERWRITE: () = {
 LL |         *(ptr as *mut u8) = 123;
    |         ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -25,9 +25,9 @@ LL | const PARTIAL_OVERWRITE: () = {
 LL |         *(ptr as *mut u8) = 123;
    |         ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
index cfca8ef0746..d5f73dcd11f 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr
@@ -53,13 +53,13 @@ LL |     0 - 1
 LL | const X: () = {
    | -----------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 warning: any use of this value will cause an error
   --> $DIR/promoted_errors.rs:43:28
@@ -88,13 +88,13 @@ LL |     0 - 1
 LL | const X: () = {
    | -----------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -105,11 +105,11 @@ LL | const X: () = {
 LL |     let _x: &'static u32 = &overflow();
    |                            ^^^^^^^^^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
index 984484a850f..42310327692 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr
@@ -53,13 +53,13 @@ LL |     1 / 0
 LL | const X: () = {
    | -----------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 warning: any use of this value will cause an error
   --> $DIR/promoted_errors.rs:46:28
@@ -89,13 +89,13 @@ LL |     1 / 0
 LL | const X: () = {
    | -----------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -107,11 +107,11 @@ LL | const X: () = {
 LL |     let _x: &'static i32 = &div_by_zero1();
    |                            ^^^^^^^^^^^^^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
index cfca8ef0746..d5f73dcd11f 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
@@ -53,13 +53,13 @@ LL |     0 - 1
 LL | const X: () = {
    | -----------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 warning: any use of this value will cause an error
   --> $DIR/promoted_errors.rs:43:28
@@ -88,13 +88,13 @@ LL |     0 - 1
 LL | const X: () = {
    | -----------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -105,11 +105,11 @@ LL | const X: () = {
 LL |     let _x: &'static u32 = &overflow();
    |                            ^^^^^^^^^^^ referenced constant has errors
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/promoted_errors.rs:11:9
    |
 LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/pub_const_err.stderr b/src/test/ui/consts/const-eval/pub_const_err.stderr
index 36197a7ab59..d1081f9c2ca 100644
--- a/src/test/ui/consts/const-eval/pub_const_err.stderr
+++ b/src/test/ui/consts/const-eval/pub_const_err.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL | pub const Z: u32 = 0 - 1;
    | ----------------   ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/pub_const_err.rs:2:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 warning: 1 warning emitted
 
@@ -21,11 +21,11 @@ warning: any use of this value will cause an error
 LL | pub const Z: u32 = 0 - 1;
    | ----------------   ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/pub_const_err.rs:2:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr
index 2eef3b8f5c4..93362a9375c 100644
--- a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr
+++ b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr
@@ -4,13 +4,13 @@ warning: any use of this value will cause an error
 LL | pub const Z: u32 = 0 - 1;
    | ----------------   ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/pub_const_err_bin.rs:2:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 warning: 1 warning emitted
 
@@ -21,11 +21,11 @@ warning: any use of this value will cause an error
 LL | pub const Z: u32 = 0 - 1;
    | ----------------   ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/pub_const_err_bin.rs:2:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
index 30935e41549..02feb6a7832 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr
@@ -4,11 +4,11 @@ error: any use of this value will cause an error
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    | --------------            ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: could not evaluate constant pattern
   --> $DIR/ref_to_int_match.rs:7:14
@@ -31,9 +31,9 @@ error: any use of this value will cause an error
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    | --------------            ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
index 30935e41549..02feb6a7832 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr
@@ -4,11 +4,11 @@ error: any use of this value will cause an error
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    | --------------            ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: could not evaluate constant pattern
   --> $DIR/ref_to_int_match.rs:7:14
@@ -31,9 +31,9 @@ error: any use of this value will cause an error
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    | --------------            ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
index 80395e32db0..ddfe1d5909f 100644
--- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
@@ -15,11 +15,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ub-enum.rs:31:1
@@ -137,11 +137,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -150,11 +150,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -163,11 +163,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -176,11 +176,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -189,9 +189,9 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
index d20f63a7289..930f8130bc3 100644
--- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
@@ -15,11 +15,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ub-enum.rs:31:1
@@ -137,11 +137,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -150,11 +150,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -163,11 +163,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -176,11 +176,11 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -189,9 +189,9 @@ error: any use of this value will cause an error
 LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
index 3e93219c86d..66b993764e9 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
@@ -48,11 +48,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ub-ref-ptr.rs:35:39
@@ -171,11 +171,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -184,11 +184,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    | ----------------------------------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -197,9 +197,9 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    | ----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -208,11 +208,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
    | ------------------------------------------                                           ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -221,7 +221,7 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
    | ------------------------------------------                                          ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
index bc2aa12a2f3..cbf120a397e 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
@@ -48,11 +48,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ub-ref-ptr.rs:35:39
@@ -171,11 +171,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -184,11 +184,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    | ----------------------------------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -197,9 +197,9 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    | ----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -208,11 +208,11 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
    | ------------------------------------------                                           ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -221,7 +221,7 @@ error: any use of this value will cause an error
 LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
    | ------------------------------------------                                          ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index 4cd974e7bf9..2d4218a94f5 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -26,11 +26,11 @@ error: any use of this value will cause an error
 LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ub-wide-ptr.rs:46:1
@@ -320,11 +320,11 @@ error: any use of this value will cause an error
 LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -333,11 +333,11 @@ error: any use of this value will cause an error
 LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -346,11 +346,11 @@ error: any use of this value will cause an error
 LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -359,11 +359,11 @@ error: any use of this value will cause an error
 LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -372,9 +372,9 @@ error: any use of this value will cause an error
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
    | ------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -383,9 +383,9 @@ error: any use of this value will cause an error
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
    | --------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -394,7 +394,7 @@ error: any use of this value will cause an error
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
    | --------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index 1d84b7bce14..9997b8fe5f2 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -26,11 +26,11 @@ error: any use of this value will cause an error
 LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ub-wide-ptr.rs:46:1
@@ -320,11 +320,11 @@ error: any use of this value will cause an error
 LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -333,11 +333,11 @@ error: any use of this value will cause an error
 LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -346,11 +346,11 @@ error: any use of this value will cause an error
 LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -359,11 +359,11 @@ error: any use of this value will cause an error
 LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -372,9 +372,9 @@ error: any use of this value will cause an error
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
    | ------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -383,9 +383,9 @@ error: any use of this value will cause an error
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
    | --------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -394,7 +394,7 @@ error: any use of this value will cause an error
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
    | --------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/unused-broken-const.stderr b/src/test/ui/consts/const-eval/unused-broken-const.stderr
index df5bd524f27..cdc1e9d97f4 100644
--- a/src/test/ui/consts/const-eval/unused-broken-const.stderr
+++ b/src/test/ui/consts/const-eval/unused-broken-const.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const FOO: i32 = [][0];
    | --------------   ^^^^^ index out of bounds: the length is 0 but the index is 0
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -17,7 +17,7 @@ error: any use of this value will cause an error
 LL | const FOO: i32 = [][0];
    | --------------   ^^^^^ index out of bounds: the length is 0 but the index is 0
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
index b568518b449..dd948f9adb3 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
@@ -7,8 +7,8 @@ LL |     unsafe { std::mem::transmute(()) }
    |              this code causes undefined behavior when executed
    |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
-   = note: `#[warn(invalid_value)]` on by default
    = note: the `!` type has no valid value
+   = note: `#[warn(invalid_value)]` on by default
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/validate_uninhabited_zsts.rs:4:14
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
index b568518b449..dd948f9adb3 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
@@ -7,8 +7,8 @@ LL |     unsafe { std::mem::transmute(()) }
    |              this code causes undefined behavior when executed
    |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
-   = note: `#[warn(invalid_value)]` on by default
    = note: the `!` type has no valid value
+   = note: `#[warn(invalid_value)]` on by default
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/validate_uninhabited_zsts.rs:4:14
diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr
index 205ee92dfd7..b57615e9a7c 100644
--- a/src/test/ui/consts/const-external-macro-const-err.stderr
+++ b/src/test/ui/consts/const-external-macro-const-err.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL |     static_assert!(2 + 2 == 5);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
@@ -18,8 +18,8 @@ error: any use of this value will cause an error
 LL |     static_assert!(2 + 2 == 5);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr
index 01f2f489564..908fef7265d 100644
--- a/src/test/ui/consts/const-float-bits-reject-conv.stderr
+++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr
@@ -45,9 +45,9 @@ LL |             const _: () = assert!($a);
 LL |     const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
    |                                  ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/const-float-bits-reject-conv.rs:33:34
@@ -184,9 +184,9 @@ LL |             const _: () = assert!($a);
 LL |     const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
    |                                  ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -198,9 +198,9 @@ LL |             const _: () = assert!($a);
 LL |     const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
    |                                  ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -212,9 +212,9 @@ LL |             const _: () = assert!($a == $b);
 LL |         const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
    |                                      ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -226,9 +226,9 @@ LL |             const _: () = assert!($a == $b);
 LL |         const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
    |                                      ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -240,9 +240,9 @@ LL |             const _: () = assert!($a);
 LL |     const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
    |                                  ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -254,9 +254,9 @@ LL |             const _: () = assert!($a);
 LL |     const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
    |                                  ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -268,9 +268,9 @@ LL |             const _: () = assert!($a == $b);
 LL |         const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
    |                                      ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -282,7 +282,7 @@ LL |             const _: () = assert!($a == $b);
 LL |         const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
    |                                      ^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-fn-error.stderr b/src/test/ui/consts/const-fn-error.stderr
index e36324f0b3e..02960b363e7 100644
--- a/src/test/ui/consts/const-fn-error.stderr
+++ b/src/test/ui/consts/const-fn-error.stderr
@@ -22,8 +22,8 @@ LL |     for i in 0..x {
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
-LL | impl<I: ~const Iterator> const IntoIterator for I {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<I: Iterator> const IntoIterator for I {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error[E0658]: mutable references are not allowed in constant functions
diff --git a/src/test/ui/consts/const-for.stderr b/src/test/ui/consts/const-for.stderr
index f2e1c8a4991..11e4ae309c0 100644
--- a/src/test/ui/consts/const-for.stderr
+++ b/src/test/ui/consts/const-for.stderr
@@ -7,8 +7,8 @@ LL |     for _ in 0..5 {}
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
-LL | impl<I: ~const Iterator> const IntoIterator for I {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<I: Iterator> const IntoIterator for I {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr
index d1bf4b92e6a..56645980b05 100644
--- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr
+++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const LEN: usize = ONE - TWO;
    | ----------------   ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/const-len-underflow-separate-spans.rs:12:17
@@ -24,7 +24,7 @@ error: any use of this value will cause an error
 LL | const LEN: usize = ONE - TWO;
    | ----------------   ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-prop-read-static-in-const.stderr b/src/test/ui/consts/const-prop-read-static-in-const.stderr
index ea5ad24b0b1..38941331003 100644
--- a/src/test/ui/consts/const-prop-read-static-in-const.stderr
+++ b/src/test/ui/consts/const-prop-read-static-in-const.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const TEST: u8 = MY_STATIC;
    | --------------   ^^^^^^^^^ constant accesses static
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 warning: skipping const checks
    |
@@ -25,7 +25,7 @@ error: any use of this value will cause an error
 LL | const TEST: u8 = MY_STATIC;
    | --------------   ^^^^^^^^^ constant accesses static
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
index d19a89378ec..0ed09ff8341 100644
--- a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
+++ b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
    | ------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/const-size_of_val-align_of_val-extern-type.rs:13:32
@@ -26,9 +26,9 @@ error: any use of this value will cause an error
 LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
    | ------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -37,7 +37,7 @@ error: any use of this value will cause an error
 LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) };
    | -------------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const-slice-oob.stderr b/src/test/ui/consts/const-slice-oob.stderr
index 27c21e7af14..16756454974 100644
--- a/src/test/ui/consts/const-slice-oob.stderr
+++ b/src/test/ui/consts/const-slice-oob.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const BAR: u32 = FOO[5];
    | --------------   ^^^^^^ index out of bounds: the length is 3 but the index is 5
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -17,7 +17,7 @@ error: any use of this value will cause an error
 LL | const BAR: u32 = FOO[5];
    | --------------   ^^^^^^ index out of bounds: the length is 3 but the index is 5
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr
index e51d6f91649..22348272275 100644
--- a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr
+++ b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr
@@ -4,9 +4,9 @@ warning: to use a constant of type `CustomEq` in a pattern, the constant's initi
 LL |         BAR_BAZ => panic!(),
    |         ^^^^^^^
    |
-   = note: `#[warn(nontrivial_structural_match)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
+   = note: `#[warn(nontrivial_structural_match)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr b/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr
index 0ff70837138..ddc576ced8f 100644
--- a/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr
+++ b/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr
@@ -4,9 +4,9 @@ warning: to use a constant of type `E` in a pattern, `E` must be annotated with
 LL |         E_SL => {}
    |         ^^^^
    |
-   = note: `#[warn(indirect_structural_match)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: `#[warn(indirect_structural_match)]` on by default
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
   --> $DIR/incomplete-slice.rs:9:11
diff --git a/src/test/ui/consts/const_in_pattern/issue-44333.stderr b/src/test/ui/consts/const_in_pattern/issue-44333.stderr
index 8302b09e533..731ef509cca 100644
--- a/src/test/ui/consts/const_in_pattern/issue-44333.stderr
+++ b/src/test/ui/consts/const_in_pattern/issue-44333.stderr
@@ -4,13 +4,13 @@ warning: function pointers and unsized pointers in patterns behave unpredictably
 LL |         FOO => println!("foo"),
    |         ^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
 note: the lint level is defined here
   --> $DIR/issue-44333.rs:3:9
    |
 LL | #![warn(pointer_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
 
 warning: function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/issue-44333.rs:21:9
diff --git a/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr b/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr
index 56405a55d69..66019834997 100644
--- a/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr
+++ b/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr
@@ -64,13 +64,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a
 LL |     match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
    |                             ^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 note: the lint level is defined here
   --> $DIR/reject_non_structural.rs:12:9
    |
 LL | #![warn(indirect_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 error: aborting due to 10 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr b/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr
index a24c8d18184..e957a43a13d 100644
--- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr
+++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr
@@ -4,9 +4,9 @@ warning: to use a constant of type `NoDerive` in a pattern, the constant's initi
 LL |     match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
    |                                               ^^^^^
    |
-   = note: `#[warn(nontrivial_structural_match)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
+   = note: `#[warn(nontrivial_structural_match)]` on by default
 
 warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/warn_corner_cases.rs:32:47
diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
index e450f4aa3bd..0f7d93a3be3 100644
--- a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
+++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr
@@ -7,9 +7,9 @@ LL |     let mut x = 0;
 LL |     while x != 1000 {
    |           ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -23,7 +23,7 @@ LL |     let mut x = 0;
 LL |     while x != 1000 {
    |           ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/constifconst-call-in-const-position.rs b/src/test/ui/consts/constifconst-call-in-const-position.rs
new file mode 100644
index 00000000000..fcf01d5bc71
--- /dev/null
+++ b/src/test/ui/consts/constifconst-call-in-const-position.rs
@@ -0,0 +1,22 @@
+// known-bug: #102498
+
+#![feature(const_trait_impl, generic_const_exprs)]
+
+#[const_trait]
+pub trait Tr {
+    fn a() -> usize;
+}
+
+impl Tr for () {
+    fn a() -> usize {
+        1
+    }
+}
+
+const fn foo<T: ~const Tr>() -> [u8; T::a()] {
+    [0; T::a()]
+}
+
+fn main() {
+    foo::<()>();
+}
diff --git a/src/test/ui/consts/constifconst-call-in-const-position.stderr b/src/test/ui/consts/constifconst-call-in-const-position.stderr
new file mode 100644
index 00000000000..d4a445120a2
--- /dev/null
+++ b/src/test/ui/consts/constifconst-call-in-const-position.stderr
@@ -0,0 +1,18 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/constifconst-call-in-const-position.rs:3:30
+   |
+LL | #![feature(const_trait_impl, generic_const_exprs)]
+   |                              ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
+  --> $DIR/constifconst-call-in-const-position.rs:16:38
+   |
+LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
+   |                                      ^^^^^^ calling non-const function `<() as Tr>::a`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
index 793725d3b80..a2d881f396e 100644
--- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
+++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
@@ -12,11 +12,11 @@ LL | const INVALID_PTR_IN_INT: () = unsafe {
 LL |     let _x: usize = transmute(&3u8);
    |                     ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/detect-extra-ub.rs:22:30
@@ -80,11 +80,11 @@ LL | const INVALID_PTR_IN_INT: () = unsafe {
 LL |     let _x: usize = transmute(&3u8);
    |                     ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -96,11 +96,11 @@ LL |     let x: &[u8] = &[0; 32];
 LL |     let _x: (usize, usize) = transmute(x);
    |                              ^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -111,7 +111,7 @@ LL | const UNALIGNED_READ: () = {
 LL |     INNER;
    |     ^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr
index ae5f6b2baee..f4d69c801ab 100644
--- a/src/test/ui/consts/invalid-union.32bit.stderr
+++ b/src/test/ui/consts/invalid-union.32bit.stderr
@@ -15,9 +15,9 @@ error: erroneous constant used
 LL |     let _: &'static _ = &C;
    |                         ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 2 previous errors
 
@@ -29,7 +29,7 @@ error: erroneous constant used
 LL |     let _: &'static _ = &C;
    |                         ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr
index d50e74a16ec..69b63d3ff92 100644
--- a/src/test/ui/consts/invalid-union.64bit.stderr
+++ b/src/test/ui/consts/invalid-union.64bit.stderr
@@ -15,9 +15,9 @@ error: erroneous constant used
 LL |     let _: &'static _ = &C;
    |                         ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 2 previous errors
 
@@ -29,7 +29,7 @@ error: erroneous constant used
 LL |     let _: &'static _ = &C;
    |                         ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr
index 73a0f8ec0d0..b672f5690da 100644
--- a/src/test/ui/consts/issue-56164.stderr
+++ b/src/test/ui/consts/issue-56164.stderr
@@ -19,9 +19,9 @@ error: erroneous constant used
 LL | const fn foo() { (||{})() }
    |                  ^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 3 previous errors
 
@@ -33,7 +33,7 @@ error: erroneous constant used
 LL | const fn foo() { (||{})() }
    |                  ^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr
index 5460cc1ee82..5320da00562 100644
--- a/src/test/ui/consts/issue-66693.stderr
+++ b/src/test/ui/consts/issue-66693.stderr
@@ -28,9 +28,9 @@ error: erroneous constant used
 LL |     panic!(&1);
    |            ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to 4 previous errors
 
@@ -41,7 +41,7 @@ error: erroneous constant used
 LL |     panic!(&1);
    |            ^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr
index 0f0539e0979..bfd5421a93c 100644
--- a/src/test/ui/consts/issue-miri-1910.stderr
+++ b/src/test/ui/consts/issue-miri-1910.stderr
@@ -14,11 +14,11 @@ LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
 LL | const C: () = unsafe {
    | -----------
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error
 
@@ -39,9 +39,9 @@ LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
 LL | const C: () = unsafe {
    | -----------
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr
index 1f82ac827ad..c64107ee26e 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr
+++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr
@@ -32,11 +32,11 @@ LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 LL |     const F: u32 = (U::X, 42).1;
    |     ------------
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/assoc_const.rs:4:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
index cbf02199f5b..950c3db1b7e 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
+++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
@@ -14,11 +14,11 @@ warning: any use of this value will cause an error
 LL |     const F: u32 = 100 / U::X;
    |     ------------   ^^^^^^^^^^ attempt to divide `100_u32` by zero
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/assoc_const_2.rs:3:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr
index fa2088124b0..03359e62264 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr
@@ -57,13 +57,13 @@ LL |     static FOO: AtomicUsize = AtomicUsize::new(0);
 LL |     FOO.fetch_add(1, Ordering::Relaxed)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `AtomicUsize::fetch_add`
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static.rs:3:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -75,13 +75,13 @@ LL |     static FOO: AtomicUsize = AtomicUsize::new(0);
 LL |     unsafe { *(&FOO as *const _ as *const usize) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static.rs:3:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -90,11 +90,11 @@ warning: any use of this value will cause an error
 LL | const READ_MUT: u32 = unsafe { MUTABLE };
    | -------------------            ^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static.rs:3:10
    |
 LL | #![allow(const_err)]
    |          ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
index 3a22b068916..f66a96ae3f1 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
@@ -40,13 +40,13 @@ LL | const U8_MUT2: &u8 = {
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:23:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: could not evaluate constant pattern
   --> $DIR/const_refers_to_static_cross_crate.rs:60:9
@@ -62,13 +62,13 @@ LL | const U8_MUT3: &u8 = {
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:30:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: could not evaluate constant pattern
   --> $DIR/const_refers_to_static_cross_crate.rs:68:9
@@ -165,13 +165,13 @@ LL | const U8_MUT2: &u8 = {
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:23:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -182,11 +182,11 @@ LL | const U8_MUT3: &u8 = {
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:30:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
index 39c874d6498..f919c364310 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
@@ -40,13 +40,13 @@ LL | const U8_MUT2: &u8 = {
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:23:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: could not evaluate constant pattern
   --> $DIR/const_refers_to_static_cross_crate.rs:60:9
@@ -62,13 +62,13 @@ LL | const U8_MUT3: &u8 = {
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:30:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 error: could not evaluate constant pattern
   --> $DIR/const_refers_to_static_cross_crate.rs:68:9
@@ -165,13 +165,13 @@ LL | const U8_MUT2: &u8 = {
 LL |     unsafe { &(*static_cross_crate::ZERO_REF)[0] }
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:23:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
 Future breakage diagnostic:
 warning: any use of this value will cause an error
@@ -182,11 +182,11 @@ LL | const U8_MUT3: &u8 = {
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 note: the lint level is defined here
   --> $DIR/const_refers_to_static_cross_crate.rs:30:8
    |
 LL | #[warn(const_err)]
    |        ^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
 
diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr
index 3de2aba5b05..df9a8bf51b0 100644
--- a/src/test/ui/consts/ptr_comparisons.stderr
+++ b/src/test/ui/consts/ptr_comparisons.stderr
@@ -24,11 +24,11 @@ error: any use of this value will cause an error
 LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
    | --------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/ptr_comparisons.rs:62:27
@@ -51,11 +51,11 @@ error: any use of this value will cause an error
 LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
    | --------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
 Future breakage diagnostic:
 error: any use of this value will cause an error
@@ -64,9 +64,9 @@ error: any use of this value will cause an error
 LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
    | --------------            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
    = help: this code performed an operation that depends on the underlying bytes representing a pointer
    = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/recursive.stderr b/src/test/ui/consts/recursive.stderr
index 647ed1db20b..65fb2a69d8f 100644
--- a/src/test/ui/consts/recursive.stderr
+++ b/src/test/ui/consts/recursive.stderr
@@ -6,8 +6,8 @@ LL | const fn f<T>(x: T) {
 LL |     f(x);
    |     ---- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error: any use of this value will cause an error
   --> $DIR/recursive.rs:4:5
@@ -23,9 +23,9 @@ LL |     f(x);
 LL | const X: () = f(1);
    | -----------
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error: aborting due to previous error; 1 warning emitted
 
@@ -44,7 +44,7 @@ LL |     f(x);
 LL | const X: () = f(1);
    | -----------
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr
index 4f2f5e244b6..3855b5f2a68 100644
--- a/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr
+++ b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr
@@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use
 LL | #![feature(adt_const_params)]
    |            ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0741]: using function pointers as const generic parameters is forbidden
   --> $DIR/refs_check_const_eq-issue-88384.rs:10:21
diff --git a/src/test/ui/consts/trait_specialization.stderr b/src/test/ui/consts/trait_specialization.stderr
index e80821cf46a..10bebe8ebc5 100644
--- a/src/test/ui/consts/trait_specialization.stderr
+++ b/src/test/ui/consts/trait_specialization.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
index d3177784789..0848fbf1968 100644
--- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr
+++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
@@ -137,9 +137,9 @@ LL |     hint_unreachable()
 LL |     const CONSTANT: i32 = unsafe { fake_type() };
    |     -------------------
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error[E0080]: erroneous constant used
   --> $DIR/uninhabited-const-issue-61744.rs:19:10
@@ -290,7 +290,7 @@ LL |     hint_unreachable()
 LL |     const CONSTANT: i32 = unsafe { fake_type() };
    |     -------------------
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr
index bd36a25686a..dcdf8f8430f 100644
--- a/src/test/ui/derive-uninhabited-enum-38885.stderr
+++ b/src/test/ui/derive-uninhabited-enum-38885.stderr
@@ -7,8 +7,8 @@ LL |     Bar(u8),
 LL |     Void(Void),
    |     ^^^^
    |
-   = note: `-W dead-code` implied by `-W unused`
    = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+   = note: `-W dead-code` implied by `-W unused`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr
index baf34b46d8b..512b870fa4b 100644
--- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr
+++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr
@@ -13,12 +13,12 @@ LL |     field3: (),
 LL |     field4: (),
    |     ^^^^^^
    |
+   = note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
 note: the lint level is defined here
   --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11
    |
 LL | #![forbid(dead_code)]
    |           ^^^^^^^^^
-   = note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr
index d3fe550c3e4..0ad800c3981 100644
--- a/src/test/ui/derives/deriving-with-repr-packed.stderr
+++ b/src/test/ui/derives/deriving-with-repr-packed.stderr
@@ -4,13 +4,13 @@ error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or co
 LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
    |                ^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
 note: the lint level is defined here
   --> $DIR/deriving-with-repr-packed.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters
@@ -52,13 +52,13 @@ error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or co
 LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
    |                ^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
 note: the lint level is defined here
   --> $DIR/deriving-with-repr-packed.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -68,13 +68,13 @@ error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type o
 LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
    |                                ^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
 note: the lint level is defined here
   --> $DIR/deriving-with-repr-packed.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -84,13 +84,13 @@ error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not de
 LL | #[derive(Default, Hash)]
    |                   ^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
 note: the lint level is defined here
   --> $DIR/deriving-with-repr-packed.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -100,12 +100,12 @@ error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not d
 LL | #[derive(Debug, Default)]
    |          ^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
 note: the lint level is defined here
   --> $DIR/deriving-with-repr-packed.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs
index d1a81c72c2f..1c7a501edc7 100644
--- a/src/test/ui/deriving/deriving-default-enum.rs
+++ b/src/test/ui/deriving/deriving-default-enum.rs
@@ -12,6 +12,16 @@ enum Foo {
     Beta(NotDefault),
 }
 
+// #[default] on a generic enum does not add `Default` bounds to the type params.
+#[derive(Default)]
+enum MyOption<T> {
+    #[default]
+    None,
+    #[allow(dead_code)]
+    Some(T),
+}
+
 fn main() {
     assert_eq!(Foo::default(), Foo::Alpha);
+    assert!(matches!(MyOption::<NotDefault>::default(), MyOption::None));
 }
diff --git a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr
index 1df7a5f224f..e16625136ac 100644
--- a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr
+++ b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr
@@ -4,12 +4,12 @@ warning: value assigned to `a` is never read
 LL |     (a, a) = (0, 1);
    |      ^
    |
+   = help: maybe it is overwritten before being read?
 note: the lint level is defined here
   --> $DIR/warn-unused-duplication.rs:3:9
    |
 LL | #![warn(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
-   = help: maybe it is overwritten before being read?
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr
index 2326af934d0..21f957ab549 100644
--- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr
+++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr
@@ -105,9 +105,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | type H = Fn(u8) -> (u8)::Output;
    |          ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL | type H = <dyn Fn(u8) -> (u8)>::Output;
diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr
index 88617381236..8fe38bf6972 100644
--- a/src/test/ui/did_you_mean/issue-31424.stderr
+++ b/src/test/ui/did_you_mean/issue-31424.stderr
@@ -24,8 +24,8 @@ LL |     fn bar(self: &mut Self) {
 LL |         (&mut self).bar();
    |         ----------------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
   --> $DIR/issue-31424.rs:16:9
diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr
index 3eb5bb7b26d..89aded9134f 100644
--- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr
+++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr
@@ -4,13 +4,13 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     pub mod dyn {
    |             ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:11:9
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
   --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:17:20
diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
index e7db68693c0..6bafff9192a 100644
--- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -4,13 +4,13 @@ error: trait objects without an explicit `dyn` are deprecated
 LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
    |                 ^^^^^^^^^
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/dyn-2018-edition-lint.rs:2:8
    |
 LL | #[deny(bare_trait_objects)]
    |        ^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 help: use `dyn`
    |
 LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
index 261c2d5742f..0bb764d712e 100644
--- a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
+++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
@@ -4,13 +4,13 @@ error: trait objects without an explicit `dyn` are deprecated
 LL |         <fmt::Debug>::fmt(self, f)
    |          ^^^^^^^^^^
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/dyn-angle-brackets.rs:4:9
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 help: use `dyn`
    |
 LL |         <dyn fmt::Debug>::fmt(self, f)
diff --git a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr
index 417daf36fca..612dd17e71e 100644
--- a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr
+++ b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr
@@ -4,14 +4,14 @@ error: type annotations needed
 LL |     let _ = y.is_null();
    |               ^^^^^^^
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
 note: the lint level is defined here
   --> $DIR/edition-raw-pointer-method-2015.rs:5:8
    |
 LL | #[deny(warnings)]
    |        ^^^^^^^^
    = note: `#[deny(tyvar_behind_raw_pointer)]` implied by `#[deny(warnings)]`
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/empty/empty-attributes.stderr b/src/test/ui/empty/empty-attributes.stderr
index 8653eaf5ccd..01d0d5a6b48 100644
--- a/src/test/ui/empty/empty-attributes.stderr
+++ b/src/test/ui/empty/empty-attributes.stderr
@@ -4,12 +4,12 @@ error: unused attribute
 LL | #[repr()]
    | ^^^^^^^^^ help: remove this attribute
    |
+   = note: attribute `repr` with an empty list has no effect
 note: the lint level is defined here
   --> $DIR/empty-attributes.rs:3:9
    |
 LL | #![deny(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = note: attribute `repr` with an empty list has no effect
 
 error: unused attribute
   --> $DIR/empty-attributes.rs:14:1
diff --git a/src/test/ui/enum-discriminant/discriminant_size.stderr b/src/test/ui/enum-discriminant/discriminant_size.stderr
index efc7d998466..9b1505b5c46 100644
--- a/src/test/ui/enum-discriminant/discriminant_size.stderr
+++ b/src/test/ui/enum-discriminant/discriminant_size.stderr
@@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c
 LL | #![feature(core_intrinsics, repr128)]
    |                             ^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/enum-discriminant/issue-43398.stderr b/src/test/ui/enum-discriminant/issue-43398.stderr
index 9a394153bf6..fc7bbd06284 100644
--- a/src/test/ui/enum-discriminant/issue-43398.stderr
+++ b/src/test/ui/enum-discriminant/issue-43398.stderr
@@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c
 LL | #![feature(repr128)]
    |            ^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr b/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr
index 5bf6ea56ebc..ac93badf215 100644
--- a/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr
+++ b/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr
@@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c
 LL | #![feature(repr128, arbitrary_enum_discriminant)]
    |            ^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/enum-discriminant/repr128.stderr b/src/test/ui/enum-discriminant/repr128.stderr
index 88adfb1742d..da8d75c11af 100644
--- a/src/test/ui/enum-discriminant/repr128.stderr
+++ b/src/test/ui/enum-discriminant/repr128.stderr
@@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c
 LL | #![feature(repr128, core_intrinsics, discriminant_kind)]
    |            ^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr
index 43830679535..f79f7a043d6 100644
--- a/src/test/ui/enum/enum-discrim-too-small2.stderr
+++ b/src/test/ui/enum/enum-discrim-too-small2.stderr
@@ -4,13 +4,13 @@ error: literal out of range for `i8`
 LL |     Ci8 = 223,
    |           ^^^
    |
+   = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `u8` instead
 note: the lint level is defined here
   --> $DIR/enum-discrim-too-small2.rs:1:9
    |
 LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127`
-   = help: consider using the type `u8` instead
 
 error: literal out of range for `i16`
   --> $DIR/enum-discrim-too-small2.rs:15:12
diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr
index 830e4db345a..6e48f9582f1 100644
--- a/src/test/ui/error-codes/E0017.stderr
+++ b/src/test/ui/error-codes/E0017.stderr
@@ -4,7 +4,6 @@ warning: taking a mutable reference to a `const` item
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^
    |
-   = note: `#[warn(const_item_mutation)]` on by default
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: `const` item defined here
@@ -12,6 +11,7 @@ note: `const` item defined here
    |
 LL | const C: i32 = 2;
    | ^^^^^^^^^^^^
+   = note: `#[warn(const_item_mutation)]` on by default
 
 error[E0764]: mutable references are not allowed in the final value of constants
   --> $DIR/E0017.rs:5:30
diff --git a/src/test/ui/error-codes/E0094.rs b/src/test/ui/error-codes/E0094.rs
index 0d58e5a2862..a2ec932c124 100644
--- a/src/test/ui/error-codes/E0094.rs
+++ b/src/test/ui/error-codes/E0094.rs
@@ -1,5 +1,7 @@
 #![feature(intrinsics)]
+
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T, U>() -> usize; //~ ERROR E0094
 }
 
diff --git a/src/test/ui/error-codes/E0094.stderr b/src/test/ui/error-codes/E0094.stderr
index da97f3a014b..531cd4c784d 100644
--- a/src/test/ui/error-codes/E0094.stderr
+++ b/src/test/ui/error-codes/E0094.stderr
@@ -1,5 +1,5 @@
 error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
-  --> $DIR/E0094.rs:3:15
+  --> $DIR/E0094.rs:5:15
    |
 LL |     fn size_of<T, U>() -> usize;
    |               ^^^^^^ expected 1 type parameter
diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr
index 90a28874ead..90316c6e981 100644
--- a/src/test/ui/error-codes/E0283.stderr
+++ b/src/test/ui/error-codes/E0283.stderr
@@ -9,8 +9,8 @@ LL |     let cont: u32 = Generator::create();
    |
 help: use a fully-qualified path to a specific available implementation (2 found)
    |
-LL |     let cont: u32 = <::Impl as Generator>::create();
-   |                     ++++++++++          +
+LL |     let cont: u32 = <Impl as Generator>::create();
+   |                     ++++++++          +
 
 error[E0283]: type annotations needed
   --> $DIR/E0283.rs:35:24
diff --git a/src/test/ui/error-codes/E0308.rs b/src/test/ui/error-codes/E0308.rs
index fa79bee570e..dd9e0b284ea 100644
--- a/src/test/ui/error-codes/E0308.rs
+++ b/src/test/ui/error-codes/E0308.rs
@@ -1,6 +1,8 @@
 #![feature(intrinsics)]
+#![feature(rustc_attrs)]
 
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T>(); //~ ERROR E0308
 }
 
diff --git a/src/test/ui/error-codes/E0308.stderr b/src/test/ui/error-codes/E0308.stderr
index b71fb95e706..187b775f92d 100644
--- a/src/test/ui/error-codes/E0308.stderr
+++ b/src/test/ui/error-codes/E0308.stderr
@@ -1,5 +1,5 @@
 error[E0308]: intrinsic has wrong type
-  --> $DIR/E0308.rs:4:5
+  --> $DIR/E0308.rs:6:5
    |
 LL |     fn size_of<T>();
    |     ^^^^^^^^^^^^^^^^ expected `()`, found `usize`
diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr
index 106efc19ac9..b51aa263d5e 100644
--- a/src/test/ui/error-codes/E0388.stderr
+++ b/src/test/ui/error-codes/E0388.stderr
@@ -4,7 +4,6 @@ warning: taking a mutable reference to a `const` item
 LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^
    |
-   = note: `#[warn(const_item_mutation)]` on by default
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: `const` item defined here
@@ -12,6 +11,7 @@ note: `const` item defined here
    |
 LL | const C: i32 = 2;
    | ^^^^^^^^^^^^
+   = note: `#[warn(const_item_mutation)]` on by default
 
 error[E0764]: mutable references are not allowed in the final value of constants
   --> $DIR/E0388.rs:4:30
diff --git a/src/test/ui/error-codes/E0520.stderr b/src/test/ui/error-codes/E0520.stderr
index 65ebfcdbe32..12ecead13de 100644
--- a/src/test/ui/error-codes/E0520.stderr
+++ b/src/test/ui/error-codes/E0520.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0520]: `fly` specializes an item from a parent `impl`, but that item is not marked `default`
   --> $DIR/E0520.rs:17:5
diff --git a/src/test/ui/error-codes/E0585.stderr b/src/test/ui/error-codes/E0585.stderr
index 7a31c4896ee..53c82fb416b 100644
--- a/src/test/ui/error-codes/E0585.stderr
+++ b/src/test/ui/error-codes/E0585.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     /// Hello! I'm useless...
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr
index 3ab727f5f69..b759399a940 100644
--- a/src/test/ui/error-codes/E0771.stderr
+++ b/src/test/ui/error-codes/E0771.stderr
@@ -12,8 +12,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use
 LL | #![feature(adt_const_params)]
    |            ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/error-codes/E0790.stderr b/src/test/ui/error-codes/E0790.stderr
index 6e173a9682a..f68c0e7d220 100644
--- a/src/test/ui/error-codes/E0790.stderr
+++ b/src/test/ui/error-codes/E0790.stderr
@@ -9,8 +9,8 @@ LL |         MyTrait::my_fn();
    |
 help: use the fully-qualified path to the only available implementation
    |
-LL |         <::inner::MyStruct as MyTrait>::my_fn();
-   |         +++++++++++++++++++++        +
+LL |         <MyStruct as MyTrait>::my_fn();
+   |         ++++++++++++        +
 
 error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
   --> $DIR/E0790.rs:21:17
@@ -23,8 +23,8 @@ LL |         let _ = MyTrait::MY_ASSOC_CONST;
    |
 help: use the fully-qualified path to the only available implementation
    |
-LL |         let _ = <::inner::MyStruct as MyTrait>::MY_ASSOC_CONST;
-   |                 +++++++++++++++++++++        +
+LL |         let _ = <MyStruct as MyTrait>::MY_ASSOC_CONST;
+   |                 ++++++++++++        +
 
 error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
   --> $DIR/E0790.rs:26:5
@@ -37,8 +37,8 @@ LL |     inner::MyTrait::my_fn();
    |
 help: use the fully-qualified path to the only available implementation
    |
-LL |     inner::<::inner::MyStruct as MyTrait>::my_fn();
-   |            +++++++++++++++++++++        +
+LL |     inner::<MyStruct as MyTrait>::my_fn();
+   |            ++++++++++++        +
 
 error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
   --> $DIR/E0790.rs:30:13
@@ -51,8 +51,8 @@ LL |     let _ = inner::MyTrait::MY_ASSOC_CONST;
    |
 help: use the fully-qualified path to the only available implementation
    |
-LL |     let _ = inner::<::inner::MyStruct as MyTrait>::MY_ASSOC_CONST;
-   |                    +++++++++++++++++++++        +
+LL |     let _ = inner::<MyStruct as MyTrait>::MY_ASSOC_CONST;
+   |                    ++++++++++++        +
 
 error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
   --> $DIR/E0790.rs:50:5
@@ -65,8 +65,8 @@ LL |     MyTrait2::my_fn();
    |
 help: use a fully-qualified path to a specific available implementation (2 found)
    |
-LL |     <::Impl1 as MyTrait2>::my_fn();
-   |     +++++++++++         +
+LL |     <Impl1 as MyTrait2>::my_fn();
+   |     +++++++++         +
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr
index 4ec78a298fe..08eb8cfac49 100644
--- a/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr
+++ b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr
@@ -8,9 +8,9 @@ LL | |
 LL | |     )) {}
    | |_____^
    |
-   = note: `#[warn(anonymous_parameters)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+   = note: `#[warn(anonymous_parameters)]` on by default
 help: try naming the parameter or explicitly ignoring it
    |
 LL ~     fn test(x: u32, _: (
diff --git a/src/test/ui/expr/if/if-let.stderr b/src/test/ui/expr/if/if-let.stderr
index 8238b3f0e49..c4bba3cb1a8 100644
--- a/src/test/ui/expr/if/if-let.stderr
+++ b/src/test/ui/expr/if/if-let.stderr
@@ -9,9 +9,9 @@ LL | |         println!("irrefutable pattern");
 LL | |     });
    | |______- in this macro invocation
    |
-   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this pattern will always match, so the `if let` is useless
    = help: consider replacing the `if let` with a `let`
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: irrefutable `if let` pattern
diff --git a/src/test/ui/extern/extern-no-mangle.stderr b/src/test/ui/extern/extern-no-mangle.stderr
index b5642814114..f20ee158ac4 100644
--- a/src/test/ui/extern/extern-no-mangle.stderr
+++ b/src/test/ui/extern/extern-no-mangle.stderr
@@ -7,12 +7,12 @@ LL |     #[no_mangle]
 LL |     let x = 0_u8;
    |     ------------- not a free function, impl method or static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 note: the lint level is defined here
   --> $DIR/extern-no-mangle.rs:1:9
    |
 LL | #![warn(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[no_mangle]` has no effect on a foreign static
   --> $DIR/extern-no-mangle.rs:11:5
diff --git a/src/test/ui/extern/extern-with-type-bounds.rs b/src/test/ui/extern/extern-with-type-bounds.rs
index 8f9683e4a74..a72aa4171a1 100644
--- a/src/test/ui/extern/extern-with-type-bounds.rs
+++ b/src/test/ui/extern/extern-with-type-bounds.rs
@@ -2,6 +2,7 @@
 
 extern "rust-intrinsic" {
     // Real example from libcore
+    #[rustc_safe_intrinsic]
     fn type_id<T: ?Sized + 'static>() -> u64;
 
     // Silent bounds made explicit to make sure they are actually
@@ -10,6 +11,7 @@ extern "rust-intrinsic" {
 
     // Bounds aren't checked right now, so this should work
     // even though it's incorrect.
+    #[rustc_safe_intrinsic]
     fn size_of<T: Clone>() -> usize;
 
     // Unresolved bounds should still error.
diff --git a/src/test/ui/extern/extern-with-type-bounds.stderr b/src/test/ui/extern/extern-with-type-bounds.stderr
index acd0596422f..88be1e5dd3d 100644
--- a/src/test/ui/extern/extern-with-type-bounds.stderr
+++ b/src/test/ui/extern/extern-with-type-bounds.stderr
@@ -1,5 +1,5 @@
 error[E0405]: cannot find trait `NoSuchTrait` in this scope
-  --> $DIR/extern-with-type-bounds.rs:16:20
+  --> $DIR/extern-with-type-bounds.rs:18:20
    |
 LL |     fn align_of<T: NoSuchTrait>() -> usize;
    |                    ^^^^^^^^^^^ not found in this scope
diff --git a/src/test/ui/feature-gates/bench.stderr b/src/test/ui/feature-gates/bench.stderr
index 168ac925724..5f0aaf9251f 100644
--- a/src/test/ui/feature-gates/bench.stderr
+++ b/src/test/ui/feature-gates/bench.stderr
@@ -4,9 +4,9 @@ error: use of unstable library feature 'test': `bench` is a part of custom test
 LL | #[bench]
    |   ^^^^^
    |
-   = note: `#[deny(soft_unstable)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
+   = note: `#[deny(soft_unstable)]` on by default
 
 error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
   --> $DIR/bench.rs:7:5
diff --git a/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr b/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr
index a7d5c7ac39b..308de269293 100644
--- a/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr
+++ b/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr
@@ -4,9 +4,9 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
 LL | fn avg<T=i32>(_: T) {}
    |        ^^^^^
    |
-   = note: `#[deny(invalid_type_param_default)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
   --> $DIR/feature-gate-default_type_parameter_fallback.rs:8:6
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
index 3de08e215da..4d79ce3c659 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
@@ -4,10 +4,10 @@ warning: unknown lint: `non_exhaustive_omitted_patterns`
 LL | #![deny(non_exhaustive_omitted_patterns)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unknown_lints)]` on by default
    = note: the `non_exhaustive_omitted_patterns` lint is unstable
    = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
    = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+   = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `non_exhaustive_omitted_patterns`
   --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:6:1
diff --git a/src/test/ui/feature-gates/feature-gate-repr-simd.stderr b/src/test/ui/feature-gates/feature-gate-repr-simd.stderr
index ae44b802069..5b1270a1984 100644
--- a/src/test/ui/feature-gates/feature-gate-repr-simd.stderr
+++ b/src/test/ui/feature-gates/feature-gate-repr-simd.stderr
@@ -25,9 +25,9 @@ LL |
 LL | #[repr(simd)]
    |        ^^^^
    |
-   = note: `#[deny(conflicting_repr_hints)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr b/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr
index 34bd240c304..751da87cc0d 100644
--- a/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr
+++ b/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr
@@ -4,10 +4,10 @@ warning: unknown lint: `fuzzy_provenance_casts`
 LL | #![deny(fuzzy_provenance_casts)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unknown_lints)]` on by default
    = note: the `fuzzy_provenance_casts` lint is unstable
    = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
    = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+   = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `lossy_provenance_casts`
   --> $DIR/feature-gate-strict_provenance.rs:7:1
diff --git a/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr b/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr
index a29322443ea..b4d6aa658e1 100644
--- a/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr
+++ b/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr
@@ -4,9 +4,9 @@ warning: unknown lint: `test_unstable_lint`
 LL | #![allow(test_unstable_lint)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unknown_lints)]` on by default
    = note: the `test_unstable_lint` lint is unstable
    = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `test_unstable_lint`
   --> $DIR/feature-gate-test_unstable_lint.rs:4:1
diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
index f94ec7d4704..5a645cf4ef9 100644
--- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
+++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
@@ -12,9 +12,9 @@ error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
 LL |     #[inline = "2100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(ill_formed_attribute_input)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: `start` attribute can only be used on functions
   --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:1
diff --git a/src/test/ui/fmt/auxiliary/format-string-proc-macro.rs b/src/test/ui/fmt/auxiliary/format-string-proc-macro.rs
new file mode 100644
index 00000000000..e44a84776bc
--- /dev/null
+++ b/src/test/ui/fmt/auxiliary/format-string-proc-macro.rs
@@ -0,0 +1,28 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Literal, Span, TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn foo_with_input_span(input: TokenStream) -> TokenStream {
+    let span = input.into_iter().next().unwrap().span();
+
+    let mut lit = Literal::string("{foo}");
+    lit.set_span(span);
+
+    TokenStream::from(TokenTree::Literal(lit))
+}
+
+#[proc_macro]
+pub fn err_with_input_span(input: TokenStream) -> TokenStream {
+    let span = input.into_iter().next().unwrap().span();
+
+    let mut lit = Literal::string("         }");
+    lit.set_span(span);
+
+    TokenStream::from(TokenTree::Literal(lit))
+}
diff --git a/src/test/ui/fmt/format-args-capture-issue-102057.rs b/src/test/ui/fmt/format-args-capture-issue-102057.rs
new file mode 100644
index 00000000000..b8089d49bcb
--- /dev/null
+++ b/src/test/ui/fmt/format-args-capture-issue-102057.rs
@@ -0,0 +1,19 @@
+fn main() {
+    format!("\x7Ba}");
+    //~^ ERROR cannot find value `a` in this scope
+    format!("\x7Ba\x7D");
+    //~^ ERROR cannot find value `a` in this scope
+
+    let a = 0;
+
+    format!("\x7Ba} {b}");
+    //~^ ERROR cannot find value `b` in this scope
+    format!("\x7Ba\x7D {b}");
+    //~^ ERROR cannot find value `b` in this scope
+    format!("\x7Ba} \x7Bb}");
+    //~^ ERROR cannot find value `b` in this scope
+    format!("\x7Ba\x7D \x7Bb}");
+    //~^ ERROR cannot find value `b` in this scope
+    format!("\x7Ba\x7D \x7Bb\x7D");
+    //~^ ERROR cannot find value `b` in this scope
+}
diff --git a/src/test/ui/fmt/format-args-capture-issue-102057.stderr b/src/test/ui/fmt/format-args-capture-issue-102057.stderr
new file mode 100644
index 00000000000..f2d625e7f8d
--- /dev/null
+++ b/src/test/ui/fmt/format-args-capture-issue-102057.stderr
@@ -0,0 +1,45 @@
+error[E0425]: cannot find value `a` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:2:18
+   |
+LL |     format!("\x7Ba}");
+   |                  ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:4:18
+   |
+LL |     format!("\x7Ba\x7D");
+   |                  ^ not found in this scope
+
+error[E0425]: cannot find value `b` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:9:22
+   |
+LL |     format!("\x7Ba} {b}");
+   |                      ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:11:25
+   |
+LL |     format!("\x7Ba\x7D {b}");
+   |                         ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:13:25
+   |
+LL |     format!("\x7Ba} \x7Bb}");
+   |                         ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:15:28
+   |
+LL |     format!("\x7Ba\x7D \x7Bb}");
+   |                            ^ help: a local variable with a similar name exists: `a`
+
+error[E0425]: cannot find value `b` in this scope
+  --> $DIR/format-args-capture-issue-102057.rs:17:28
+   |
+LL |     format!("\x7Ba\x7D \x7Bb\x7D");
+   |                            ^ help: a local variable with a similar name exists: `a`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs
index fdbd93836ef..b04f80ba406 100644
--- a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs
+++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs
@@ -1,4 +1,22 @@
+// aux-build:format-string-proc-macro.rs
+
+#[macro_use]
+extern crate format_string_proc_macro;
+
+macro_rules! def_site {
+    () => { "{foo}" } //~ ERROR: there is no argument named `foo`
+}
+
+macro_rules! call_site {
+    ($fmt:literal) => { $fmt }
+}
+
 fn main() {
     format!(concat!("{foo}"));         //~ ERROR: there is no argument named `foo`
     format!(concat!("{ba", "r} {}"), 1);     //~ ERROR: there is no argument named `bar`
+
+    format!(def_site!());
+    format!(call_site!("{foo}")); //~ ERROR: there is no argument named `foo`
+
+    format!(foo_with_input_span!("")); //~ ERROR: there is no argument named `foo`
 }
diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr
index 9423e8c819d..1b5fbd2af34 100644
--- a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr
+++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr
@@ -1,5 +1,5 @@
 error: there is no argument named `foo`
-  --> $DIR/format-args-capture-macro-hygiene.rs:2:13
+  --> $DIR/format-args-capture-macro-hygiene.rs:15:13
    |
 LL |     format!(concat!("{foo}"));
    |             ^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     format!(concat!("{foo}"));
    = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: there is no argument named `bar`
-  --> $DIR/format-args-capture-macro-hygiene.rs:3:13
+  --> $DIR/format-args-capture-macro-hygiene.rs:16:13
    |
 LL |     format!(concat!("{ba", "r} {}"), 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -18,5 +18,36 @@ LL |     format!(concat!("{ba", "r} {}"), 1);
    = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
    = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: there is no argument named `foo`
+  --> $DIR/format-args-capture-macro-hygiene.rs:7:13
+   |
+LL |     () => { "{foo}" }
+   |             ^^^^^^^
+...
+LL |     format!(def_site!());
+   |             ----------- in this macro invocation
+   |
+   = note: did you intend to capture a variable `foo` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+   = note: this error originates in the macro `def_site` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: there is no argument named `foo`
+  --> $DIR/format-args-capture-macro-hygiene.rs:19:24
+   |
+LL |     format!(call_site!("{foo}"));
+   |                        ^^^^^^^
+   |
+   = note: did you intend to capture a variable `foo` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+
+error: there is no argument named `foo`
+  --> $DIR/format-args-capture-macro-hygiene.rs:21:34
+   |
+LL |     format!(foo_with_input_span!(""));
+   |                                  ^^
+   |
+   = note: did you intend to capture a variable `foo` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/fmt/format-concat-span.stderr b/src/test/ui/fmt/format-concat-span.stderr
deleted file mode 100644
index da46f40abcb..00000000000
--- a/src/test/ui/fmt/format-concat-span.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: invalid format string: unmatched `}` found
-  --> $DIR/format-concat-span.rs:13:13
-   |
-LL |     format!(concat!("abc}"));
-   |             ^^^^^^^^^^^^^^^ unmatched `}` in format string
-   |
-   = note: if you intended to print `}`, you can escape it using `}}`
-   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/fmt/format-concat-span.rs b/src/test/ui/fmt/format-expanded-string.rs
index ce92df0ad92..4c716f08c71 100644
--- a/src/test/ui/fmt/format-concat-span.rs
+++ b/src/test/ui/fmt/format-expanded-string.rs
@@ -1,3 +1,9 @@
+// aux-build:format-string-proc-macro.rs
+
+#[macro_use]
+extern crate format_string_proc_macro;
+
+
 // If the format string is another macro invocation, rustc would previously
 // compute nonsensical spans, such as:
 //
@@ -12,4 +18,7 @@
 fn main() {
     format!(concat!("abc}"));
     //~^ ERROR: invalid format string: unmatched `}` found
+
+    format!(err_with_input_span!(""));
+    //~^ ERROR: invalid format string: unmatched `}` found
 }
diff --git a/src/test/ui/fmt/format-expanded-string.stderr b/src/test/ui/fmt/format-expanded-string.stderr
new file mode 100644
index 00000000000..26ce7f26958
--- /dev/null
+++ b/src/test/ui/fmt/format-expanded-string.stderr
@@ -0,0 +1,19 @@
+error: invalid format string: unmatched `}` found
+  --> $DIR/format-expanded-string.rs:19:13
+   |
+LL |     format!(concat!("abc}"));
+   |             ^^^^^^^^^^^^^^^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: invalid format string: unmatched `}` found
+  --> $DIR/format-expanded-string.rs:22:34
+   |
+LL |     format!(err_with_input_span!(""));
+   |                                  ^^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/for-loop-while/while-let-2.stderr b/src/test/ui/for-loop-while/while-let-2.stderr
index 2d23a637361..1b1cf679243 100644
--- a/src/test/ui/for-loop-while/while-let-2.stderr
+++ b/src/test/ui/for-loop-while/while-let-2.stderr
@@ -9,9 +9,9 @@ LL | |         println!("irrefutable pattern");
 LL | |     });
    | |______- in this macro invocation
    |
-   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this pattern will always match, so the loop will never exit
    = help: consider instead using a `loop { ... }` with a `let` inside it
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: irrefutable `while let` pattern
diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr
index 8f6dde665e6..a8fb100a749 100644
--- a/src/test/ui/future-incompatible-lint-group.stderr
+++ b/src/test/ui/future-incompatible-lint-group.stderr
@@ -4,9 +4,9 @@ warning: anonymous parameters are deprecated and will be removed in the next edi
 LL |     fn f(u8) {}
    |          ^^ help: try naming the parameter or explicitly ignoring it: `_: u8`
    |
-   = note: `#[warn(anonymous_parameters)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+   = note: `#[warn(anonymous_parameters)]` on by default
 
 error: this attribute can only be applied at the crate level
   --> $DIR/future-incompatible-lint-group.rs:13:12
@@ -14,15 +14,15 @@ error: this attribute can only be applied at the crate level
 LL |     #![doc(test(some_test))]
    |            ^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 note: the lint level is defined here
   --> $DIR/future-incompatible-lint-group.rs:3:9
    |
 LL | #![deny(future_incompatible)]
    |         ^^^^^^^^^^^^^^^^^^^
    = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
-   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr
index 3f8ebb5a738..30a6732f759 100644
--- a/src/test/ui/generator/issue-52398.stderr
+++ b/src/test/ui/generator/issue-52398.stderr
@@ -6,8 +6,8 @@ LL | |         A.test(yield);
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: unused generator that must be used
   --> $DIR/issue-52398.rs:24:5
diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr
index 32a04f94dcb..29aca94408a 100644
--- a/src/test/ui/generator/issue-57084.stderr
+++ b/src/test/ui/generator/issue-57084.stderr
@@ -9,8 +9,8 @@ LL | |         }
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr
index 4fd1e26f0c8..b911b666190 100644
--- a/src/test/ui/generator/match-bindings.stderr
+++ b/src/test/ui/generator/match-bindings.stderr
@@ -10,8 +10,8 @@ LL | |         }
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr
index 3a83021dd99..2e020780480 100644
--- a/src/test/ui/generator/print/generator-print-verbose-1.stderr
+++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr
@@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield
   --> $DIR/generator-print-verbose-1.rs:35:9
    |
 LL |         let _non_send_gen = make_non_send_generator();
-   |             ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
+   |             ------------- has type `Opaque(DefId(0:44 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
 LL |     };
@@ -35,17 +35,17 @@ note: required because it's used within this generator
    |
 LL |     || {
    |     ^^
-note: required because it appears within the type `Opaque(DefId(0:39 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
+note: required because it appears within the type `Opaque(DefId(0:45 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
   --> $DIR/generator-print-verbose-1.rs:41:30
    |
 LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
+note: required because it appears within the type `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
   --> $DIR/generator-print-verbose-1.rs:47:34
    |
 LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
+   = note: required because it captures the following types: `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
 note: required because it's used within this generator
   --> $DIR/generator-print-verbose-1.rs:52:20
    |
diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr
index ff511b76672..e83dbf833bf 100644
--- a/src/test/ui/generator/reborrow-mut-upvar.stderr
+++ b/src/test/ui/generator/reborrow-mut-upvar.stderr
@@ -10,8 +10,8 @@ LL | |         *bar = 2;
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
index 72a2bd4ebc5..5cb43067fee 100644
--- a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
+++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
@@ -10,8 +10,8 @@ LL | |             let _ = &a;
 LL | |         };
    | |__________^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr
index a575bf88678..c9e1ab722d4 100644
--- a/src/test/ui/generator/yield-in-args-rev.stderr
+++ b/src/test/ui/generator/yield-in-args-rev.stderr
@@ -7,8 +7,8 @@ LL | |         foo(yield, &b);
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr
index 7602e803945..8587e1dc663 100644
--- a/src/test/ui/generator/yield-in-box.stderr
+++ b/src/test/ui/generator/yield-in-box.stderr
@@ -10,8 +10,8 @@ LL | |         }
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr
index e79047ae701..07de24662cf 100644
--- a/src/test/ui/generator/yield-in-initializer.stderr
+++ b/src/test/ui/generator/yield-in-initializer.stderr
@@ -10,8 +10,8 @@ LL | |         }
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr
index bded36a4cda..fe10477bf73 100644
--- a/src/test/ui/generator/yield-subtype.stderr
+++ b/src/test/ui/generator/yield-subtype.stderr
@@ -7,8 +7,8 @@ LL | |         yield b;
 LL | |     };
    | |______^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/generic-associated-types/issue-102114.rs b/src/test/ui/generic-associated-types/issue-102114.rs
new file mode 100644
index 00000000000..de31737efef
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102114.rs
@@ -0,0 +1,16 @@
+trait A {
+    type B<'b>;
+    fn a() -> Self::B<'static>;
+}
+
+struct C;
+
+struct Wrapper<T>(T);
+
+impl A for C {
+    type B<T> = Wrapper<T>;
+    //~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters
+    fn a() -> Self::B<'static> {}
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-102114.stderr b/src/test/ui/generic-associated-types/issue-102114.stderr
new file mode 100644
index 00000000000..8e41dee54d7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102114.stderr
@@ -0,0 +1,12 @@
+error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/issue-102114.rs:11:12
+   |
+LL |     type B<'b>;
+   |            -- expected 0 type parameters
+...
+LL |     type B<T> = Wrapper<T>;
+   |            ^ found 1 type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/src/test/ui/generic-associated-types/issue-102333.rs b/src/test/ui/generic-associated-types/issue-102333.rs
new file mode 100644
index 00000000000..6c72563322f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102333.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+trait A {
+    type T: B<U<1i32> = ()>;
+}
+
+trait B {
+    type U<const C: i32>;
+}
+
+fn f<T: A>() {
+    let _: <<T as A>::T as B>::U<1i32> = ();
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
index d8e889aecef..11c4ebf604e 100644
--- a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
+++ b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: can't compare `Foo` with `Foo`
   --> $DIR/issue-87429-specialization.rs:20:31
diff --git a/src/test/ui/generics/issue-94923.rs b/src/test/ui/generics/issue-94923.rs
new file mode 100644
index 00000000000..d337a5dffc9
--- /dev/null
+++ b/src/test/ui/generics/issue-94923.rs
@@ -0,0 +1,49 @@
+// run-pass
+// regression test for issue #94923
+// min-llvm-version: 15.0.0
+// compile-flags: -C opt-level=3
+
+fn f0<T>(mut x: usize) -> usize {
+    for _ in 0..1000 {
+        x *= 123;
+        x %= 99
+    }
+    x + 321 // function composition is not just longer iteration
+}
+
+fn f1<T>(x: usize) -> usize {
+    f0::<(i8, T)>(f0::<(u8, T)>(x))
+}
+
+fn f2<T>(x: usize) -> usize {
+    f1::<(i8, T)>(f1::<(u8, T)>(x))
+}
+
+fn f3<T>(x: usize) -> usize {
+    f2::<(i8, T)>(f2::<(u8, T)>(x))
+}
+
+fn f4<T>(x: usize) -> usize {
+    f3::<(i8, T)>(f3::<(u8, T)>(x))
+}
+
+fn f5<T>(x: usize) -> usize {
+    f4::<(i8, T)>(f4::<(u8, T)>(x))
+}
+
+fn f6<T>(x: usize) -> usize {
+    f5::<(i8, T)>(f5::<(u8, T)>(x))
+}
+
+fn f7<T>(x: usize) -> usize {
+    f6::<(i8, T)>(f6::<(u8, T)>(x))
+}
+
+fn f8<T>(x: usize) -> usize {
+    f7::<(i8, T)>(f7::<(u8, T)>(x))
+}
+
+fn main() {
+    let y = f8::<()>(1);
+    assert_eq!(y, 348);
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
index 5e75a4cc8af..727b9e6bec8 100644
--- a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
@@ -9,8 +9,8 @@ LL | |     T: Bar<&'b isize>,
 LL |       no_hrtb(&mut t);
    |       --------------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 warning: function cannot return without recursing
   --> $DIR/hrtb-perfect-forwarding.rs:25:1
diff --git a/src/test/ui/impl-trait/equality-rpass.stderr b/src/test/ui/impl-trait/equality-rpass.stderr
index 11eeceba0ee..bde8362fdf8 100644
--- a/src/test/ui/impl-trait/equality-rpass.stderr
+++ b/src/test/ui/impl-trait/equality-rpass.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index d4a3495515c..1841b8e5dcd 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0308]: mismatched types
   --> $DIR/equality.rs:15:5
diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr
index 46053c6e7c1..e399a61023d 100644
--- a/src/test/ui/impl-trait/equality2.stderr
+++ b/src/test/ui/impl-trait/equality2.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0308]: mismatched types
   --> $DIR/equality2.rs:25:18
diff --git a/src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs
new file mode 100644
index 00000000000..74df300f85a
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs
@@ -0,0 +1,11 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+pub trait Foo {
+    fn bar() -> impl Sized;
+}
+
+pub struct Foreign;
+
+impl Foo for Foreign {
+    fn bar() {}
+}
diff --git a/src/test/ui/impl-trait/in-trait/foreign.rs b/src/test/ui/impl-trait/in-trait/foreign.rs
new file mode 100644
index 00000000000..6341f5b4284
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/foreign.rs
@@ -0,0 +1,9 @@
+// check-pass
+// aux-build: rpitit.rs
+
+extern crate rpitit;
+
+fn main() {
+    // Witness an RPITIT from another crate
+    let () = <rpitit::Foreign as rpitit::Foo>::bar();
+}
diff --git a/src/test/ui/impl-trait/in-trait/issue-102571.rs b/src/test/ui/impl-trait/in-trait/issue-102571.rs
new file mode 100644
index 00000000000..61c91e64417
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/issue-102571.rs
@@ -0,0 +1,24 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+use std::ops::Deref;
+
+trait Foo {
+    fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
+}
+
+struct A;
+
+impl Foo for A {
+    fn bar(self) -> &'static str {
+        "Hello, world"
+    }
+}
+
+fn foo<T: Foo>(t: T) {
+    let () = t.bar();
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/issue-102571.stderr b/src/test/ui/impl-trait/in-trait/issue-102571.stderr
new file mode 100644
index 00000000000..87219941d91
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/issue-102571.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-102571.rs:20:9
+   |
+LL |     let () = t.bar();
+   |         ^^   ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
+   |         |
+   |         expected associated type, found `()`
+   |
+   = note: expected associated type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
+                    found unit type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/issue-100075-2.stderr b/src/test/ui/impl-trait/issue-100075-2.stderr
index 5a1f1a97d04..d2dbd8c6205 100644
--- a/src/test/ui/impl-trait/issue-100075-2.stderr
+++ b/src/test/ui/impl-trait/issue-100075-2.stderr
@@ -7,8 +7,8 @@ LL | fn opaque<T>(t: T) -> impl Sized {
 LL |     opaque(Some(t))
    |     --------------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/issue-100075-2.rs:1:23
diff --git a/src/test/ui/impl-trait/issue-102605.rs b/src/test/ui/impl-trait/issue-102605.rs
new file mode 100644
index 00000000000..3bbdf35af8f
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-102605.rs
@@ -0,0 +1,15 @@
+// edition:2021
+
+async fn foo() -> Result<(), String> {
+    Ok(())
+}
+
+fn convert_result<T, E>(r: Result<T, E>) -> Option<T> {
+    None
+}
+
+fn main() -> Option<()> {
+    //~^ ERROR `main` has invalid return type `Option<()>`
+    convert_result(foo())
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/impl-trait/issue-102605.stderr b/src/test/ui/impl-trait/issue-102605.stderr
new file mode 100644
index 00000000000..d4aba914908
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-102605.stderr
@@ -0,0 +1,41 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-102605.rs:13:20
+   |
+LL |     convert_result(foo())
+   |     -------------- ^^^^^ expected enum `Result`, found opaque type
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: while checking the return type of the `async fn`
+  --> $DIR/issue-102605.rs:3:19
+   |
+LL | async fn foo() -> Result<(), String> {
+   |                   ^^^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, found opaque type
+   = note:     expected enum `Result<(), _>`
+           found opaque type `impl Future<Output = Result<(), String>>`
+note: function defined here
+  --> $DIR/issue-102605.rs:7:4
+   |
+LL | fn convert_result<T, E>(r: Result<T, E>) -> Option<T> {
+   |    ^^^^^^^^^^^^^^       ---------------
+help: consider `await`ing on the `Future`
+   |
+LL |     convert_result(foo().await)
+   |                         ++++++
+help: try wrapping the expression in `Err`
+   |
+LL |     convert_result(Err(foo()))
+   |                    ++++     +
+
+error[E0277]: `main` has invalid return type `Option<()>`
+  --> $DIR/issue-102605.rs:11:14
+   |
+LL | fn main() -> Option<()> {
+   |              ^^^^^^^^^^ `main` can only return types that implement `Termination`
+   |
+   = help: consider using `()`, or a `Result`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/issue-87450.stderr b/src/test/ui/impl-trait/issue-87450.stderr
index 5019e544bd5..173fca63fa0 100644
--- a/src/test/ui/impl-trait/issue-87450.stderr
+++ b/src/test/ui/impl-trait/issue-87450.stderr
@@ -7,8 +7,8 @@ LL | fn foo() -> impl Fn() {
 LL |     wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
    |                                        ----- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/issue-87450.rs:5:13
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.rs b/src/test/ui/impl-trait/nested-return-type2-tait.rs
index 42613d5ccd9..089018a1cdf 100644
--- a/src/test/ui/impl-trait/nested-return-type2-tait.rs
+++ b/src/test/ui/impl-trait/nested-return-type2-tait.rs
@@ -26,6 +26,7 @@ type Sendable = impl Send;
 // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
 // type does not implement `Duh`, but if its hidden type does.
 fn foo() -> impl Trait<Assoc = Sendable> {
+    //~^ WARN opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
     || 42
 }
 
diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.stderr b/src/test/ui/impl-trait/nested-return-type2-tait.stderr
new file mode 100644
index 00000000000..a8eb69cfcb7
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type2-tait.stderr
@@ -0,0 +1,17 @@
+warning: opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
+  --> $DIR/nested-return-type2-tait.rs:28:24
+   |
+LL |     type Assoc: Duh;
+   |                 --- this associated type bound is unsatisfied for `Sendable`
+...
+LL | fn foo() -> impl Trait<Assoc = Sendable> {
+   |                        ^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
+help: add this bound
+   |
+LL | type Sendable = impl Send + Duh;
+   |                           +++++
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/nested-return-type2.rs b/src/test/ui/impl-trait/nested-return-type2.rs
index 39928d543e1..cc1f1f4ec44 100644
--- a/src/test/ui/impl-trait/nested-return-type2.rs
+++ b/src/test/ui/impl-trait/nested-return-type2.rs
@@ -23,6 +23,7 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
 // Lazy TAIT would error out, but we inserted a hack to make it work again,
 // keeping backwards compatibility.
 fn foo() -> impl Trait<Assoc = impl Send> {
+    //~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
     || 42
 }
 
diff --git a/src/test/ui/impl-trait/nested-return-type2.stderr b/src/test/ui/impl-trait/nested-return-type2.stderr
new file mode 100644
index 00000000000..3aed05ca132
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type2.stderr
@@ -0,0 +1,17 @@
+warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
+  --> $DIR/nested-return-type2.rs:25:24
+   |
+LL |     type Assoc: Duh;
+   |                 --- this associated type bound is unsatisfied for `impl Send`
+...
+LL | fn foo() -> impl Trait<Assoc = impl Send> {
+   |                        ^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
+help: add this bound
+   |
+LL | fn foo() -> impl Trait<Assoc = impl Send + Duh> {
+   |                                          +++++
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/nested-return-type3-tait.rs b/src/test/ui/impl-trait/nested-return-type3-tait.rs
index 3936f4dbbb4..3a97e35b4c4 100644
--- a/src/test/ui/impl-trait/nested-return-type3-tait.rs
+++ b/src/test/ui/impl-trait/nested-return-type3-tait.rs
@@ -17,6 +17,7 @@ impl<F: Duh> Trait for F {
 type Sendable = impl Send;
 
 fn foo() -> impl Trait<Assoc = Sendable> {
+    //~^ WARN opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
     42
 }
 
diff --git a/src/test/ui/impl-trait/nested-return-type3-tait.stderr b/src/test/ui/impl-trait/nested-return-type3-tait.stderr
new file mode 100644
index 00000000000..5f58c8dca4a
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type3-tait.stderr
@@ -0,0 +1,17 @@
+warning: opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds
+  --> $DIR/nested-return-type3-tait.rs:19:24
+   |
+LL |     type Assoc: Duh;
+   |                 --- this associated type bound is unsatisfied for `Sendable`
+...
+LL | fn foo() -> impl Trait<Assoc = Sendable> {
+   |                        ^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
+help: add this bound
+   |
+LL | type Sendable = impl Send + Duh;
+   |                           +++++
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/nested-return-type3-tait2.rs b/src/test/ui/impl-trait/nested-return-type3-tait2.rs
index 56778ed90dc..5b6f78a9896 100644
--- a/src/test/ui/impl-trait/nested-return-type3-tait2.rs
+++ b/src/test/ui/impl-trait/nested-return-type3-tait2.rs
@@ -16,6 +16,7 @@ impl<F: Duh> Trait for F {
 
 type Sendable = impl Send;
 type Traitable = impl Trait<Assoc = Sendable>;
+//~^ WARN opaque type `Traitable` does not satisfy its associated type bounds
 
 fn foo() -> Traitable {
     42
diff --git a/src/test/ui/impl-trait/nested-return-type3-tait2.stderr b/src/test/ui/impl-trait/nested-return-type3-tait2.stderr
new file mode 100644
index 00000000000..c07f6ead750
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type3-tait2.stderr
@@ -0,0 +1,17 @@
+warning: opaque type `Traitable` does not satisfy its associated type bounds
+  --> $DIR/nested-return-type3-tait2.rs:18:29
+   |
+LL |     type Assoc: Duh;
+   |                 --- this associated type bound is unsatisfied for `Sendable`
+...
+LL | type Traitable = impl Trait<Assoc = Sendable>;
+   |                             ^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
+help: add this bound
+   |
+LL | type Sendable = impl Send + Duh;
+   |                           +++++
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/nested-return-type3-tait3.rs b/src/test/ui/impl-trait/nested-return-type3-tait3.rs
index 04c6c92b1a3..394d8f58110 100644
--- a/src/test/ui/impl-trait/nested-return-type3-tait3.rs
+++ b/src/test/ui/impl-trait/nested-return-type3-tait3.rs
@@ -15,6 +15,7 @@ impl<F: Duh> Trait for F {
 }
 
 type Traitable = impl Trait<Assoc = impl Send>;
+//~^ WARN opaque type `Traitable` does not satisfy its associated type bounds
 
 fn foo() -> Traitable {
     42
diff --git a/src/test/ui/impl-trait/nested-return-type3-tait3.stderr b/src/test/ui/impl-trait/nested-return-type3-tait3.stderr
new file mode 100644
index 00000000000..d98ad89222f
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type3-tait3.stderr
@@ -0,0 +1,17 @@
+warning: opaque type `Traitable` does not satisfy its associated type bounds
+  --> $DIR/nested-return-type3-tait3.rs:17:29
+   |
+LL |     type Assoc: Duh;
+   |                 --- this associated type bound is unsatisfied for `impl Send`
+...
+LL | type Traitable = impl Trait<Assoc = impl Send>;
+   |                             ^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
+help: add this bound
+   |
+LL | type Traitable = impl Trait<Assoc = impl Send + Duh>;
+   |                                               +++++
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/nested-return-type3.rs b/src/test/ui/impl-trait/nested-return-type3.rs
index 74b4dae22eb..5a764fc4c28 100644
--- a/src/test/ui/impl-trait/nested-return-type3.rs
+++ b/src/test/ui/impl-trait/nested-return-type3.rs
@@ -13,6 +13,7 @@ impl<F: Duh> Trait for F {
 }
 
 fn foo() -> impl Trait<Assoc = impl Send> {
+    //~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
     42
 }
 
diff --git a/src/test/ui/impl-trait/nested-return-type3.stderr b/src/test/ui/impl-trait/nested-return-type3.stderr
new file mode 100644
index 00000000000..632de71aa4c
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type3.stderr
@@ -0,0 +1,17 @@
+warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
+  --> $DIR/nested-return-type3.rs:15:24
+   |
+LL |     type Assoc: Duh;
+   |                 --- this associated type bound is unsatisfied for `impl Send`
+...
+LL | fn foo() -> impl Trait<Assoc = impl Send> {
+   |                        ^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(opaque_hidden_inferred_bound)]` on by default
+help: add this bound
+   |
+LL | fn foo() -> impl Trait<Assoc = impl Send + Duh> {
+   |                                          +++++
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 9b346387d61..2e7c7ca40dd 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -301,9 +301,9 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^
    |
-   = note: `#[deny(invalid_type_param_default)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
   --> $DIR/where-allowed.rs:241:36
diff --git a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr
index 3c20f552fdf..2c1965ac0a4 100644
--- a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr
+++ b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr
@@ -4,7 +4,6 @@ error: macro-expanded `macro_export` macros from the current crate cannot be ref
 LL |     use exported;
    |         ^^^^^^^^
    |
-   = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
 note: the macro is defined here
@@ -17,6 +16,7 @@ LL | |     }
 ...
 LL |   define_exported!();
    |   ------------------ in this macro invocation
+   = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
    = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr
index c38f57912ad..3dea09e7f52 100644
--- a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr
+++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr
@@ -4,9 +4,9 @@ warning: type annotations needed
 LL |     if data.is_null() {}
    |             ^^^^^^^
    |
-   = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
+   = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/inference/inference_unstable.stderr b/src/test/ui/inference/inference_unstable.stderr
index df7a09686bf..ecbf2641bec 100644
--- a/src/test/ui/inference/inference_unstable.stderr
+++ b/src/test/ui/inference/inference_unstable.stderr
@@ -4,11 +4,11 @@ warning: an associated function with this name may be added to the standard libr
 LL |     assert_eq!('x'.ipu_flatten(), 1);
    |                    ^^^^^^^^^^^
    |
-   = note: `#[warn(unstable_name_collisions)]` on by default
    = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
    = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
    = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method
    = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten`
+   = note: `#[warn(unstable_name_collisions)]` on by default
 
 warning: an associated function with this name may be added to the standard library in the future
   --> $DIR/inference_unstable.rs:19:20
diff --git a/src/test/ui/inference/need_type_info/concrete-impl.stderr b/src/test/ui/inference/need_type_info/concrete-impl.stderr
index b79d34affa2..aa32969950d 100644
--- a/src/test/ui/inference/need_type_info/concrete-impl.stderr
+++ b/src/test/ui/inference/need_type_info/concrete-impl.stderr
@@ -3,11 +3,6 @@ error[E0282]: type annotations needed
    |
 LL |     <Struct as Ambiguous<_>>::method();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
-   |
-help: consider specifying the generic argument
-   |
-LL |     <Struct as Ambiguous::<_>>::method();
-   |                         ~~~~~
 
 error[E0283]: type annotations needed
   --> $DIR/concrete-impl.rs:13:5
@@ -22,10 +17,6 @@ LL | impl Ambiguous<One> for Struct {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL | impl Ambiguous<Two> for Struct {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: consider specifying the generic argument
-   |
-LL |     <Struct as Ambiguous::<_>>::method();
-   |                         ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
new file mode 100644
index 00000000000..3084f6eac67
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs
@@ -0,0 +1,11 @@
+enum OhNo<T, U> {
+    A(T),
+    B(U),
+    C,
+}
+
+fn uwu() {
+    OhNo::C::<u32, _>; //~ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr
new file mode 100644
index 00000000000..2ad35ab039f
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/do-not-suggest-generic-arguments-for-turbofish.rs:8:5
+   |
+LL |     OhNo::C::<u32, _>;
+   |     ^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the enum `OhNo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs
index 6007eba8c09..c8b1ff1dbce 100644
--- a/src/test/ui/intrinsics/intrinsic-alignment.rs
+++ b/src/test/ui/intrinsics/intrinsic-alignment.rs
@@ -6,6 +6,7 @@
 mod rusti {
     extern "rust-intrinsic" {
         pub fn pref_align_of<T>() -> usize;
+        #[rustc_safe_intrinsic]
         pub fn min_align_of<T>() -> usize;
     }
 }
diff --git a/src/test/ui/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs
index bac6c8d872b..88bf42b685f 100644
--- a/src/test/ui/intrinsics/intrinsics-integer.rs
+++ b/src/test/ui/intrinsics/intrinsics-integer.rs
@@ -1,15 +1,21 @@
 // run-pass
 
 #![feature(intrinsics)]
+#![feature(rustc_attrs)]
 
 mod rusti {
     extern "rust-intrinsic" {
+        #[rustc_safe_intrinsic]
         pub fn ctpop<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn ctlz<T>(x: T) -> T;
         pub fn ctlz_nonzero<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn cttz<T>(x: T) -> T;
         pub fn cttz_nonzero<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn bswap<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn bitreverse<T>(x: T) -> T;
     }
 }
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index 4aa869cca35..ae44ffd29bd 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -34,6 +34,12 @@ enum OneVariant_NonZero {
     DeadVariant(Bar),
 }
 
+#[allow(dead_code, non_camel_case_types)]
+enum OneVariant_Ref {
+    Variant(&'static i32),
+    DeadVariant(Bar),
+}
+
 // An `Aggregate` abi enum where 0 is not a valid discriminant.
 #[allow(dead_code)]
 #[repr(i32)]
@@ -63,6 +69,7 @@ enum ZeroIsValid {
     One(NonNull<()>) = 1,
 }
 
+#[track_caller]
 fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
     let err = panic::catch_unwind(op).err();
     assert_eq!(
@@ -71,6 +78,15 @@ fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
     );
 }
 
+#[track_caller]
+fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
+    let err = panic::catch_unwind(op).err();
+    assert_eq!(
+        err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
+        if cfg!(strict) { Some(&msg) } else { None },
+    );
+}
+
 fn main() {
     unsafe {
         // Uninhabited types
@@ -139,92 +155,216 @@ fn main() {
             "attempted to instantiate uninhabited type `[Bar; 2]`"
         );
 
-        // Types that do not like zero-initialziation
+        // Types that don't allow either.
         test_panic_msg(
-            || mem::uninitialized::<fn()>(),
-            "attempted to leave type `fn()` uninitialized, which is invalid"
+            || mem::zeroed::<&i32>(),
+            "attempted to zero-initialize type `&i32`, which is invalid"
         );
         test_panic_msg(
-            || mem::zeroed::<fn()>(),
-            "attempted to zero-initialize type `fn()`, which is invalid"
+            || mem::uninitialized::<&i32>(),
+            "attempted to leave type `&i32` uninitialized, which is invalid"
         );
 
         test_panic_msg(
-            || mem::uninitialized::<*const dyn Send>(),
-            "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
+            || mem::zeroed::<Box<[i32; 0]>>(),
+            "attempted to zero-initialize type `alloc::boxed::Box<[i32; 0]>`, which is invalid"
+        );
+        test_panic_msg(
+            || mem::uninitialized::<Box<[i32; 0]>>(),
+            "attempted to leave type `alloc::boxed::Box<[i32; 0]>` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<Box<u8>>(),
+            "attempted to zero-initialize type `alloc::boxed::Box<u8>`, which is invalid"
         );
         test_panic_msg(
+            || mem::uninitialized::<Box<u8>>(),
+            "attempted to leave type `alloc::boxed::Box<u8>` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<&[i32]>(),
+            "attempted to zero-initialize type `&[i32]`, which is invalid"
+        );
+        test_panic_msg(
+            || mem::uninitialized::<&[i32]>(),
+            "attempted to leave type `&[i32]` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<&(u8, [u8])>(),
+            "attempted to zero-initialize type `&(u8, [u8])`, which is invalid"
+        );
+        test_panic_msg(
+            || mem::uninitialized::<&(u8, [u8])>(),
+            "attempted to leave type `&(u8, [u8])` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<&dyn Send>(),
+            "attempted to zero-initialize type `&dyn core::marker::Send`, which is invalid"
+        );
+        test_panic_msg(
+            || mem::uninitialized::<&dyn Send>(),
+            "attempted to leave type `&dyn core::marker::Send` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
             || mem::zeroed::<*const dyn Send>(),
             "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
         );
+        test_panic_msg(
+            || mem::uninitialized::<*const dyn Send>(),
+            "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
+        );
 
         test_panic_msg(
-            || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
-            "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
+            || mem::uninitialized::<NoNullVariant>(),
+            "attempted to leave type `NoNullVariant` uninitialized, \
+                which is invalid"
+        );
+        test_panic_msg(
+            || mem::zeroed::<NoNullVariant>(),
+            "attempted to zero-initialize type `NoNullVariant`, \
                 which is invalid"
         );
 
         test_panic_msg(
-            || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
-            "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
+            || mem::zeroed::<OneVariant_Ref>(),
+            "attempted to zero-initialize type `OneVariant_Ref`, \
                 which is invalid"
         );
+        test_panic_msg(
+            || mem::uninitialized::<OneVariant_Ref>(),
+            "attempted to leave type `OneVariant_Ref` uninitialized, which is invalid"
+        );
 
+        // Types where both are invalid, but we allow uninit since the 0x01-filling is not LLVM UB.
         test_panic_msg(
-            || mem::uninitialized::<OneVariant_NonZero>(),
-            "attempted to leave type `OneVariant_NonZero` uninitialized, \
+            || mem::zeroed::<fn()>(),
+            "attempted to zero-initialize type `fn()`, which is invalid"
+        );
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<fn()>(),
+            "attempted to leave type `fn()` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<&()>(),
+            "attempted to zero-initialize type `&()`, which is invalid"
+        );
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<&()>(),
+            "attempted to leave type `&()` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<&[u8]>(),
+            "attempted to zero-initialize type `&[u8]`, which is invalid"
+        );
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<&[u8]>(),
+            "attempted to leave type `&[u8]` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<&str>(),
+            "attempted to zero-initialize type `&str`, which is invalid"
+        );
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<&str>(),
+            "attempted to leave type `&str` uninitialized, which is invalid"
+        );
+
+        test_panic_msg(
+            || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
+            "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
                 which is invalid"
         );
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
+            "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, which is invalid"
+        );
+
         test_panic_msg(
             || mem::zeroed::<OneVariant_NonZero>(),
             "attempted to zero-initialize type `OneVariant_NonZero`, \
                 which is invalid"
         );
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<OneVariant_NonZero>(),
+            "attempted to leave type `OneVariant_NonZero` uninitialized, which is invalid"
+        );
 
+        // Types where both are invalid but we allow the zeroed form since it is not LLVM UB.
+        test_panic_msg_only_if_strict(
+            || mem::zeroed::<LR_NonZero>(),
+            "attempted to zero-initialize type `LR_NonZero`, which is invalid"
+        );
         test_panic_msg(
             || mem::uninitialized::<LR_NonZero>(),
             "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
         );
 
+        test_panic_msg_only_if_strict(
+            || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
+            "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
+             which is invalid"
+        );
         test_panic_msg(
             || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
             "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>` uninitialized, \
              which is invalid"
         );
 
-        test_panic_msg(
-            || mem::uninitialized::<NoNullVariant>(),
-            "attempted to leave type `NoNullVariant` uninitialized, \
-                which is invalid"
+        // Some strict-only things
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<i32>(),
+            "attempted to leave type `i32` uninitialized, which is invalid"
         );
 
-        test_panic_msg(
-            || mem::zeroed::<NoNullVariant>(),
-            "attempted to zero-initialize type `NoNullVariant`, \
-                which is invalid"
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<*const ()>(),
+            "attempted to leave type `*const ()` uninitialized, which is invalid"
         );
 
-        // Types that can be zero, but not uninit.
-        test_panic_msg(
-            || mem::uninitialized::<bool>(),
-            "attempted to leave type `bool` uninitialized, which is invalid"
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<[i32; 1]>(),
+            "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
         );
 
+        test_panic_msg_only_if_strict(
+            || mem::zeroed::<[NonNull<()>; 1]>(),
+            "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
+        );
+
+        // Types that can be zero, but not uninit (though some are mitigated).
+        let _val = mem::zeroed::<LR>();
         test_panic_msg(
             || mem::uninitialized::<LR>(),
             "attempted to leave type `LR` uninitialized, which is invalid"
         );
 
+        let _val = mem::zeroed::<ManuallyDrop<LR>>();
         test_panic_msg(
             || mem::uninitialized::<ManuallyDrop<LR>>(),
             "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
         );
 
-        // Some things that should work.
         let _val = mem::zeroed::<bool>();
-        let _val = mem::zeroed::<LR>();
-        let _val = mem::zeroed::<ManuallyDrop<LR>>();
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<bool>(),
+            "attempted to leave type `bool` uninitialized, which is invalid"
+        );
+
         let _val = mem::zeroed::<OneVariant>();
+        test_panic_msg_only_if_strict(
+            || mem::uninitialized::<OneVariant>(),
+            "attempted to leave type `OneVariant` uninitialized, which is invalid"
+        );
+
+        // Some things that are actually allowed.
         let _val = mem::zeroed::<Option<&'static i32>>();
         let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
         let _val = mem::zeroed::<[!; 0]>();
@@ -233,59 +373,5 @@ fn main() {
         let _val = mem::uninitialized::<[!; 0]>();
         let _val = mem::uninitialized::<()>();
         let _val = mem::uninitialized::<ZeroSized>();
-
-        if cfg!(strict) {
-            test_panic_msg(
-                || mem::uninitialized::<i32>(),
-                "attempted to leave type `i32` uninitialized, which is invalid"
-            );
-
-            test_panic_msg(
-                || mem::uninitialized::<*const ()>(),
-                "attempted to leave type `*const ()` uninitialized, which is invalid"
-            );
-
-            test_panic_msg(
-                || mem::uninitialized::<[i32; 1]>(),
-                "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
-            );
-
-            test_panic_msg(
-                || mem::zeroed::<NonNull<()>>(),
-                "attempted to zero-initialize type `core::ptr::non_null::NonNull<()>`, which is invalid"
-            );
-
-            test_panic_msg(
-                || mem::zeroed::<[NonNull<()>; 1]>(),
-                "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
-            );
-
-            // FIXME(#66151) we conservatively do not error here yet (by default).
-            test_panic_msg(
-                || mem::zeroed::<LR_NonZero>(),
-                "attempted to zero-initialize type `LR_NonZero`, which is invalid"
-            );
-
-            test_panic_msg(
-                || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
-                "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
-                 which is invalid"
-            );
-        } else {
-            // These are UB because they have not been officially blessed, but we await the resolution
-            // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
-            // anything about that.
-            let _val = mem::uninitialized::<i32>();
-            let _val = mem::uninitialized::<*const ()>();
-
-            // These are UB, but best to test them to ensure we don't become unintentionally
-            // stricter.
-
-            // It's currently unchecked to create invalid enums and values inside arrays.
-            let _val = mem::zeroed::<LR_NonZero>();
-            let _val = mem::zeroed::<[LR_NonZero; 1]>();
-            let _val = mem::zeroed::<[NonNull<()>; 1]>();
-            let _val = mem::uninitialized::<[NonNull<()>; 1]>();
-        }
     }
 }
diff --git a/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs b/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs
new file mode 100644
index 00000000000..50e12eaeb5c
--- /dev/null
+++ b/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs
@@ -0,0 +1,11 @@
+#![feature(intrinsics)]
+#![feature(rustc_attrs)]
+
+extern "rust-intrinsic" {
+    fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch
+
+    #[rustc_safe_intrinsic]
+    fn assume(b: bool); //~ ERROR intrinsic safety mismatch
+}
+
+fn main() {}
diff --git a/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr b/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr
new file mode 100644
index 00000000000..0c2f3be491d
--- /dev/null
+++ b/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr
@@ -0,0 +1,14 @@
+error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
+  --> $DIR/safe-intrinsic-mismatch.rs:5:5
+   |
+LL |     fn size_of<T>() -> usize;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
+  --> $DIR/safe-intrinsic-mismatch.rs:8:5
+   |
+LL |     fn assume(b: bool);
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issues/issue-11958.stderr b/src/test/ui/issues/issue-11958.stderr
index 25de6ff4c11..5dca4c2f01d 100644
--- a/src/test/ui/issues/issue-11958.stderr
+++ b/src/test/ui/issues/issue-11958.stderr
@@ -4,8 +4,8 @@ warning: value assigned to `x` is never read
 LL |     let _thunk = Box::new(move|| { x = 2; });
    |                                    ^
    |
-   = note: `#[warn(unused_assignments)]` on by default
    = help: maybe it is overwritten before being read?
+   = note: `#[warn(unused_assignments)]` on by default
 
 warning: unused variable: `x`
   --> $DIR/issue-11958.rs:8:36
@@ -13,8 +13,8 @@ warning: unused variable: `x`
 LL |     let _thunk = Box::new(move|| { x = 2; });
    |                                    ^
    |
-   = note: `#[warn(unused_variables)]` on by default
    = help: did you mean to capture by reference instead?
+   = note: `#[warn(unused_variables)]` on by default
 
 warning: 2 warnings emitted
 
diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr
index 26f95f5af3d..f0ff2cafd44 100644
--- a/src/test/ui/issues/issue-1460.stderr
+++ b/src/test/ui/issues/issue-1460.stderr
@@ -4,8 +4,8 @@ warning: unused closure that must be used
 LL |     {|i: u32| if 1 == i { }};
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: closures are lazy and do nothing unless called
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/issues/issue-16250.stderr b/src/test/ui/issues/issue-16250.stderr
index ae3b7f334c6..5eb5e0864ad 100644
--- a/src/test/ui/issues/issue-16250.stderr
+++ b/src/test/ui/issues/issue-16250.stderr
@@ -4,12 +4,6 @@ error: `extern` block uses type `Foo`, which is not FFI-safe
 LL |     pub fn foo(x: (Foo));
    |                    ^^^ not FFI-safe
    |
-note: the lint level is defined here
-  --> $DIR/issue-16250.rs:1:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]`
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
@@ -17,6 +11,12 @@ note: the type is defined here
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/issue-16250.rs:1:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr
index 9c7312461c4..ca8e9a1bed3 100644
--- a/src/test/ui/issues/issue-16256.stderr
+++ b/src/test/ui/issues/issue-16256.stderr
@@ -4,8 +4,8 @@ warning: unused closure that must be used
 LL |     |c: u8| buf.push(c);
    |     ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: closures are lazy and do nothing unless called
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/issues/issue-24013.stderr b/src/test/ui/issues/issue-24013.stderr
index 995dce552e3..72102f460e0 100644
--- a/src/test/ui/issues/issue-24013.stderr
+++ b/src/test/ui/issues/issue-24013.stderr
@@ -3,11 +3,6 @@ error[E0282]: type annotations needed
    |
 LL |     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
    |             ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap`
-   |
-help: consider specifying the generic argument
-   |
-LL |     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
-   |                 ~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr
index 85a8698afc5..f398a5da3e9 100644
--- a/src/test/ui/issues/issue-28344.stderr
+++ b/src/test/ui/issues/issue-28344.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
    |                 ^^^^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL |     let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
diff --git a/src/test/ui/issues/issue-47094.stderr b/src/test/ui/issues/issue-47094.stderr
index e323ce66029..970e3184710 100644
--- a/src/test/ui/issues/issue-47094.stderr
+++ b/src/test/ui/issues/issue-47094.stderr
@@ -4,9 +4,9 @@ error[E0566]: conflicting representation hints
 LL | #[repr(C, u8)]
    |        ^  ^^
    |
-   = note: `#[deny(conflicting_repr_hints)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
+   = note: `#[deny(conflicting_repr_hints)]` on by default
 
 error[E0566]: conflicting representation hints
   --> $DIR/issue-47094.rs:8:8
diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr
index b45f57b7b84..2bd24f08c1e 100644
--- a/src/test/ui/issues/issue-47486.stderr
+++ b/src/test/ui/issues/issue-47486.stderr
@@ -9,11 +9,6 @@ error[E0282]: type annotations needed
    |
 LL |     [0u8; std::mem::size_of::<_>()];
    |           ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `size_of`
-   |
-help: consider specifying the generic argument
-   |
-LL |     [0u8; std::mem::size_of::<_>()];
-   |                            ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-47725.stderr b/src/test/ui/issues/issue-47725.stderr
index c7a9bfe317f..7143fb4d6e1 100644
--- a/src/test/ui/issues/issue-47725.stderr
+++ b/src/test/ui/issues/issue-47725.stderr
@@ -13,12 +13,12 @@ LL | #[link_name = "foo"]
 LL | struct Foo;
    | ----------- not a foreign function or static
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 note: the lint level is defined here
   --> $DIR/issue-47725.rs:1:9
    |
 LL | #![warn(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
   --> $DIR/issue-47725.rs:8:1
diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr
index 93bd951d3fa..e185ecdda23 100644
--- a/src/test/ui/issues/issue-50781.stderr
+++ b/src/test/ui/issues/issue-50781.stderr
@@ -4,11 +4,6 @@ error: the trait `X` cannot be made into an object
 LL |     fn foo(&self) where Self: Trait;
    |        ^^^
    |
-note: the lint level is defined here
-  --> $DIR/issue-50781.rs:1:9
-   |
-LL | #![deny(where_clauses_object_safety)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
@@ -19,6 +14,11 @@ LL | trait X {
 LL |     fn foo(&self) where Self: Trait;
    |        ^^^ ...because method `foo` references the `Self` type in its `where` clause
    = help: consider moving `foo` to another trait
+note: the lint level is defined here
+  --> $DIR/issue-50781.rs:1:9
+   |
+LL | #![deny(where_clauses_object_safety)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-54044.stderr b/src/test/ui/issues/issue-54044.stderr
index 100965de1aa..8bd94a041d0 100644
--- a/src/test/ui/issues/issue-54044.stderr
+++ b/src/test/ui/issues/issue-54044.stderr
@@ -7,12 +7,12 @@ LL | #[cold]
 LL | struct Foo;
    | ----------- not a function definition
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 note: the lint level is defined here
   --> $DIR/issue-54044.rs:1:9
    |
 LL | #![deny(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: attribute should be applied to a function definition
   --> $DIR/issue-54044.rs:9:5
diff --git a/src/test/ui/issues/issue-55380.stderr b/src/test/ui/issues/issue-55380.stderr
index 65e94d79670..403844c726f 100644
--- a/src/test/ui/issues/issue-55380.stderr
+++ b/src/test/ui/issues/issue-55380.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/issues/issue-58734.stderr b/src/test/ui/issues/issue-58734.stderr
index a91a1b3778e..d2314626d3e 100644
--- a/src/test/ui/issues/issue-58734.stderr
+++ b/src/test/ui/issues/issue-58734.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     Trait::nonexistent(());
    |     ^^^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL |     <dyn Trait>::nonexistent(());
diff --git a/src/test/ui/issues/issue-60622.stderr b/src/test/ui/issues/issue-60622.stderr
index b305cc78535..ecf1ae758dd 100644
--- a/src/test/ui/issues/issue-60622.stderr
+++ b/src/test/ui/issues/issue-60622.stderr
@@ -7,14 +7,14 @@ LL |     fn a(&self) {}
 LL |     b.a::<'_, T>();
    |           ^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
 note: the lint level is defined here
   --> $DIR/issue-60622.rs:1:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
 
 error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-60622.rs:10:7
diff --git a/src/test/ui/issues/issue-6458-4.stderr b/src/test/ui/issues/issue-6458-4.stderr
index d6e74d10e03..168ececac31 100644
--- a/src/test/ui/issues/issue-6458-4.stderr
+++ b/src/test/ui/issues/issue-6458-4.stderr
@@ -6,7 +6,7 @@ LL | fn foo(b: bool) -> Result<bool,String> {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 LL |     Err("bar".to_string());
-   |                           - help: remove this semicolon
+   |                           - help: remove this semicolon to return this value
    |
    = note:   expected enum `Result<bool, String>`
            found unit type `()`
diff --git a/src/test/ui/issues/issue-72278.stderr b/src/test/ui/issues/issue-72278.stderr
index 41dff686bc4..5468837a305 100644
--- a/src/test/ui/issues/issue-72278.stderr
+++ b/src/test/ui/issues/issue-72278.stderr
@@ -7,9 +7,9 @@ LL |     fn func<'a, U>(&'a self) -> U {
 LL |     S.func::<'a, U>()
    |              ^^
    |
-   = note: `#[warn(late_bound_lifetime_arguments)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
+   = note: `#[warn(late_bound_lifetime_arguments)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/issues/issue-78957.stderr b/src/test/ui/issues/issue-78957.stderr
index 45fa69d6fd7..6de22d6bf79 100644
--- a/src/test/ui/issues/issue-78957.stderr
+++ b/src/test/ui/issues/issue-78957.stderr
@@ -10,12 +10,12 @@ error: attribute should be applied to a function definition
 LL | pub struct Bar<#[cold] const N: usize>;
    |                ^^^^^^^ -------------- not a function definition
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 note: the lint level is defined here
   --> $DIR/issue-78957.rs:1:9
    |
 LL | #![deny(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error[E0517]: attribute should be applied to a struct, enum, or union
   --> $DIR/issue-78957.rs:10:23
diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr
index b26c1834d84..693cfecedc4 100644
--- a/src/test/ui/issues/issue-86756.stderr
+++ b/src/test/ui/issues/issue-86756.stderr
@@ -20,9 +20,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     eq::<dyn, Foo>
    |               ^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL |     eq::<dyn, dyn Foo>
diff --git a/src/test/ui/issues/issue-8727.stderr b/src/test/ui/issues/issue-8727.stderr
index 10daba5ef3d..5e1fdad60cb 100644
--- a/src/test/ui/issues/issue-8727.stderr
+++ b/src/test/ui/issues/issue-8727.stderr
@@ -6,8 +6,8 @@ LL | fn generic<T>() {
 LL |     generic::<Option<T>>();
    |     ---------------------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
   --> $DIR/issue-8727.rs:8:5
diff --git a/src/test/ui/iterators/into-iter-on-arrays-2018.stderr b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
index 9b312505837..2378476e5d0 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
+++ b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
@@ -4,9 +4,9 @@ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (du
 LL |     let _: Iter<'_, i32> = array.into_iter();
    |                                  ^^^^^^^^^
    |
-   = note: `#[warn(array_into_iter)]` on by default
    = warning: this changes meaning in Rust 2021
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+   = note: `#[warn(array_into_iter)]` on by default
 help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
 LL |     let _: Iter<'_, i32> = array.iter();
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
index e32d35d8638..2fde276faa3 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
@@ -4,9 +4,9 @@ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (du
 LL |     small.into_iter();
    |           ^^^^^^^^^
    |
-   = note: `#[warn(array_into_iter)]` on by default
    = warning: this changes meaning in Rust 2021
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+   = note: `#[warn(array_into_iter)]` on by default
 help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
 LL |     small.iter();
diff --git a/src/test/ui/lang-items/issue-83471.stderr b/src/test/ui/lang-items/issue-83471.stderr
index 6d796fe7f50..fc9ab293f99 100644
--- a/src/test/ui/lang-items/issue-83471.stderr
+++ b/src/test/ui/lang-items/issue-83471.stderr
@@ -32,9 +32,9 @@ warning: anonymous parameters are deprecated and will be removed in the next edi
 LL |     fn call(export_name);
    |             ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name`
    |
-   = note: `#[warn(anonymous_parameters)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+   = note: `#[warn(anonymous_parameters)]` on by default
 
 error[E0718]: `fn` language item must be applied to a trait with 1 generic argument
   --> $DIR/issue-83471.rs:11:1
diff --git a/src/test/ui/let-else/let-else-irrefutable.stderr b/src/test/ui/let-else/let-else-irrefutable.stderr
index e030c50d45d..e0581f4d9ab 100644
--- a/src/test/ui/let-else/let-else-irrefutable.stderr
+++ b/src/test/ui/let-else/let-else-irrefutable.stderr
@@ -4,9 +4,9 @@ warning: irrefutable `let...else` pattern
 LL |     let x = 1 else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(irrefutable_let_patterns)]` on by default
    = note: this pattern will always match, so the `else` clause is useless
    = help: consider removing the `else` clause
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr
index 6c3683d7896..4f165b1d9fe 100644
--- a/src/test/ui/limits/issue-55878.stderr
+++ b/src/test/ui/limits/issue-55878.stderr
@@ -15,9 +15,9 @@ error: erroneous constant used
 LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
@@ -30,8 +30,8 @@ error: erroneous constant used
 LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/linkage-attr/link-attr-validation-early.stderr b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
index 903141e439d..24ad9d825f8 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-early.stderr
+++ b/src/test/ui/linkage-attr/link-attr-validation-early.stderr
@@ -4,9 +4,9 @@ error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib
 LL | #[link]
    | ^^^^^^^
    |
-   = note: `#[deny(ill_formed_attribute_input)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]`
   --> $DIR/link-attr-validation-early.rs:4:1
diff --git a/src/test/ui/lint/auxiliary/trivial-cast-ice.rs b/src/test/ui/lint/auxiliary/trivial-cast-ice.rs
new file mode 100644
index 00000000000..ab2332d0656
--- /dev/null
+++ b/src/test/ui/lint/auxiliary/trivial-cast-ice.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! foo {
+    () => {
+        let x: &Option<i32> = &Some(1);
+        let _y = x as *const Option<i32>;
+    }
+}
diff --git a/src/test/ui/lint/bare-trait-objects-path.stderr b/src/test/ui/lint/bare-trait-objects-path.stderr
index 4b8c2b539d5..8ed303ca606 100644
--- a/src/test/ui/lint/bare-trait-objects-path.stderr
+++ b/src/test/ui/lint/bare-trait-objects-path.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let _: Dyn::Ty;
    |            ^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL |     let _: <dyn Dyn>::Ty;
diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr
index 4607f684993..217eed6c92c 100644
--- a/src/test/ui/lint/clashing-extern-fn.stderr
+++ b/src/test/ui/lint/clashing-extern-fn.stderr
@@ -7,13 +7,13 @@ LL |             fn clash(x: u8);
 LL |             fn clash(x: u64);
    |             ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
+   = note: expected `unsafe extern "C" fn(u8)`
+              found `unsafe extern "C" fn(u64)`
 note: the lint level is defined here
   --> $DIR/clashing-extern-fn.rs:4:9
    |
 LL | #![warn(clashing_extern_declarations)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `unsafe extern "C" fn(u8)`
-              found `unsafe extern "C" fn(u64)`
 
 warning: `extern_link_name` redeclared with a different signature
   --> $DIR/clashing-extern-fn.rs:52:9
@@ -219,9 +219,9 @@ warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI
 LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
    |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
-   = note: `#[warn(improper_ctypes)]` on by default
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
+   = note: `#[warn(improper_ctypes)]` on by default
 
 warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
   --> $DIR/clashing-extern-fn.rs:412:46
diff --git a/src/test/ui/lint/cli-lint-override.forbid_warn.stderr b/src/test/ui/lint/cli-lint-override.forbid_warn.stderr
index ff4dc4abc74..d1c66a81cd8 100644
--- a/src/test/ui/lint/cli-lint-override.forbid_warn.stderr
+++ b/src/test/ui/lint/cli-lint-override.forbid_warn.stderr
@@ -4,8 +4,8 @@ error: extern declarations without an explicit ABI are deprecated
 LL | extern fn foo() {}
    | ^^^^^^^^^^^^^^^ ABI should be specified here
    |
-   = note: requested on the command line with `-F missing-abi`
    = help: the default ABI is C
+   = note: requested on the command line with `-F missing-abi`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr b/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr
index 74e7823e1ff..779c24c93f2 100644
--- a/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr
+++ b/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr
@@ -4,8 +4,8 @@ warning: extern declarations without an explicit ABI are deprecated
 LL | extern fn foo() {}
    | ^^^^^^^^^^^^^^^ ABI should be specified here
    |
-   = note: requested on the command line with `--force-warn missing-abi`
    = help: the default ABI is C
+   = note: requested on the command line with `--force-warn missing-abi`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/cli-lint-override.warn_deny.stderr b/src/test/ui/lint/cli-lint-override.warn_deny.stderr
index 2d869adfd37..f034cfa9338 100644
--- a/src/test/ui/lint/cli-lint-override.warn_deny.stderr
+++ b/src/test/ui/lint/cli-lint-override.warn_deny.stderr
@@ -4,8 +4,8 @@ error: extern declarations without an explicit ABI are deprecated
 LL | extern fn foo() {}
    | ^^^^^^^^^^^^^^^ ABI should be specified here
    |
-   = note: requested on the command line with `-D missing-abi`
    = help: the default ABI is C
+   = note: requested on the command line with `-D missing-abi`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/dead-code/issue-85071-2.stderr b/src/test/ui/lint/dead-code/issue-85071-2.stderr
index 86fbd1d75e8..5e963183d09 100644
--- a/src/test/ui/lint/dead-code/issue-85071-2.stderr
+++ b/src/test/ui/lint/dead-code/issue-85071-2.stderr
@@ -7,16 +7,16 @@ LL |
 LL |     let _y = x;
    |         ^^ unreachable definition
    |
-note: the lint level is defined here
-  --> $DIR/issue-85071-2.rs:7:26
-   |
-LL | #![warn(unused_variables,unreachable_code)]
-   |                          ^^^^^^^^^^^^^^^^
 note: this expression has type `Foo`, which is uninhabited
   --> $DIR/issue-85071-2.rs:18:13
    |
 LL |     let x = s.f();
    |             ^^^^^
+note: the lint level is defined here
+  --> $DIR/issue-85071-2.rs:7:26
+   |
+LL | #![warn(unused_variables,unreachable_code)]
+   |                          ^^^^^^^^^^^^^^^^
 
 warning: unused variable: `x`
   --> $DIR/issue-85071-2.rs:18:9
diff --git a/src/test/ui/lint/dead-code/issue-85071.stderr b/src/test/ui/lint/dead-code/issue-85071.stderr
index 49555fdaa35..721fb8148d9 100644
--- a/src/test/ui/lint/dead-code/issue-85071.stderr
+++ b/src/test/ui/lint/dead-code/issue-85071.stderr
@@ -7,16 +7,16 @@ LL |
 LL |     let _ = x;
    |             ^ unreachable expression
    |
-note: the lint level is defined here
-  --> $DIR/issue-85071.rs:9:26
-   |
-LL | #![warn(unused_variables,unreachable_code)]
-   |                          ^^^^^^^^^^^^^^^^
 note: this expression has type `Foo`, which is uninhabited
   --> $DIR/issue-85071.rs:15:13
    |
 LL |     let x = f();
    |             ^^^
+note: the lint level is defined here
+  --> $DIR/issue-85071.rs:9:26
+   |
+LL | #![warn(unused_variables,unreachable_code)]
+   |                          ^^^^^^^^^^^^^^^^
 
 warning: unused variable: `x`
   --> $DIR/issue-85071.rs:15:9
diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr
index a68f64775ad..6029bf26856 100644
--- a/src/test/ui/lint/dead-code/unused-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-variant.stderr
@@ -6,12 +6,12 @@ LL | enum Enum {
 LL |     Variant1,
    |     ^^^^^^^^
    |
+   = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
 note: the lint level is defined here
   --> $DIR/unused-variant.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
-   = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/deny-overflowing-literals.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr
index 127dd4127c2..beb0ad79560 100644
--- a/src/test/ui/lint/deny-overflowing-literals.stderr
+++ b/src/test/ui/lint/deny-overflowing-literals.stderr
@@ -4,8 +4,8 @@ error: literal out of range for `u8`
 LL |     let x: u8 = 256;
    |                 ^^^
    |
-   = note: `#[deny(overflowing_literals)]` on by default
    = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
+   = note: `#[deny(overflowing_literals)]` on by default
 
 error: range endpoint is out of range for `u8`
   --> $DIR/deny-overflowing-literals.rs:5:14
diff --git a/src/test/ui/lint/expansion-time.stderr b/src/test/ui/lint/expansion-time.stderr
index b0fc1f8e5ee..064ee5fadb1 100644
--- a/src/test/ui/lint/expansion-time.stderr
+++ b/src/test/ui/lint/expansion-time.stderr
@@ -18,13 +18,13 @@ warning: missing fragment specifier
 LL | macro_rules! m { ($i) => {} }
    |                   ^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 note: the lint level is defined here
   --> $DIR/expansion-time.rs:8:8
    |
 LL | #[warn(missing_fragment_specifier)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 
 warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
   --> $DIR/expansion-time.rs:14:7
@@ -32,13 +32,13 @@ warning: use of unstable library feature 'test': `bench` is a part of custom tes
 LL |     #[bench]
    |       ^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
 note: the lint level is defined here
   --> $DIR/expansion-time.rs:12:8
    |
 LL | #[warn(soft_unstable)]
    |        ^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
 
 warning: include macro expected single expression in source
   --> $DIR/expansion-time-include.rs:4:1
diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr
index 61b7993d2ae..2805720f035 100644
--- a/src/test/ui/lint/fn_must_use.stderr
+++ b/src/test/ui/lint/fn_must_use.stderr
@@ -4,12 +4,12 @@ warning: unused return value of `need_to_use_this_value` that must be used
 LL |     need_to_use_this_value();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: it's important
 note: the lint level is defined here
   --> $DIR/fn_must_use.rs:3:9
    |
 LL | #![warn(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
-   = note: it's important
 
 warning: unused return value of `MyStruct::need_to_use_this_method_value` that must be used
   --> $DIR/fn_must_use.rs:60:5
diff --git a/src/test/ui/lint/forbid-group-group-2.stderr b/src/test/ui/lint/forbid-group-group-2.stderr
index 214e949c11a..b2e2bcea1b4 100644
--- a/src/test/ui/lint/forbid-group-group-2.stderr
+++ b/src/test/ui/lint/forbid-group-group-2.stderr
@@ -7,13 +7,13 @@ LL | #![forbid(warnings)]
 LL | #[allow(nonstandard_style)]
    |         ^^^^^^^^^^^^^^^^^ overruled by previous forbid
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 note: the lint level is defined here
   --> $DIR/forbid-group-group-2.rs:5:9
    |
 LL | #![deny(forbidden_lint_groups)]
    |         ^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 
 error: allow(nonstandard_style) incompatible with previous forbid
   --> $DIR/forbid-group-group-2.rs:7:9
diff --git a/src/test/ui/lint/forbid-group-member.stderr b/src/test/ui/lint/forbid-group-member.stderr
index 891fa9885f3..47336d4d890 100644
--- a/src/test/ui/lint/forbid-group-member.stderr
+++ b/src/test/ui/lint/forbid-group-member.stderr
@@ -7,9 +7,9 @@ LL |
 LL | #[allow(unused_variables)]
    |         ^^^^^^^^^^^^^^^^ overruled by previous forbid
    |
-   = note: `#[warn(forbidden_lint_groups)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
+   = note: `#[warn(forbidden_lint_groups)]` on by default
 
 warning: allow(unused_variables) incompatible with previous forbid
   --> $DIR/forbid-group-member.rs:8:9
diff --git a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
index 915b3b86fe8..97c2dee46dd 100644
--- a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: any use of this value will cause an error
 LL | const C: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warn const-err`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: requested on the command line with `--force-warn const-err`
 
 warning: 1 warning emitted
 
@@ -17,7 +17,7 @@ warning: any use of this value will cause an error
 LL | const C: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warn const-err`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: requested on the command line with `--force-warn const-err`
 
diff --git a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
index 3b36d1d0227..f293b78119e 100644
--- a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: any use of this value will cause an error
 LL | const C: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warn const-err`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: requested on the command line with `--force-warn const-err`
 
 warning: 1 warning emitted
 
@@ -17,7 +17,7 @@ warning: any use of this value will cause an error
 LL | const C: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warn const-err`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: requested on the command line with `--force-warn const-err`
 
diff --git a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
index 94d81c3aa71..0f58953a54b 100644
--- a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^
    |
-   = note: requested on the command line with `--force-warn bare-trait-objects`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: requested on the command line with `--force-warn bare-trait-objects`
 help: use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
diff --git a/src/test/ui/lint/force-warn/cap-lints-allow.stderr b/src/test/ui/lint/force-warn/cap-lints-allow.stderr
index 7f0fd8530e2..03a32fa6f08 100644
--- a/src/test/ui/lint/force-warn/cap-lints-allow.stderr
+++ b/src/test/ui/lint/force-warn/cap-lints-allow.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^
    |
-   = note: requested on the command line with `--force-warn bare-trait-objects`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: requested on the command line with `--force-warn bare-trait-objects`
 help: use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
diff --git a/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
index 3dafaf7055f..d1b764b3414 100644
--- a/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: `...` range patterns are deprecated
 LL |         0...100 => true,
    |          ^^^ help: use `..=` for an inclusive range
    |
-   = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr
index a2e5baa8b9d..703d0afd608 100644
--- a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: any use of this value will cause an error
 LL | const C: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warn const-err`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: requested on the command line with `--force-warn const-err`
 
 warning: 1 warning emitted
 
@@ -17,7 +17,7 @@ warning: any use of this value will cause an error
 LL | const C: i32 = 1 / 0;
    | ------------   ^^^^^ attempt to divide `1_i32` by zero
    |
-   = note: requested on the command line with `--force-warn const-err`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: requested on the command line with `--force-warn const-err`
 
diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
index eb2bca7b84d..e17630fd358 100644
--- a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^
    |
-   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
 help: use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
index ed01937a57b..72198541a70 100644
--- a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
+++ b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^
    |
-   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
 help: use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
index 8db7c12757b..52c870ac28a 100644
--- a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^
    |
-   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
 help: use `dyn`
    |
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
index 91b8d2b5afc..ed9fa0d4101 100644
--- a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
+++ b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
@@ -4,13 +4,13 @@ warning: `...` range patterns are deprecated
 LL |         1...2 => {}
    |          ^^^ help: use `..=` for an inclusive range
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/inclusive-range-pattern-syntax.rs:4:9
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 
 warning: `...` range patterns are deprecated
   --> $DIR/inclusive-range-pattern-syntax.rs:16:9
diff --git a/src/test/ui/lint/inert-attr-macro.stderr b/src/test/ui/lint/inert-attr-macro.stderr
index 3b3aa5d0bc0..5ccb4ffe792 100644
--- a/src/test/ui/lint/inert-attr-macro.stderr
+++ b/src/test/ui/lint/inert-attr-macro.stderr
@@ -4,17 +4,17 @@ warning: unused attribute `inline`
 LL |     #[inline] foo!();
    |     ^^^^^^^^^
    |
+note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
+  --> $DIR/inert-attr-macro.rs:10:15
+   |
+LL |     #[inline] foo!();
+   |               ^^^
 note: the lint level is defined here
   --> $DIR/inert-attr-macro.rs:3:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]`
-note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
-  --> $DIR/inert-attr-macro.rs:10:15
-   |
-LL |     #[inline] foo!();
-   |               ^^^
 
 warning: unused attribute `allow`
   --> $DIR/inert-attr-macro.rs:14:5
diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr
index fc7e89e4f4c..27399746bed 100644
--- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr
+++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr
@@ -4,13 +4,13 @@ warning: `#[inline]` is ignored on constants
 LL |     #[inline]
    |     ^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: see issue #65833 <https://github.com/rust-lang/rust/issues/65833> for more information
 note: the lint level is defined here
   --> $DIR/inline-trait-and-foreign-items.rs:4:9
    |
 LL | #![warn(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: see issue #65833 <https://github.com/rust-lang/rust/issues/65833> for more information
 
 error[E0518]: attribute should be applied to function or closure
   --> $DIR/inline-trait-and-foreign-items.rs:11:5
diff --git a/src/test/ui/lint/invalid_value.rs b/src/test/ui/lint/invalid_value.rs
index 51edb2b7baf..946a0e38861 100644
--- a/src/test/ui/lint/invalid_value.rs
+++ b/src/test/ui/lint/invalid_value.rs
@@ -88,6 +88,9 @@ fn main() {
         let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
         let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
 
+        let _val: (NonZeroU32, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: (NonZeroU32, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
         let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization
         let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
 
@@ -133,7 +136,7 @@ fn main() {
         let _val: Result<i32, i32> = mem::zeroed();
         let _val: Result<i32, i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
 
-        // Some things that happen to work due to rustc implementation details,
+        // Some things that happen to be UB-free due to rustc implementation details,
         // but are not guaranteed to keep working.
         let _val: OneFruit = mem::zeroed();
         let _val: OneFruit = mem::uninitialized();
diff --git a/src/test/ui/lint/invalid_value.stderr b/src/test/ui/lint/invalid_value.stderr
index 750b3c76c44..3901692001a 100644
--- a/src/test/ui/lint/invalid_value.stderr
+++ b/src/test/ui/lint/invalid_value.stderr
@@ -7,12 +7,12 @@ LL |         let _val: &'static T = mem::zeroed();
    |                                this code causes undefined behavior when executed
    |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
+   = note: references must be non-null
 note: the lint level is defined here
   --> $DIR/invalid_value.rs:6:9
    |
 LL | #![deny(invalid_value)]
    |         ^^^^^^^^^^^^^
-   = note: references must be non-null
 
 error: the type `&T` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:51:32
@@ -315,8 +315,30 @@ LL |         let _val: NonNull<i32> = mem::uninitialized();
    |
    = note: `std::ptr::NonNull<i32>` must be non-null
 
+error: the type `(NonZeroU32, i32)` does not permit zero-initialization
+  --> $DIR/invalid_value.rs:91:39
+   |
+LL |         let _val: (NonZeroU32, i32) = mem::zeroed();
+   |                                       ^^^^^^^^^^^^^
+   |                                       |
+   |                                       this code causes undefined behavior when executed
+   |                                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: `std::num::NonZeroU32` must be non-null
+
+error: the type `(NonZeroU32, i32)` does not permit being left uninitialized
+  --> $DIR/invalid_value.rs:92:39
+   |
+LL |         let _val: (NonZeroU32, i32) = mem::uninitialized();
+   |                                       ^^^^^^^^^^^^^^^^^^^^
+   |                                       |
+   |                                       this code causes undefined behavior when executed
+   |                                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: `std::num::NonZeroU32` must be non-null
+
 error: the type `*const dyn Send` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:91:37
+  --> $DIR/invalid_value.rs:94:37
    |
 LL |         let _val: *const dyn Send = mem::zeroed();
    |                                     ^^^^^^^^^^^^^
@@ -327,7 +349,7 @@ LL |         let _val: *const dyn Send = mem::zeroed();
    = note: the vtable of a wide raw pointer must be non-null
 
 error: the type `*const dyn Send` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:92:37
+  --> $DIR/invalid_value.rs:95:37
    |
 LL |         let _val: *const dyn Send = mem::uninitialized();
    |                                     ^^^^^^^^^^^^^^^^^^^^
@@ -338,7 +360,7 @@ LL |         let _val: *const dyn Send = mem::uninitialized();
    = note: the vtable of a wide raw pointer must be non-null
 
 error: the type `[fn(); 2]` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:94:31
+  --> $DIR/invalid_value.rs:97:31
    |
 LL |         let _val: [fn(); 2] = mem::zeroed();
    |                               ^^^^^^^^^^^^^
@@ -349,7 +371,7 @@ LL |         let _val: [fn(); 2] = mem::zeroed();
    = note: function pointers must be non-null
 
 error: the type `[fn(); 2]` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:95:31
+  --> $DIR/invalid_value.rs:98:31
    |
 LL |         let _val: [fn(); 2] = mem::uninitialized();
    |                               ^^^^^^^^^^^^^^^^^^^^
@@ -360,7 +382,7 @@ LL |         let _val: [fn(); 2] = mem::uninitialized();
    = note: function pointers must be non-null
 
 error: the type `TwoUninhabited` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:97:36
+  --> $DIR/invalid_value.rs:100:36
    |
 LL |         let _val: TwoUninhabited = mem::zeroed();
    |                                    ^^^^^^^^^^^^^
@@ -375,7 +397,7 @@ LL | enum TwoUninhabited {
    | ^^^^^^^^^^^^^^^^^^^
 
 error: the type `TwoUninhabited` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:98:36
+  --> $DIR/invalid_value.rs:101:36
    |
 LL |         let _val: TwoUninhabited = mem::uninitialized();
    |                                    ^^^^^^^^^^^^^^^^^^^^
@@ -390,7 +412,7 @@ LL | enum TwoUninhabited {
    | ^^^^^^^^^^^^^^^^^^^
 
 error: the type `OneFruitNonZero` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:100:37
+  --> $DIR/invalid_value.rs:103:37
    |
 LL |         let _val: OneFruitNonZero = mem::zeroed();
    |                                     ^^^^^^^^^^^^^
@@ -405,7 +427,7 @@ LL |     Banana(NonZeroU32),
    |            ^^^^^^^^^^
 
 error: the type `OneFruitNonZero` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:101:37
+  --> $DIR/invalid_value.rs:104:37
    |
 LL |         let _val: OneFruitNonZero = mem::uninitialized();
    |                                     ^^^^^^^^^^^^^^^^^^^^
@@ -420,7 +442,7 @@ LL |     Banana(NonZeroU32),
    |            ^^^^^^^^^^
 
 error: the type `bool` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:105:26
+  --> $DIR/invalid_value.rs:108:26
    |
 LL |         let _val: bool = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
@@ -431,7 +453,7 @@ LL |         let _val: bool = mem::uninitialized();
    = note: booleans must be either `true` or `false`
 
 error: the type `Wrap<char>` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:108:32
+  --> $DIR/invalid_value.rs:111:32
    |
 LL |         let _val: Wrap<char> = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
@@ -446,7 +468,7 @@ LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `NonBig` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:111:28
+  --> $DIR/invalid_value.rs:114:28
    |
 LL |         let _val: NonBig = mem::uninitialized();
    |                            ^^^^^^^^^^^^^^^^^^^^
@@ -457,7 +479,7 @@ LL |         let _val: NonBig = mem::uninitialized();
    = note: `NonBig` must be initialized inside its custom valid range
 
 error: the type `Fruit` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:114:27
+  --> $DIR/invalid_value.rs:117:27
    |
 LL |         let _val: Fruit = mem::uninitialized();
    |                           ^^^^^^^^^^^^^^^^^^^^
@@ -472,7 +494,7 @@ LL | enum Fruit {
    | ^^^^^^^^^^
 
 error: the type `[bool; 2]` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:117:31
+  --> $DIR/invalid_value.rs:120:31
    |
 LL |         let _val: [bool; 2] = mem::uninitialized();
    |                               ^^^^^^^^^^^^^^^^^^^^
@@ -483,7 +505,7 @@ LL |         let _val: [bool; 2] = mem::uninitialized();
    = note: booleans must be either `true` or `false`
 
 error: the type `i32` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:120:25
+  --> $DIR/invalid_value.rs:123:25
    |
 LL |         let _val: i32 = mem::uninitialized();
    |                         ^^^^^^^^^^^^^^^^^^^^
@@ -494,7 +516,7 @@ LL |         let _val: i32 = mem::uninitialized();
    = note: integers must not be uninitialized
 
 error: the type `f32` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:123:25
+  --> $DIR/invalid_value.rs:126:25
    |
 LL |         let _val: f32 = mem::uninitialized();
    |                         ^^^^^^^^^^^^^^^^^^^^
@@ -505,7 +527,7 @@ LL |         let _val: f32 = mem::uninitialized();
    = note: floats must not be uninitialized
 
 error: the type `*const ()` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:126:31
+  --> $DIR/invalid_value.rs:129:31
    |
 LL |         let _val: *const () = mem::uninitialized();
    |                               ^^^^^^^^^^^^^^^^^^^^
@@ -516,7 +538,7 @@ LL |         let _val: *const () = mem::uninitialized();
    = note: raw pointers must not be uninitialized
 
 error: the type `*const [()]` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:129:33
+  --> $DIR/invalid_value.rs:132:33
    |
 LL |         let _val: *const [()] = mem::uninitialized();
    |                                 ^^^^^^^^^^^^^^^^^^^^
@@ -527,7 +549,7 @@ LL |         let _val: *const [()] = mem::uninitialized();
    = note: raw pointers must not be uninitialized
 
 error: the type `Result<i32, i32>` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:134:38
+  --> $DIR/invalid_value.rs:137:38
    |
 LL |         let _val: Result<i32, i32> = mem::uninitialized();
    |                                      ^^^^^^^^^^^^^^^^^^^^
@@ -542,7 +564,7 @@ LL | pub enum Result<T, E> {
    | ^^^^^^^^^^^^^^^^^^^^^
 
 error: the type `&i32` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:142:34
+  --> $DIR/invalid_value.rs:145:34
    |
 LL |         let _val: &'static i32 = mem::transmute(0usize);
    |                                  ^^^^^^^^^^^^^^^^^^^^^^
@@ -553,7 +575,7 @@ LL |         let _val: &'static i32 = mem::transmute(0usize);
    = note: references must be non-null
 
 error: the type `&[i32]` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:143:36
+  --> $DIR/invalid_value.rs:146:36
    |
 LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -564,7 +586,7 @@ LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
    = note: references must be non-null
 
 error: the type `NonZeroU32` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:144:32
+  --> $DIR/invalid_value.rs:147:32
    |
 LL |         let _val: NonZeroU32 = mem::transmute(0);
    |                                ^^^^^^^^^^^^^^^^^
@@ -575,7 +597,7 @@ LL |         let _val: NonZeroU32 = mem::transmute(0);
    = note: `std::num::NonZeroU32` must be non-null
 
 error: the type `NonNull<i32>` does not permit zero-initialization
-  --> $DIR/invalid_value.rs:147:34
+  --> $DIR/invalid_value.rs:150:34
    |
 LL |         let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -586,7 +608,7 @@ LL |         let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
    = note: `std::ptr::NonNull<i32>` must be non-null
 
 error: the type `NonNull<i32>` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:148:34
+  --> $DIR/invalid_value.rs:151:34
    |
 LL |         let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -597,7 +619,7 @@ LL |         let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
    = note: `std::ptr::NonNull<i32>` must be non-null
 
 error: the type `bool` does not permit being left uninitialized
-  --> $DIR/invalid_value.rs:149:26
+  --> $DIR/invalid_value.rs:152:26
    |
 LL |         let _val: bool = MaybeUninit::uninit().assume_init();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -607,5 +629,5 @@ LL |         let _val: bool = MaybeUninit::uninit().assume_init();
    |
    = note: booleans must be either `true` or `false`
 
-error: aborting due to 48 previous errors
+error: aborting due to 50 previous errors
 
diff --git a/src/test/ui/lint/issue-14309.stderr b/src/test/ui/lint/issue-14309.stderr
index a9538b5e3a4..9ce62a6b804 100644
--- a/src/test/ui/lint/issue-14309.stderr
+++ b/src/test/ui/lint/issue-14309.stderr
@@ -4,11 +4,6 @@ error: `extern` block uses type `A`, which is not FFI-safe
 LL |     fn foo(x: A);
    |               ^ not FFI-safe
    |
-note: the lint level is defined here
-  --> $DIR/issue-14309.rs:1:9
-   |
-LL | #![deny(improper_ctypes)]
-   |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
@@ -16,6 +11,11 @@ note: the type is defined here
    |
 LL | struct A {
    | ^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/issue-14309.rs:1:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/issue-14309.rs:31:15
diff --git a/src/test/ui/lint/issue-1866.stderr b/src/test/ui/lint/issue-1866.stderr
index 5edae48a10f..d19a1349668 100644
--- a/src/test/ui/lint/issue-1866.stderr
+++ b/src/test/ui/lint/issue-1866.stderr
@@ -7,13 +7,13 @@ LL |             pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
 LL |             pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
+   = note: expected `unsafe extern "C" fn(*const usize) -> bool`
+              found `unsafe extern "C" fn(*const bool) -> bool`
 note: the lint level is defined here
   --> $DIR/issue-1866.rs:4:9
    |
 LL | #![warn(clashing_extern_declarations)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `unsafe extern "C" fn(*const usize) -> bool`
-              found `unsafe extern "C" fn(*const bool) -> bool`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/issue-63364.stderr b/src/test/ui/lint/issue-63364.stderr
index 0375359aeab..9b5453fa82d 100644
--- a/src/test/ui/lint/issue-63364.stderr
+++ b/src/test/ui/lint/issue-63364.stderr
@@ -4,8 +4,8 @@ error: literal out of range for `u16`
 LL |     for n in 100_000.. {
    |              ^^^^^^^
    |
-   = note: `#[deny(overflowing_literals)]` on by default
    = note: the literal `100_000` does not fit into the type `u16` whose range is `0..=65535`
+   = note: `#[deny(overflowing_literals)]` on by default
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
index 5093715decf..cc44f8aa58b 100644
--- a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
+++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr
@@ -6,13 +6,13 @@ LL |     #![forbid(unused)]
 LL |     #![deny(unused)]
    |             ^^^^^^ overruled by previous forbid
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 note: the lint level is defined here
   --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11
    |
 LL | #![forbid(forbidden_lint_groups)]
    |           ^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/issue-79744.stderr b/src/test/ui/lint/issue-79744.stderr
index 6f6dd44d236..c1b56250d3e 100644
--- a/src/test/ui/lint/issue-79744.stderr
+++ b/src/test/ui/lint/issue-79744.stderr
@@ -4,9 +4,9 @@ error: literal out of range for `i8`
 LL |     let e2 = 230;
    |              ^^^
    |
-   = note: `#[deny(overflowing_literals)]` on by default
    = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127`
    = help: consider using the type `u8` instead
+   = note: `#[deny(overflowing_literals)]` on by default
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/issue-80988.stderr b/src/test/ui/lint/issue-80988.stderr
index 1d397f43133..73e27ffda7f 100644
--- a/src/test/ui/lint/issue-80988.stderr
+++ b/src/test/ui/lint/issue-80988.stderr
@@ -7,9 +7,9 @@ LL |
 LL | #[deny(warnings)]
    |        ^^^^^^^^ overruled by previous forbid
    |
-   = note: `#[warn(forbidden_lint_groups)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
+   = note: `#[warn(forbidden_lint_groups)]` on by default
 
 warning: deny(warnings) incompatible with previous forbid
   --> $DIR/issue-80988.rs:7:8
diff --git a/src/test/ui/lint/issue-83477.stderr b/src/test/ui/lint/issue-83477.stderr
index e619bcfe23f..f824fc09e72 100644
--- a/src/test/ui/lint/issue-83477.stderr
+++ b/src/test/ui/lint/issue-83477.stderr
@@ -18,13 +18,13 @@ warning: prefer `FxHashMap` over `HashMap`, it has better performance
 LL |     let _ = std::collections::HashMap::<String, String>::new();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 note: the lint level is defined here
   --> $DIR/issue-83477.rs:3:9
    |
 LL | #![warn(rustc::internal)]
    |         ^^^^^^^^^^^^^^^
    = note: `#[warn(rustc::default_hash_types)]` implied by `#[warn(rustc::internal)]`
-   = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
 
 warning: 3 warnings emitted
 
diff --git a/src/test/ui/lint/issue-86600-lint-twice.stderr b/src/test/ui/lint/issue-86600-lint-twice.stderr
index 8da3fb5a839..5a65c612128 100644
--- a/src/test/ui/lint/issue-86600-lint-twice.stderr
+++ b/src/test/ui/lint/issue-86600-lint-twice.stderr
@@ -4,9 +4,9 @@ warning: floating-point types cannot be used in patterns
 LL |         5.0 => {}
    |         ^^^
    |
-   = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+   = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/lint-attr-everywhere-early.stderr b/src/test/ui/lint/lint-attr-everywhere-early.stderr
index 1d6e3cda4e5..d6c6d5faef2 100644
--- a/src/test/ui/lint/lint-attr-everywhere-early.stderr
+++ b/src/test/ui/lint/lint-attr-everywhere-early.stderr
@@ -474,13 +474,13 @@ error: `...` range patterns are deprecated
 LL |             f1: 0...100,
    |                  ^^^ help: use `..=` for an inclusive range
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/lint-attr-everywhere-early.rs:166:20
    |
 LL |             #[deny(ellipsis_inclusive_range_patterns)]
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 
 error: aborting due to 36 previous errors
 
diff --git a/src/test/ui/lint/lint-attr-everywhere-late.stderr b/src/test/ui/lint/lint-attr-everywhere-late.stderr
index 977843997c6..a69c2e0ef2b 100644
--- a/src/test/ui/lint/lint-attr-everywhere-late.stderr
+++ b/src/test/ui/lint/lint-attr-everywhere-late.stderr
@@ -163,13 +163,13 @@ LL |         fn clashing1();
 LL |     fn clashing1(_: i32);
    |     ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
+   = note: expected `unsafe extern "C" fn()`
+              found `unsafe extern "C" fn(i32)`
 note: the lint level is defined here
   --> $DIR/lint-attr-everywhere-late.rs:122:13
    |
 LL |     #![deny(clashing_extern_declarations)]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `unsafe extern "C" fn()`
-              found `unsafe extern "C" fn(i32)`
 
 error: `clashing2` redeclared with a different signature
   --> $DIR/lint-attr-everywhere-late.rs:128:5
@@ -180,13 +180,13 @@ LL |         fn clashing2();
 LL |     fn clashing2(_: i32);
    |     ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
+   = note: expected `unsafe extern "C" fn()`
+              found `unsafe extern "C" fn(i32)`
 note: the lint level is defined here
   --> $DIR/lint-attr-everywhere-late.rs:127:12
    |
 LL |     #[deny(clashing_extern_declarations)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `unsafe extern "C" fn()`
-              found `unsafe extern "C" fn(i32)`
 
 error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
   --> $DIR/lint-attr-everywhere-late.rs:93:38
@@ -206,16 +206,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     fn assoc_fn() { discriminant::<i32>(&123); }
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:95:12
-   |
-LL |     #[deny(enum_intrinsics_non_enums)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:96:41
    |
 LL |     fn assoc_fn() { discriminant::<i32>(&123); }
    |                                         ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:95:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: literal out of range for `u8`
   --> $DIR/lint-attr-everywhere-late.rs:98:59
@@ -223,12 +223,12 @@ error: literal out of range for `u8`
 LL |     #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
    |                                                           ^^^^
    |
+   = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
 note: the lint level is defined here
   --> $DIR/lint-attr-everywhere-late.rs:98:12
    |
 LL |     #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000;
    |            ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
 
 error: variable `PARAM` should have a snake case name
   --> $DIR/lint-attr-everywhere-late.rs:131:37
@@ -248,16 +248,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     let _ = discriminant::<i32>(&123);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:138:12
-   |
-LL |     #[deny(enum_intrinsics_non_enums)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:139:33
    |
 LL |     let _ = discriminant::<i32>(&123);
    |                                 ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:138:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: variable `PARAM` should have a snake case name
   --> $DIR/lint-attr-everywhere-late.rs:145:44
@@ -277,16 +277,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |             discriminant::<i32>(&123);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:153:17
-   |
-LL |         #![deny(enum_intrinsics_non_enums)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:155:33
    |
 LL |             discriminant::<i32>(&123);
    |                                 ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:153:17
+   |
+LL |         #![deny(enum_intrinsics_non_enums)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:161:13
@@ -294,16 +294,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |             discriminant::<i32>(&123);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:159:16
-   |
-LL |         #[deny(enum_intrinsics_non_enums)]
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:161:33
    |
 LL |             discriminant::<i32>(&123);
    |                                 ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:159:16
+   |
+LL |         #[deny(enum_intrinsics_non_enums)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:168:9
@@ -311,16 +311,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |         discriminant::<i32>(&123);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:167:17
-   |
-LL |         #![deny(enum_intrinsics_non_enums)]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:168:29
    |
 LL |         discriminant::<i32>(&123);
    |                             ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:167:17
+   |
+LL |         #![deny(enum_intrinsics_non_enums)]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:172:9
@@ -328,16 +328,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |         discriminant::<i32>(&123);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:171:16
-   |
-LL |         #[deny(enum_intrinsics_non_enums)]
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:172:29
    |
 LL |         discriminant::<i32>(&123);
    |                             ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:171:16
+   |
+LL |         #[deny(enum_intrinsics_non_enums)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:177:5
@@ -345,16 +345,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     discriminant::<i32>(&123);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:176:12
-   |
-LL |     #[deny(enum_intrinsics_non_enums)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:177:25
    |
 LL |     discriminant::<i32>(&123);
    |                         ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:176:12
+   |
+LL |     #[deny(enum_intrinsics_non_enums)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:179:41
@@ -362,16 +362,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:179:13
-   |
-LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:179:61
    |
 LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
    |                                                             ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:179:13
+   |
+LL |     [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:180:41
@@ -379,16 +379,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:180:13
-   |
-LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:180:61
    |
 LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
    |                                                             ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:180:13
+   |
+LL |     (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:182:45
@@ -396,16 +396,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
    |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:182:17
-   |
-LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:182:65
    |
 LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
    |                                                                 ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:182:17
+   |
+LL |     call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-attr-everywhere-late.rs:184:52
@@ -413,16 +413,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
    |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/lint-attr-everywhere-late.rs:184:24
-   |
-LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
   --> $DIR/lint-attr-everywhere-late.rs:184:72
    |
 LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
    |                                                                        ^^^^
+note: the lint level is defined here
+  --> $DIR/lint-attr-everywhere-late.rs:184:24
+   |
+LL |     TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123));
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 31 previous errors
 
diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr
index 94d876423e7..9f4360e6763 100644
--- a/src/test/ui/lint/lint-const-item-mutation.stderr
+++ b/src/test/ui/lint/lint-const-item-mutation.stderr
@@ -4,13 +4,13 @@ warning: attempting to modify a `const` item
 LL |     ARRAY[0] = 5;
    |     ^^^^^^^^^^^^
    |
-   = note: `#[warn(const_item_mutation)]` on by default
    = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
 note: `const` item defined here
   --> $DIR/lint-const-item-mutation.rs:26:1
    |
 LL | const ARRAY: [u8; 1] = [25];
    | ^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(const_item_mutation)]` on by default
 
 warning: attempting to modify a `const` item
   --> $DIR/lint-const-item-mutation.rs:38:5
diff --git a/src/test/ui/lint/lint-ctypes-73249-2.stderr b/src/test/ui/lint/lint-ctypes-73249-2.stderr
index 7c85e9fa85c..8073c33dd46 100644
--- a/src/test/ui/lint/lint-ctypes-73249-2.stderr
+++ b/src/test/ui/lint/lint-ctypes-73249-2.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe
 LL |     pub fn lint_me() -> A<()>;
    |                         ^^^^^ not FFI-safe
    |
+   = note: opaque types have no C equivalent
 note: the lint level is defined here
   --> $DIR/lint-ctypes-73249-2.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-ctypes-73249-3.stderr b/src/test/ui/lint/lint-ctypes-73249-3.stderr
index 83e2a233c43..c41ce666db8 100644
--- a/src/test/ui/lint/lint-ctypes-73249-3.stderr
+++ b/src/test/ui/lint/lint-ctypes-73249-3.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe
 LL |     pub fn lint_me() -> A;
    |                         ^ not FFI-safe
    |
+   = note: opaque types have no C equivalent
 note: the lint level is defined here
   --> $DIR/lint-ctypes-73249-3.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-ctypes-73249-5.stderr b/src/test/ui/lint/lint-ctypes-73249-5.stderr
index 37781d78cf2..98245c4f144 100644
--- a/src/test/ui/lint/lint-ctypes-73249-5.stderr
+++ b/src/test/ui/lint/lint-ctypes-73249-5.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe
 LL |     pub fn lint_me() -> A;
    |                         ^ not FFI-safe
    |
+   = note: opaque types have no C equivalent
 note: the lint level is defined here
   --> $DIR/lint-ctypes-73249-5.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-ctypes-73251-1.stderr b/src/test/ui/lint/lint-ctypes-73251-1.stderr
index 76b19d37e21..9f43576ad73 100644
--- a/src/test/ui/lint/lint-ctypes-73251-1.stderr
+++ b/src/test/ui/lint/lint-ctypes-73251-1.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe
 LL |     pub fn lint_me() -> <u32 as Foo>::Assoc;
    |                         ^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
+   = note: opaque types have no C equivalent
 note: the lint level is defined here
   --> $DIR/lint-ctypes-73251-1.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-ctypes-73251-2.stderr b/src/test/ui/lint/lint-ctypes-73251-2.stderr
index 64f0fb2d892..0b3de379c19 100644
--- a/src/test/ui/lint/lint-ctypes-73251-2.stderr
+++ b/src/test/ui/lint/lint-ctypes-73251-2.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `AliasA`, which is not FFI-safe
 LL |     pub fn lint_me() -> <AliasB as TraitB>::Assoc;
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
+   = note: opaque types have no C equivalent
 note: the lint level is defined here
   --> $DIR/lint-ctypes-73251-2.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-ctypes-enum.stderr b/src/test/ui/lint/lint-ctypes-enum.stderr
index de532f69ac0..8554e261778 100644
--- a/src/test/ui/lint/lint-ctypes-enum.stderr
+++ b/src/test/ui/lint/lint-ctypes-enum.stderr
@@ -4,11 +4,6 @@ error: `extern` block uses type `U`, which is not FFI-safe
 LL |    fn uf(x: U);
    |             ^ not FFI-safe
    |
-note: the lint level is defined here
-  --> $DIR/lint-ctypes-enum.rs:3:9
-   |
-LL | #![deny(improper_ctypes)]
-   |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
@@ -16,6 +11,11 @@ note: the type is defined here
    |
 LL | enum U {
    | ^^^^^^
+note: the lint level is defined here
+  --> $DIR/lint-ctypes-enum.rs:3:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `B`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:61:13
diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr
index 6f8d76411aa..a05206bf18d 100644
--- a/src/test/ui/lint/lint-ctypes-fn.stderr
+++ b/src/test/ui/lint/lint-ctypes-fn.stderr
@@ -4,13 +4,13 @@ error: `extern` fn uses type `[u32]`, which is not FFI-safe
 LL | pub extern "C" fn slice_type(p: &[u32]) { }
    |                                 ^^^^^^ not FFI-safe
    |
+   = help: consider using a raw pointer instead
+   = note: slices have no C equivalent
 note: the lint level is defined here
   --> $DIR/lint-ctypes-fn.rs:4:9
    |
 LL | #![deny(improper_ctypes_definitions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: consider using a raw pointer instead
-   = note: slices have no C equivalent
 
 error: `extern` fn uses type `str`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:76:31
diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr
index bfec40e1955..121ad0ce8fa 100644
--- a/src/test/ui/lint/lint-ctypes.stderr
+++ b/src/test/ui/lint/lint-ctypes.stderr
@@ -4,11 +4,6 @@ error: `extern` block uses type `Foo`, which is not FFI-safe
 LL |     pub fn ptr_type1(size: *const Foo);
    |                            ^^^^^^^^^^ not FFI-safe
    |
-note: the lint level is defined here
-  --> $DIR/lint-ctypes.rs:4:9
-   |
-LL | #![deny(improper_ctypes)]
-   |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
@@ -16,6 +11,11 @@ note: the type is defined here
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/lint-ctypes.rs:4:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:49:28
diff --git a/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
index bec9fb62efa..63ed2503cf3 100644
--- a/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
+++ b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
@@ -4,12 +4,12 @@ error: the return value of `mem::discriminant` is unspecified when called with a
 LL |     discriminant(&());
    |     ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(enum_intrinsics_non_enums)]` on by default
 note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `()`, which is not an enum.
   --> $DIR/lint-enum-intrinsics-non-enums.rs:26:18
    |
 LL |     discriminant(&());
    |                  ^^^
+   = note: `#[deny(enum_intrinsics_non_enums)]` on by default
 
 error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
   --> $DIR/lint-enum-intrinsics-non-enums.rs:29:5
diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
index afbab989676..3f366bedbf3 100644
--- a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
+++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
@@ -7,9 +7,9 @@ LL |
 LL | impl Foo for dyn Send + Send {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
    |
-   = note: `#[deny(order_dependent_trait_objects)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
+   = note: `#[deny(order_dependent_trait_objects)]` on by default
 
 error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr
index 2a1847b9801..9f38dcb0b22 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr
@@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering
 LL |     let _ = x.load(Ordering::Release);
    |                    ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: atomic loads cannot have `Release` or `AcqRel` ordering
   --> $DIR/lint-invalid-atomic-ordering-bool.rs:15:20
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
index 021654cf35e..cc075ce9e41 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr
@@ -4,8 +4,8 @@ error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRe
 LL |     let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel);
    |                                                                   ^^^^^^^^^^^^^^^^ invalid failure ordering
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using `Acquire` or `Relaxed` failure ordering instead
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write
   --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:30:67
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
index f6f8f88e884..fe6c7e55c62 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr
@@ -4,8 +4,8 @@ error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, s
 LL |     let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel);
    |                                                         ^^^^^^^^^^^^^^^^ invalid failure ordering
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using `Acquire` or `Relaxed` failure ordering instead
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write
   --> $DIR/lint-invalid-atomic-ordering-exchange.rs:28:57
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr
index e0741ffedd9..38327d607c9 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr
@@ -4,8 +4,8 @@ error: memory fences cannot have `Relaxed` ordering
 LL |     fence(Ordering::Relaxed);
    |           ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: memory fences cannot have `Relaxed` ordering
   --> $DIR/lint-invalid-atomic-ordering-fence.rs:19:20
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
index 267b1c706ef..33829d68fd5 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr
@@ -4,8 +4,8 @@ error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since
 LL |     let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1));
    |                                               ^^^^^^^^^^^^^^^^ invalid failure ordering
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using `Acquire` or `Relaxed` failure ordering instead
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write
   --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:28:47
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr
index dfd9990455a..36930e2f440 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr
@@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering
 LL |     let _ = x.load(Ordering::Release);
    |                    ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: atomic loads cannot have `Release` or `AcqRel` ordering
   --> $DIR/lint-invalid-atomic-ordering-int.rs:22:20
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr
index f00cb8e4082..12f4cad90fe 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr
@@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering
 LL |     let _ = x.load(Ordering::Release);
    |                    ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: atomic loads cannot have `Release` or `AcqRel` ordering
   --> $DIR/lint-invalid-atomic-ordering-ptr.rs:17:20
diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr
index 36672e434b9..d26621f2a88 100644
--- a/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr
+++ b/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr
@@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering
 LL |     let _ = x.load(Ordering::Release);
    |                    ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(invalid_atomic_ordering)]` on by default
    = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
+   = note: `#[deny(invalid_atomic_ordering)]` on by default
 
 error: atomic loads cannot have `Release` or `AcqRel` ordering
   --> $DIR/lint-invalid-atomic-ordering-uint.rs:21:20
diff --git a/src/test/ui/lint/lint-non-snake-case-crate-2.stderr b/src/test/ui/lint/lint-non-snake-case-crate-2.stderr
index e2951129327..4b42145bbed 100644
--- a/src/test/ui/lint/lint-non-snake-case-crate-2.stderr
+++ b/src/test/ui/lint/lint-non-snake-case-crate-2.stderr
@@ -1,11 +1,11 @@
 error: crate `NonSnakeCase` should have a snake case name
    |
+   = help: convert the identifier to snake case: `non_snake_case`
 note: the lint level is defined here
   --> $DIR/lint-non-snake-case-crate-2.rs:4:9
    |
 LL | #![deny(non_snake_case)]
    |         ^^^^^^^^^^^^^^
-   = help: convert the identifier to snake case: `non_snake_case`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-pre-expansion-extern-module.stderr b/src/test/ui/lint/lint-pre-expansion-extern-module.stderr
index 3355bb4e4ff..ce3e8806a9e 100644
--- a/src/test/ui/lint/lint-pre-expansion-extern-module.stderr
+++ b/src/test/ui/lint/lint-pre-expansion-extern-module.stderr
@@ -4,9 +4,9 @@ warning: `try` is a keyword in the 2018 edition
 LL | pub fn try() {}
    |        ^^^ help: you can use a raw identifier to stay compatible: `r#try`
    |
-   = note: `-W keyword-idents` implied by `-W rust-2018-compatibility`
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+   = note: `-W keyword-idents` implied by `-W rust-2018-compatibility`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
index c85934aa3ba..383623b4831 100644
--- a/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
+++ b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
@@ -4,12 +4,12 @@ error: strict provenance disallows casting integer `usize` to pointer `*const u8
 LL |     let dangling = 16_usize as *const u8;
    |                    ^^^^^^^^^^^^^^^^^^^^^
    |
+   = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead
 note: the lint level is defined here
   --> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9
    |
 LL | #![deny(fuzzy_provenance_casts)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead
 help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
    |
 LL |     let dangling = (...).with_addr(16_usize);
diff --git a/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr b/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr
index 05178b34b11..aa151fe2d21 100644
--- a/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr
+++ b/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr
@@ -4,12 +4,12 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
 LL |     let addr: usize = &x as *const u8 as usize;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
 note: the lint level is defined here
   --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
    |
 LL | #![deny(lossy_provenance_casts)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
 help: use `.addr()` to obtain the address of a pointer
    |
 LL |     let addr: usize = (&x as *const u8).addr();
diff --git a/src/test/ui/lint/lint-temporary-cstring-as-param.stderr b/src/test/ui/lint/lint-temporary-cstring-as-param.stderr
index 0a9e5a4bf4a..838b3bc13fe 100644
--- a/src/test/ui/lint/lint-temporary-cstring-as-param.stderr
+++ b/src/test/ui/lint/lint-temporary-cstring-as-param.stderr
@@ -6,13 +6,13 @@ LL |     some_function(CString::new("").unwrap().as_ptr());
    |                   |
    |                   this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
    |
+   = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
+   = help: for more information, see https://doc.rust-lang.org/reference/destructors.html
 note: the lint level is defined here
   --> $DIR/lint-temporary-cstring-as-param.rs:1:9
    |
 LL | #![deny(temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
-   = help: for more information, see https://doc.rust-lang.org/reference/destructors.html
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr b/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr
index e69d2dd533a..79ef57dd1a3 100644
--- a/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr
+++ b/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr
@@ -6,13 +6,13 @@ LL |     let s = CString::new("some text").unwrap().as_ptr();
    |             |
    |             this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
    |
+   = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
+   = help: for more information, see https://doc.rust-lang.org/reference/destructors.html
 note: the lint level is defined here
   --> $DIR/lint-temporary-cstring-as-ptr.rs:2:9
    |
 LL | #![deny(temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
-   = help: for more information, see https://doc.rust-lang.org/reference/destructors.html
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr
index 3562cb440a6..b3420ad8afd 100644
--- a/src/test/ui/lint/lint-type-limits2.stderr
+++ b/src/test/ui/lint/lint-type-limits2.stderr
@@ -12,13 +12,13 @@ warning: literal out of range for `i8`
 LL |     128 > bar()
    |     ^^^
    |
+   = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `u8` instead
 note: the lint level is defined here
   --> $DIR/lint-type-limits2.rs:2:9
    |
 LL | #![warn(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
-   = help: consider using the type `u8` instead
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr
index 823d1a4c76f..db46e7ae714 100644
--- a/src/test/ui/lint/lint-type-limits3.stderr
+++ b/src/test/ui/lint/lint-type-limits3.stderr
@@ -12,13 +12,13 @@ warning: literal out of range for `i8`
 LL |     while 200 != i {
    |           ^^^
    |
+   = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `u8` instead
 note: the lint level is defined here
   --> $DIR/lint-type-limits3.rs:2:9
    |
 LL | #![warn(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127`
-   = help: consider using the type `u8` instead
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/lint/lint-type-overflow.stderr b/src/test/ui/lint/lint-type-overflow.stderr
index 1bb1ec54776..48d8228b802 100644
--- a/src/test/ui/lint/lint-type-overflow.stderr
+++ b/src/test/ui/lint/lint-type-overflow.stderr
@@ -4,12 +4,12 @@ error: literal out of range for `u8`
 LL |     let x1: u8 = 256;
    |                  ^^^
    |
+   = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
 note: the lint level is defined here
   --> $DIR/lint-type-overflow.rs:1:9
    |
 LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `256` does not fit into the type `u8` whose range is `0..=255`
 
 error: literal out of range for `u8`
   --> $DIR/lint-type-overflow.rs:13:14
diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr
index 3d40cdf96ef..117bfc3ced7 100644
--- a/src/test/ui/lint/lint-type-overflow2.stderr
+++ b/src/test/ui/lint/lint-type-overflow2.stderr
@@ -4,13 +4,13 @@ error: literal out of range for `i8`
 LL |     let x2: i8 = --128;
    |                    ^^^
    |
+   = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `u8` instead
 note: the lint level is defined here
   --> $DIR/lint-type-overflow2.rs:3:9
    |
 LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
-   = help: consider using the type `u8` instead
 
 error: literal out of range for `f32`
   --> $DIR/lint-type-overflow2.rs:9:14
diff --git a/src/test/ui/lint/lint-unconditional-recursion.stderr b/src/test/ui/lint/lint-unconditional-recursion.stderr
index c11b73f41ca..9d200a7898e 100644
--- a/src/test/ui/lint/lint-unconditional-recursion.stderr
+++ b/src/test/ui/lint/lint-unconditional-recursion.stderr
@@ -6,12 +6,12 @@ LL | fn foo() {
 LL |     foo();
    |     ----- recursive call site
    |
+   = help: a `loop` may express intention better if this is on purpose
 note: the lint level is defined here
   --> $DIR/lint-unconditional-recursion.rs:1:9
    |
 LL | #![deny(unconditional_recursion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
-   = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
   --> $DIR/lint-unconditional-recursion.rs:14:1
diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr
index 8dde05fc4de..037f0a8323a 100644
--- a/src/test/ui/lint/lint-unsafe-code.stderr
+++ b/src/test/ui/lint/lint-unsafe-code.stderr
@@ -4,12 +4,12 @@ error: declaration of a `no_mangle` function
 LL | #[no_mangle] fn foo() {}
    | ^^^^^^^^^^^^
    |
+   = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 note: the lint level is defined here
   --> $DIR/lint-unsafe-code.rs:3:9
    |
 LL | #![deny(unsafe_code)]
    |         ^^^^^^^^^^^
-   = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 
 error: declaration of a `no_mangle` static
   --> $DIR/lint-unsafe-code.rs:32:1
diff --git a/src/test/ui/lint/must_not_suspend/boxed.stderr b/src/test/ui/lint/must_not_suspend/boxed.stderr
index b3c9b43810c..9efc7b0693b 100644
--- a/src/test/ui/lint/must_not_suspend/boxed.stderr
+++ b/src/test/ui/lint/must_not_suspend/boxed.stderr
@@ -6,11 +6,6 @@ LL |     let _guard = bar();
 LL |     other().await;
    |            ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/boxed.rs:3:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
   --> $DIR/boxed.rs:20:9
    |
@@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |     let _guard = bar();
    |         ^^^^^^
+note: the lint level is defined here
+  --> $DIR/boxed.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/dedup.stderr b/src/test/ui/lint/must_not_suspend/dedup.stderr
index 13fa3ae3008..f8978ba57f1 100644
--- a/src/test/ui/lint/must_not_suspend/dedup.stderr
+++ b/src/test/ui/lint/must_not_suspend/dedup.stderr
@@ -4,16 +4,16 @@ error: `No` held across a suspend point, but should not be
 LL |     wheeee(&No {}).await;
    |             ^^^^^ ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/dedup.rs:3:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
   --> $DIR/dedup.rs:16:13
    |
 LL |     wheeee(&No {}).await;
    |             ^^^^^
+note: the lint level is defined here
+  --> $DIR/dedup.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/gated.stderr b/src/test/ui/lint/must_not_suspend/gated.stderr
index b58ecb55596..64de1ebeaab 100644
--- a/src/test/ui/lint/must_not_suspend/gated.stderr
+++ b/src/test/ui/lint/must_not_suspend/gated.stderr
@@ -4,10 +4,10 @@ warning: unknown lint: `must_not_suspend`
 LL | #![deny(must_not_suspend)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unknown_lints)]` on by default
    = note: the `must_not_suspend` lint is unstable
    = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
    = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
+   = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `must_not_suspend`
   --> $DIR/gated.rs:4:1
diff --git a/src/test/ui/lint/must_not_suspend/mutex.stderr b/src/test/ui/lint/must_not_suspend/mutex.stderr
index a968b7ca033..c251cb84589 100644
--- a/src/test/ui/lint/must_not_suspend/mutex.stderr
+++ b/src/test/ui/lint/must_not_suspend/mutex.stderr
@@ -6,11 +6,6 @@ LL |     let _guard = m.lock().unwrap();
 LL |     other().await;
    |            ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/mutex.rs:3:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
   --> $DIR/mutex.rs:8:9
    |
@@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |     let _guard = m.lock().unwrap();
    |         ^^^^^^
+note: the lint level is defined here
+  --> $DIR/mutex.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
index c49d2712853..180e187c1b0 100644
--- a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
+++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr
@@ -7,11 +7,6 @@ LL |
 LL |         other().await;
    |                ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/ref-drop-tracking.rs:4:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
   --> $DIR/ref-drop-tracking.rs:19:13
    |
@@ -22,6 +17,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |         let guard = &mut self.u;
    |             ^^^^^
+note: the lint level is defined here
+  --> $DIR/ref-drop-tracking.rs:4:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr b/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr
index 0157c8b7fe1..abf76711bf0 100644
--- a/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr
+++ b/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr
@@ -7,11 +7,6 @@ LL |
 LL |         other().await;
    |                ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/ref.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
   --> $DIR/ref.rs:21:13
    |
@@ -22,6 +17,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |         let guard = &mut self.u;
    |             ^^^^^
+note: the lint level is defined here
+  --> $DIR/ref.rs:6:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr b/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
index 438e6489e31..41ac09ea72a 100644
--- a/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
+++ b/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
@@ -7,11 +7,6 @@ LL |
 LL |         other().await;
    |                ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/ref.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
   --> $DIR/ref.rs:21:26
    |
@@ -22,6 +17,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |         let guard = &mut self.u;
    |                          ^^^^^^
+note: the lint level is defined here
+  --> $DIR/ref.rs:6:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/trait.stderr b/src/test/ui/lint/must_not_suspend/trait.stderr
index 60369430a3e..d64d25aae52 100644
--- a/src/test/ui/lint/must_not_suspend/trait.stderr
+++ b/src/test/ui/lint/must_not_suspend/trait.stderr
@@ -7,16 +7,16 @@ LL |     let _guard1 = r#impl();
 LL |     other().await;
    |            ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/trait.rs:3:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
   --> $DIR/trait.rs:21:9
    |
 LL |     let _guard1 = r#impl();
    |         ^^^^^^^
+note: the lint level is defined here
+  --> $DIR/trait.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: boxed `Wow` trait object held across a suspend point, but should not be
   --> $DIR/trait.rs:22:9
diff --git a/src/test/ui/lint/must_not_suspend/unit.stderr b/src/test/ui/lint/must_not_suspend/unit.stderr
index 42d037b350b..c967dbac56c 100644
--- a/src/test/ui/lint/must_not_suspend/unit.stderr
+++ b/src/test/ui/lint/must_not_suspend/unit.stderr
@@ -6,11 +6,6 @@ LL |     let _guard = bar();
 LL |     other().await;
    |            ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/unit.rs:3:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
   --> $DIR/unit.rs:20:9
    |
@@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |     let _guard = bar();
    |         ^^^^^^
+note: the lint level is defined here
+  --> $DIR/unit.rs:3:9
+   |
+LL | #![deny(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/must_not_suspend/warn.stderr b/src/test/ui/lint/must_not_suspend/warn.stderr
index 417c397dad0..fe551c6521d 100644
--- a/src/test/ui/lint/must_not_suspend/warn.stderr
+++ b/src/test/ui/lint/must_not_suspend/warn.stderr
@@ -6,11 +6,6 @@ LL |     let _guard = bar();
 LL |     other().await;
    |            ------ the value is held across this suspend point
    |
-note: the lint level is defined here
-  --> $DIR/warn.rs:4:9
-   |
-LL | #![warn(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
 note: You gotta use Umm's, ya know?
   --> $DIR/warn.rs:21:9
    |
@@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef
    |
 LL |     let _guard = bar();
    |         ^^^^^^
+note: the lint level is defined here
+  --> $DIR/warn.rs:4:9
+   |
+LL | #![warn(must_not_suspend)]
+   |         ^^^^^^^^^^^^^^^^
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/noop-method-call.rs b/src/test/ui/lint/noop-method-call.rs
index 9870c813572..89b29663595 100644
--- a/src/test/ui/lint/noop-method-call.rs
+++ b/src/test/ui/lint/noop-method-call.rs
@@ -46,6 +46,7 @@ fn main() {
 
 fn generic<T>(non_clone_type: &PlainType<T>) {
     non_clone_type.clone();
+    //~^ WARNING call to `.clone()` on a reference in this situation does nothing
 }
 
 fn non_generic(non_clone_type: &PlainType<u32>) {
diff --git a/src/test/ui/lint/noop-method-call.stderr b/src/test/ui/lint/noop-method-call.stderr
index 7f6f96bf1d1..6a904d01abc 100644
--- a/src/test/ui/lint/noop-method-call.stderr
+++ b/src/test/ui/lint/noop-method-call.stderr
@@ -4,12 +4,12 @@ warning: call to `.clone()` on a reference in this situation does nothing
 LL |     let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
    |                                                                       ^^^^^^^^ unnecessary method call
    |
+   = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
 note: the lint level is defined here
   --> $DIR/noop-method-call.rs:4:9
    |
 LL | #![warn(noop_method_call)]
    |         ^^^^^^^^^^^^^^^^
-   = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
 
 warning: call to `.deref()` on a reference in this situation does nothing
   --> $DIR/noop-method-call.rs:28:63
@@ -28,12 +28,20 @@ LL |     let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
    = note: the type `&PlainType<u32>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed
 
 warning: call to `.clone()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:52:19
+  --> $DIR/noop-method-call.rs:48:19
+   |
+LL |     non_clone_type.clone();
+   |                   ^^^^^^^^ unnecessary method call
+   |
+   = note: the type `&PlainType<T>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
+
+warning: call to `.clone()` on a reference in this situation does nothing
+  --> $DIR/noop-method-call.rs:53:19
    |
 LL |     non_clone_type.clone();
    |                   ^^^^^^^^ unnecessary method call
    |
    = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
 
-warning: 4 warnings emitted
+warning: 5 warnings emitted
 
diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
index 62d00fd6835..33aa95854e3 100644
--- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
+++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `A`, which is not FFI-safe
 LL |     pub fn a(_: A);
    |                 ^ not FFI-safe
    |
+   = note: opaque types have no C equivalent
 note: the lint level is defined here
   --> $DIR/opaque-ty-ffi-unsafe.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr
index 78145732105..a47877980a0 100644
--- a/src/test/ui/lint/outer-forbid.stderr
+++ b/src/test/ui/lint/outer-forbid.stderr
@@ -7,13 +7,13 @@ LL | #![forbid(unused, non_snake_case)]
 LL | #[allow(unused_variables)]
    |         ^^^^^^^^^^^^^^^^ overruled by previous forbid
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 note: the lint level is defined here
   --> $DIR/outer-forbid.rs:18:11
    |
 LL | #![forbid(forbidden_lint_groups)]
    |           ^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 
 error: allow(unused) incompatible with previous forbid
   --> $DIR/outer-forbid.rs:25:9
diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr
index bc0c5330324..e31d14c5596 100644
--- a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr
+++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr
@@ -1,4 +1,4 @@
-TokenStream [Ident { ident: "fn", span: #0 bytes(198..200) }, Ident { ident: "span_preservation", span: #0 bytes(201..218) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(218..220) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(228..231) }, Ident { ident: "tst", span: #0 bytes(232..235) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(236..237) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(238..241) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(241..242) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(242..243) }, Ident { ident: "match", span: #0 bytes(289..294) }, Ident { ident: "tst", span: #0 bytes(295..298) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(483..486) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(487..489) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(487..489) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(490..492) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(492..493) }, Ident { ident: "_", span: #0 bytes(502..503) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(504..506) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(504..506) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(507..509) }], span: #0 bytes(299..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(517..518) }], span: #0 bytes(222..562) }]
+TokenStream [Ident { ident: "fn", span: #0 bytes(198..200) }, Ident { ident: "span_preservation", span: #0 bytes(201..218) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(218..220) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(228..231) }, Ident { ident: "tst", span: #0 bytes(232..235) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(236..237) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(238..241) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(241..242) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(242..243) }, Ident { ident: "match", span: #0 bytes(289..294) }, Ident { ident: "tst", span: #0 bytes(295..298) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(483..486) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(487..488) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(488..489) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(490..492) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(492..493) }, Ident { ident: "_", span: #0 bytes(502..503) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(504..505) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(505..506) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(507..509) }], span: #0 bytes(299..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(517..518) }], span: #0 bytes(222..562) }]
 error: unnecessary trailing semicolon
   --> $DIR/redundant-semi-proc-macro.rs:9:19
    |
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr
index 370e51bf70a..2c35647b8a3 100644
--- a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr
+++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr
@@ -31,8 +31,8 @@ warning: this lint expectation is unfulfilled
 LL |     unused_mut,
    |     ^^^^^^^^^^
    |
-   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
    = note: this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered
+   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
 
 warning: this lint expectation is unfulfilled
   --> $DIR/expect_nested_lint_levels.rs:24:5
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr
index 9bfee79b03d..9a1c3e442bb 100644
--- a/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr
+++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr
@@ -4,9 +4,9 @@ warning: this lint expectation is unfulfilled
 LL | #![expect(unfulfilled_lint_expectations, reason = "idk why you would expect this")]
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
    = note: idk why you would expect this
    = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
+   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
 
 warning: this lint expectation is unfulfilled
   --> $DIR/expect_unfulfilled_expectation.rs:13:10
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr
index 82c1a4c08bb..e349e4081f8 100644
--- a/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr
+++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr
@@ -4,8 +4,8 @@ warning: this lint expectation is unfulfilled
 LL | #![expect(unused_variables, reason = "<This should fail and display this reason>")]
    |           ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
    = note: <This should fail and display this reason>
+   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr b/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr
index 06befcbb511..5942fa8aeb4 100644
--- a/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr
+++ b/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr
@@ -1,11 +1,3 @@
-warning: denote infinite loops with `loop { ... }`
-  --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5
-   |
-LL |     while true {
-   |     ^^^^^^^^^^ help: use `loop`
-   |
-   = note: requested on the command line with `--force-warn while-true`
-
 warning: unused variable: `x`
   --> $DIR/force_warn_expected_lints_fulfilled.rs:20:9
    |
@@ -36,5 +28,13 @@ LL |     let mut what_does_the_fox_say = "*ding* *deng* *dung*";
    |
    = note: requested on the command line with `--force-warn unused-mut`
 
+warning: denote infinite loops with `loop { ... }`
+  --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5
+   |
+LL |     while true {
+   |     ^^^^^^^^^^ help: use `loop`
+   |
+   = note: requested on the command line with `--force-warn while-true`
+
 warning: 5 warnings emitted
 
diff --git a/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
index 3bf8137dc6e..3e9d70821b5 100644
--- a/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
+++ b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr
@@ -4,12 +4,12 @@ error: unused attribute
 LL | #[allow(reason = "I want to allow something")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
    |
+   = note: attribute `allow` without any lints has no effect
 note: the lint level is defined here
   --> $DIR/lint-attribute-only-with-reason.rs:3:9
    |
 LL | #![deny(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = note: attribute `allow` without any lints has no effect
 
 error: unused attribute
   --> $DIR/lint-attribute-only-with-reason.rs:6:1
diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr
index 9ca034b71b2..884a4a45382 100644
--- a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr
+++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr
@@ -4,13 +4,13 @@ error: the usage of Script Group `Greek` in this crate consists solely of mixed
 LL | struct ΑctuallyNotLatin;
    |        ^^^^^^^^^^^^^^^^
    |
+   = note: the usage includes 'Α' (U+0391)
+   = note: please recheck to make sure their usages are indeed what you want
 note: the lint level is defined here
   --> $DIR/lint-mixed-script-confusables.rs:1:9
    |
 LL | #![deny(mixed_script_confusables)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the usage includes 'Α' (U+0391)
-   = note: please recheck to make sure their usages are indeed what you want
 
 error: the usage of Script Group `Cyrillic` in this crate consists solely of mixed script confusables
   --> $DIR/lint-mixed-script-confusables.rs:10:5
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
index 84ad32bddd5..49608c20524 100644
--- a/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
+++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr
@@ -7,15 +7,15 @@ LL |         true;
 LL |         foo!(warn_in_block)
    |         ------------------- in this macro invocation
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
 note: the lint level is defined here
   --> $DIR/semicolon-in-expressions-from-macros.rs:4:9
    |
 LL | #![warn(semicolon_in_expressions_from_macros)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
-   = note: macro invocations at the end of a block are treated as expressions
-   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
    = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: trailing semicolon in macro used in expression position
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
index d770a8c8f36..16c152eb23c 100644
--- a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
+++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
@@ -7,9 +7,9 @@ LL |         true;
 LL |         _ => foo!()
    |              ------ in this macro invocation
    |
-   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 1 warning emitted
diff --git a/src/test/ui/lint/trivial-cast-ice.rs b/src/test/ui/lint/trivial-cast-ice.rs
new file mode 100644
index 00000000000..f781fab2212
--- /dev/null
+++ b/src/test/ui/lint/trivial-cast-ice.rs
@@ -0,0 +1,12 @@
+// aux-build:trivial-cast-ice.rs
+// check-pass
+
+// Demonstrates the ICE in #102561
+
+#![deny(trivial_casts)]
+
+extern crate trivial_cast_ice;
+
+fn main() {
+    trivial_cast_ice::foo!();
+}
diff --git a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr
index f7c42acb344..5087807b6c7 100644
--- a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr
+++ b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr
@@ -4,12 +4,12 @@ error: trivial numeric cast: `i32` as `i32`
 LL |     let lugubrious = 12i32 as i32;
    |                      ^^^^^^^^^^^^
    |
+   = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
 note: the lint level is defined here
   --> $DIR/trivial-casts-featuring-type-ascription.rs:1:24
    |
 LL | #![deny(trivial_casts, trivial_numeric_casts)]
    |                        ^^^^^^^^^^^^^^^^^^^^^
-   = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
 
 error: trivial cast: `&u32` as `*const u32`
   --> $DIR/trivial-casts-featuring-type-ascription.rs:8:13
@@ -17,12 +17,12 @@ error: trivial cast: `&u32` as `*const u32`
 LL |     let _ = haunted as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^
    |
+   = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
 note: the lint level is defined here
   --> $DIR/trivial-casts-featuring-type-ascription.rs:1:9
    |
 LL | #![deny(trivial_casts, trivial_numeric_casts)]
    |         ^^^^^^^^^^^^^
-   = help: cast can be replaced by coercion; this might require type ascription or a temporary variable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/trivial-casts.stderr b/src/test/ui/lint/trivial-casts.stderr
index 1544f553cee..7ace353de68 100644
--- a/src/test/ui/lint/trivial-casts.stderr
+++ b/src/test/ui/lint/trivial-casts.stderr
@@ -4,12 +4,12 @@ error: trivial numeric cast: `i32` as `i32`
 LL |     let lugubrious = 12i32 as i32;
    |                      ^^^^^^^^^^^^
    |
+   = help: cast can be replaced by coercion; this might require a temporary variable
 note: the lint level is defined here
   --> $DIR/trivial-casts.rs:1:24
    |
 LL | #![deny(trivial_casts, trivial_numeric_casts)]
    |                        ^^^^^^^^^^^^^^^^^^^^^
-   = help: cast can be replaced by coercion; this might require a temporary variable
 
 error: trivial cast: `&u32` as `*const u32`
   --> $DIR/trivial-casts.rs:7:13
@@ -17,12 +17,12 @@ error: trivial cast: `&u32` as `*const u32`
 LL |     let _ = haunted as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^
    |
+   = help: cast can be replaced by coercion; this might require a temporary variable
 note: the lint level is defined here
   --> $DIR/trivial-casts.rs:1:9
    |
 LL | #![deny(trivial_casts, trivial_numeric_casts)]
    |         ^^^^^^^^^^^^^
-   = help: cast can be replaced by coercion; this might require a temporary variable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/trivial_casts.stderr b/src/test/ui/lint/trivial_casts.stderr
index 8a216360f4e..74f962835c2 100644
--- a/src/test/ui/lint/trivial_casts.stderr
+++ b/src/test/ui/lint/trivial_casts.stderr
@@ -4,12 +4,12 @@ error: trivial numeric cast: `i32` as `i32`
 LL |     let _ = 42_i32 as i32;
    |             ^^^^^^^^^^^^^
    |
+   = help: cast can be replaced by coercion; this might require a temporary variable
 note: the lint level is defined here
   --> $DIR/trivial_casts.rs:4:24
    |
 LL | #![deny(trivial_casts, trivial_numeric_casts)]
    |                        ^^^^^^^^^^^^^^^^^^^^^
-   = help: cast can be replaced by coercion; this might require a temporary variable
 
 error: trivial numeric cast: `u8` as `u8`
   --> $DIR/trivial_casts.rs:19:13
@@ -25,12 +25,12 @@ error: trivial cast: `&u32` as `*const u32`
 LL |     let _ = x as *const u32;
    |             ^^^^^^^^^^^^^^^
    |
+   = help: cast can be replaced by coercion; this might require a temporary variable
 note: the lint level is defined here
   --> $DIR/trivial_casts.rs:4:9
    |
 LL | #![deny(trivial_casts, trivial_numeric_casts)]
    |         ^^^^^^^^^^^^^
-   = help: cast can be replaced by coercion; this might require a temporary variable
 
 error: trivial cast: `&mut u32` as `*mut u32`
   --> $DIR/trivial_casts.rs:28:13
diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr
index 8a31fd44746..62cb1f7f4aa 100644
--- a/src/test/ui/lint/type-overflow.stderr
+++ b/src/test/ui/lint/type-overflow.stderr
@@ -4,13 +4,13 @@ warning: literal out of range for `i8`
 LL |     let error = 255i8;
    |                 ^^^^^
    |
+   = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127`
+   = help: consider using the type `u8` instead
 note: the lint level is defined here
   --> $DIR/type-overflow.rs:2:9
    |
 LL | #![warn(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127`
-   = help: consider using the type `u8` instead
 
 warning: literal out of range for `i8`
   --> $DIR/type-overflow.rs:10:16
diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr
index 97dbec2861c..346f49b921e 100644
--- a/src/test/ui/lint/unaligned_references.stderr
+++ b/src/test/ui/lint/unaligned_references.stderr
@@ -4,15 +4,15 @@ error: reference to packed field is unaligned
 LL |         let _ = &good.ptr;
    |                 ^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error: reference to packed field is unaligned
   --> $DIR/unaligned_references.rs:24:17
@@ -111,15 +111,15 @@ error: reference to packed field is unaligned
 LL |         let _ = &good.ptr;
    |                 ^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -128,15 +128,15 @@ error: reference to packed field is unaligned
 LL |         let _ = &good.data;
    |                 ^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -145,15 +145,15 @@ error: reference to packed field is unaligned
 LL |         let _ = &good.data as *const _;
    |                 ^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -162,15 +162,15 @@ error: reference to packed field is unaligned
 LL |         let _: *const _ = &good.data;
    |                           ^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -179,15 +179,15 @@ error: reference to packed field is unaligned
 LL |         let _ = good.data.clone();
    |                 ^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -196,15 +196,15 @@ error: reference to packed field is unaligned
 LL |         let _ = &good.data2[0];
    |                 ^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -213,15 +213,15 @@ error: reference to packed field is unaligned
 LL |         let _ = &packed2.x;
    |                 ^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -230,15 +230,15 @@ error: reference to packed field is unaligned
 LL |         let _ref = &m1.1.a;
    |                    ^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -247,13 +247,13 @@ error: reference to packed field is unaligned
 LL |         let _ref = &m2.1.a;
    |                    ^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references.rs:1:9
    |
 LL | #![deny(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
diff --git a/src/test/ui/lint/unaligned_references_external_macro.stderr b/src/test/ui/lint/unaligned_references_external_macro.stderr
index 1262c21ee78..c46ca6742a5 100644
--- a/src/test/ui/lint/unaligned_references_external_macro.stderr
+++ b/src/test/ui/lint/unaligned_references_external_macro.stderr
@@ -10,6 +10,10 @@ LL | |     }
 LL | | }
    | |_^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references_external_macro.rs:5:1
    |
@@ -21,10 +25,6 @@ LL | |         pub field: u16
 LL | |     }
 LL | | }
    | |_^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
    = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
@@ -42,6 +42,10 @@ LL | |     }
 LL | | }
    | |_^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/unaligned_references_external_macro.rs:5:1
    |
@@ -53,9 +57,5 @@ LL | |         pub field: u16
 LL | |     }
 LL | | }
    | |_^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
    = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr
index e021f500c66..762834b97b9 100644
--- a/src/test/ui/lint/unreachable_pub.stderr
+++ b/src/test/ui/lint/unreachable_pub.stderr
@@ -6,12 +6,12 @@ LL |     pub use std::fmt;
    |     |
    |     help: consider restricting its visibility: `pub(crate)`
    |
+   = help: or consider exporting it for use by other crates
 note: the lint level is defined here
   --> $DIR/unreachable_pub.rs:4:9
    |
 LL | #![warn(unreachable_pub)]
    |         ^^^^^^^^^^^^^^^
-   = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
   --> $DIR/unreachable_pub.rs:9:24
diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
index 26fa6eb9b9b..fe2e3afc82e 100644
--- a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -49,8 +49,8 @@ warning: value assigned to `hours_are_suns` is never read
 LL |         hours_are_suns = false;
    |         ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
    = help: maybe it is overwritten before being read?
+   = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `fire`
   --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32
diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.stderr b/src/test/ui/lint/unused/must-use-box-from-raw.stderr
index 7769f09aa52..011acc3bf5d 100644
--- a/src/test/ui/lint/unused/must-use-box-from-raw.stderr
+++ b/src/test/ui/lint/unused/must-use-box-from-raw.stderr
@@ -4,12 +4,12 @@ warning: unused return value of `Box::<T>::from_raw` that must be used
 LL |     Box::from_raw(ptr);
    |     ^^^^^^^^^^^^^^^^^^^
    |
+   = note: call `drop(from_raw(ptr))` if you intend to drop the `Box`
 note: the lint level is defined here
   --> $DIR/must-use-box-from-raw.rs:5:9
    |
 LL | #![warn(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
-   = note: call `drop(from_raw(ptr))` if you intend to drop the `Box`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
index 76978d29dc8..f5199f43c74 100644
--- a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
+++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
@@ -4,12 +4,12 @@ error: unused implementer of `Iterator` that must be used
 LL |    iterator();
    |    ^^^^^^^^^^^
    |
+   = note: iterators are lazy and do nothing unless consumed
 note: the lint level is defined here
   --> $DIR/must_use-in-stdlib-traits.rs:1:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
-   = note: iterators are lazy and do nothing unless consumed
 
 error: unused implementer of `Future` that must be used
   --> $DIR/must_use-in-stdlib-traits.rs:43:4
diff --git a/src/test/ui/lint/unused/must_use-tuple.stderr b/src/test/ui/lint/unused/must_use-tuple.stderr
index e5709a5f0af..63e0318fbb5 100644
--- a/src/test/ui/lint/unused/must_use-tuple.stderr
+++ b/src/test/ui/lint/unused/must_use-tuple.stderr
@@ -4,12 +4,12 @@ error: unused `Result` in tuple element 0 that must be used
 LL |     (Ok::<(), ()>(()),);
    |      ^^^^^^^^^^^^^^^^
    |
+   = note: this `Result` may be an `Err` variant, which should be handled
 note: the lint level is defined here
   --> $DIR/must_use-tuple.rs:1:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
-   = note: this `Result` may be an `Err` variant, which should be handled
 
 error: unused `Result` in tuple element 0 that must be used
   --> $DIR/must_use-tuple.rs:10:6
diff --git a/src/test/ui/lint/unused/unused-attr-duplicate.stderr b/src/test/ui/lint/unused/unused-attr-duplicate.stderr
index f592323b550..769b174874b 100644
--- a/src/test/ui/lint/unused/unused-attr-duplicate.stderr
+++ b/src/test/ui/lint/unused/unused-attr-duplicate.stderr
@@ -4,16 +4,16 @@ error: unused attribute
 LL | #[no_link]
    | ^^^^^^^^^^ help: remove this attribute
    |
-note: the lint level is defined here
-  --> $DIR/unused-attr-duplicate.rs:12:9
-   |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
 note: attribute also specified here
   --> $DIR/unused-attr-duplicate.rs:32:1
    |
 LL | #[no_link]
    | ^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/unused-attr-duplicate.rs:12:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
 
 error: unused attribute
   --> $DIR/unused-attr-duplicate.rs:37:1
diff --git a/src/test/ui/lint/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr
index 265d3e8e075..4362abd2037 100644
--- a/src/test/ui/lint/unused/unused-closure.stderr
+++ b/src/test/ui/lint/unused/unused-closure.stderr
@@ -6,12 +6,12 @@ LL | |         println!("Hello!");
 LL | |     };
    | |______^
    |
+   = note: closures are lazy and do nothing unless called
 note: the lint level is defined here
   --> $DIR/unused-closure.rs:6:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
-   = note: closures are lazy and do nothing unless called
 
 error: unused implementer of `Future` that must be used
   --> $DIR/unused-closure.rs:13:5
diff --git a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
index 1a022c30938..078b780d8b9 100644
--- a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
+++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
@@ -23,12 +23,12 @@ LL |
 LL |         _ => false,
    |         ---------- rustdoc does not generate documentation for match arms
    |
+   = help: use `//` for a plain comment
 note: the lint level is defined here
   --> $DIR/unused-doc-comments-edge-cases.rs:1:9
    |
 LL | #![deny(unused_doc_comments)]
    |         ^^^^^^^^^^^^^^^^^^^
-   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/unused-doc-comments-edge-cases.rs:23:5
diff --git a/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr
index f4f5bb71e55..26b1c2b058c 100644
--- a/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr
+++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr
@@ -8,12 +8,12 @@ LL | |     /// line3
    |       |
    |       rustdoc does not generate documentation for macro invocations
    |
+   = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 note: the lint level is defined here
   --> $DIR/unused-doc-comments-for-macros.rs:1:9
    |
 LL | #![deny(unused_doc_comments)]
    |         ^^^^^^^^^^^^^^^^^^^
-   = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 
 error: unused doc comment
   --> $DIR/unused-doc-comments-for-macros.rs:13:5
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
index dd112c23e5d..ce959ddbc46 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
@@ -4,16 +4,16 @@ error: unused attribute `must_use`
 LL | #[must_use]
    | ^^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/unused_attributes-must_use.rs:2:9
-   |
-LL | #![deny(unused_attributes, unused_must_use)]
-   |         ^^^^^^^^^^^^^^^^^
 note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm`
   --> $DIR/unused_attributes-must_use.rs:59:1
    |
 LL | global_asm!("");
    | ^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/unused_attributes-must_use.rs:2:9
+   |
+LL | #![deny(unused_attributes, unused_must_use)]
+   |         ^^^^^^^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an extern crate
   --> $DIR/unused_attributes-must_use.rs:5:1
diff --git a/src/test/ui/lint/unused/useless-comment.stderr b/src/test/ui/lint/unused/useless-comment.stderr
index 0054426fb1e..8bb5bdaeb25 100644
--- a/src/test/ui/lint/unused/useless-comment.stderr
+++ b/src/test/ui/lint/unused/useless-comment.stderr
@@ -4,12 +4,12 @@ error: unused doc comment
 LL | /// foo
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations
    |
+   = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 note: the lint level is defined here
   --> $DIR/useless-comment.rs:3:9
    |
 LL | #![deny(unused_doc_comments)]
    |         ^^^^^^^^^^^^^^^^^^^
-   = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:32:5
diff --git a/src/test/ui/liveness/liveness-asm.stderr b/src/test/ui/liveness/liveness-asm.stderr
index d052aca338c..57d89e44dcb 100644
--- a/src/test/ui/liveness/liveness-asm.stderr
+++ b/src/test/ui/liveness/liveness-asm.stderr
@@ -4,12 +4,12 @@ warning: value assigned to `src` is never read
 LL |     asm!("/*{0}*/", inout(reg) src);
    |                                ^^^
    |
+   = help: maybe it is overwritten before being read?
 note: the lint level is defined here
   --> $DIR/liveness-asm.rs:7:9
    |
 LL | #![warn(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
-   = help: maybe it is overwritten before being read?
 
 warning: value assigned to `src` is never read
   --> $DIR/liveness-asm.rs:24:39
diff --git a/src/test/ui/liveness/liveness-consts.stderr b/src/test/ui/liveness/liveness-consts.stderr
index 16209d16c19..6199ea96c98 100644
--- a/src/test/ui/liveness/liveness-consts.stderr
+++ b/src/test/ui/liveness/liveness-consts.stderr
@@ -4,13 +4,13 @@ warning: variable `a` is assigned to, but never used
 LL |     let mut a = 0;
    |             ^
    |
+   = note: consider using `_a` instead
 note: the lint level is defined here
   --> $DIR/liveness-consts.rs:2:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
-   = note: consider using `_a` instead
 
 warning: value assigned to `b` is never read
   --> $DIR/liveness-consts.rs:17:5
@@ -18,8 +18,8 @@ warning: value assigned to `b` is never read
 LL |     b += 1;
    |     ^
    |
-   = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
    = help: maybe it is overwritten before being read?
+   = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `e`
   --> $DIR/liveness-consts.rs:24:13
diff --git a/src/test/ui/liveness/liveness-dead.stderr b/src/test/ui/liveness/liveness-dead.stderr
index 12680ab1156..de6d5bd993d 100644
--- a/src/test/ui/liveness/liveness-dead.stderr
+++ b/src/test/ui/liveness/liveness-dead.stderr
@@ -4,12 +4,12 @@ error: value assigned to `x` is never read
 LL |     let mut x: isize = 3;
    |             ^
    |
+   = help: maybe it is overwritten before being read?
 note: the lint level is defined here
   --> $DIR/liveness-dead.rs:2:9
    |
 LL | #![deny(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
-   = help: maybe it is overwritten before being read?
 
 error: value assigned to `x` is never read
   --> $DIR/liveness-dead.rs:17:5
diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.rs b/src/test/ui/liveness/liveness-return-last-stmt-semi.rs
index e8909c4a5ae..dff859429c9 100644
--- a/src/test/ui/liveness/liveness-return-last-stmt-semi.rs
+++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.rs
@@ -1,4 +1,3 @@
-//
 // regression test for #8005
 
 macro_rules! test { () => { fn foo() -> i32 { 1; } } }
diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr
index 82d136bd318..de0843aa637 100644
--- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr
+++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/liveness-return-last-stmt-semi.rs:7:19
+  --> $DIR/liveness-return-last-stmt-semi.rs:6:19
    |
 LL | fn no_return() -> i32 {}
    |    ---------      ^^^ expected `i32`, found `()`
@@ -7,17 +7,17 @@ LL | fn no_return() -> i32 {}
    |    implicitly returns `()` as its body has no tail or `return` expression
 
 error[E0308]: mismatched types
-  --> $DIR/liveness-return-last-stmt-semi.rs:9:19
+  --> $DIR/liveness-return-last-stmt-semi.rs:8:19
    |
 LL | fn bar(x: u32) -> u32 {
    |    ---            ^^^ expected `u32`, found `()`
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 LL |     x * 2;
-   |          - help: remove this semicolon
+   |          - help: remove this semicolon to return this value
 
 error[E0308]: mismatched types
-  --> $DIR/liveness-return-last-stmt-semi.rs:13:19
+  --> $DIR/liveness-return-last-stmt-semi.rs:12:19
    |
 LL | fn baz(x: u64) -> u32 {
    |    ---            ^^^ expected `u32`, found `()`
@@ -25,7 +25,7 @@ LL | fn baz(x: u64) -> u32 {
    |    implicitly returns `()` as its body has no tail or `return` expression
 
 error[E0308]: mismatched types
-  --> $DIR/liveness-return-last-stmt-semi.rs:4:41
+  --> $DIR/liveness-return-last-stmt-semi.rs:3:41
    |
 LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } }
    |                                ---      ^^^ expected `i32`, found `()`
diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr
index 4a6122681a9..f6c478ddbc7 100644
--- a/src/test/ui/liveness/liveness-unused.stderr
+++ b/src/test/ui/liveness/liveness-unused.stderr
@@ -57,12 +57,12 @@ error: value assigned to `x` is never read
 LL |     x += 4;
    |     ^
    |
+   = help: maybe it is overwritten before being read?
 note: the lint level is defined here
   --> $DIR/liveness-unused.rs:3:9
    |
 LL | #![deny(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
-   = help: maybe it is overwritten before being read?
 
 error: variable `z` is assigned to, but never used
   --> $DIR/liveness-unused.rs:37:13
diff --git a/src/test/ui/liveness/liveness-upvars.stderr b/src/test/ui/liveness/liveness-upvars.stderr
index cb104e0a3fd..82f62371ec5 100644
--- a/src/test/ui/liveness/liveness-upvars.stderr
+++ b/src/test/ui/liveness/liveness-upvars.stderr
@@ -4,13 +4,13 @@ warning: value assigned to `last` is never read
 LL |         last = Some(s);
    |         ^^^^
    |
+   = help: maybe it is overwritten before being read?
 note: the lint level is defined here
   --> $DIR/liveness-upvars.rs:4:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]`
-   = help: maybe it is overwritten before being read?
 
 warning: unused variable: `last`
   --> $DIR/liveness-upvars.rs:10:9
@@ -18,8 +18,8 @@ warning: unused variable: `last`
 LL |         last = Some(s);
    |         ^^^^
    |
-   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
    = help: did you mean to capture by reference instead?
+   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `sum`
   --> $DIR/liveness-upvars.rs:22:9
diff --git a/src/test/ui/macros/issue-39404.stderr b/src/test/ui/macros/issue-39404.stderr
index d2f2a823c2a..3886a70bb15 100644
--- a/src/test/ui/macros/issue-39404.stderr
+++ b/src/test/ui/macros/issue-39404.stderr
@@ -4,9 +4,9 @@ error: missing fragment specifier
 LL | macro_rules! m { ($i) => {} }
    |                   ^^
    |
-   = note: `#[deny(missing_fragment_specifier)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+   = note: `#[deny(missing_fragment_specifier)]` on by default
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/issue-84195-lint-anon-const.stderr b/src/test/ui/macros/issue-84195-lint-anon-const.stderr
index 39485d74e5e..306c08b1357 100644
--- a/src/test/ui/macros/issue-84195-lint-anon-const.stderr
+++ b/src/test/ui/macros/issue-84195-lint-anon-const.stderr
@@ -7,13 +7,13 @@ LL |     () => { 0; };
 LL |     let val: [u8; len!()] = [];
    |                   ------ in this macro invocation
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
 note: the lint level is defined here
   --> $DIR/issue-84195-lint-anon-const.rs:5:9
    |
 LL | #![deny(semicolon_in_expressions_from_macros)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
    = note: this error originates in the macro `len` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/macros/lint-trailing-macro-call.stderr b/src/test/ui/macros/lint-trailing-macro-call.stderr
index a98a559c8af..6ab121f7c06 100644
--- a/src/test/ui/macros/lint-trailing-macro-call.stderr
+++ b/src/test/ui/macros/lint-trailing-macro-call.stderr
@@ -7,11 +7,11 @@ LL |         #[cfg(FALSE)] 25;
 LL |     expand_it!()
    |     ------------ in this macro invocation
    |
-   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
    = note: macro invocations at the end of a block are treated as expressions
    = note: to ignore the value produced by the macro, add a semicolon after the invocation of `expand_it`
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = note: this warning originates in the macro `expand_it` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 1 warning emitted
diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr
index 5dc17807031..2a2e0c6c66a 100644
--- a/src/test/ui/macros/macro-context.stderr
+++ b/src/test/ui/macros/macro-context.stderr
@@ -73,9 +73,9 @@ LL |     () => ( i ; typeof );
 LL |     let i = m!();
    |             ---- in this macro invocation
    |
-   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 6 previous errors; 1 warning emitted
diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr
index 1840babd61d..1023189eaa3 100644
--- a/src/test/ui/macros/macro-in-expression-context.stderr
+++ b/src/test/ui/macros/macro-in-expression-context.stderr
@@ -20,11 +20,11 @@ LL |         assert_eq!("A", "A");
 LL |     foo!()
    |     ------ in this macro invocation
    |
-   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
    = note: macro invocations at the end of a block are treated as expressions
    = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
    = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr
index 48b9bc6ff6a..ef7261c0239 100644
--- a/src/test/ui/macros/macro-match-nonterminal.stderr
+++ b/src/test/ui/macros/macro-match-nonterminal.stderr
@@ -10,9 +10,9 @@ error: missing fragment specifier
 LL |     ($a, $b) => {
    |        ^
    |
-   = note: `#[deny(missing_fragment_specifier)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+   = note: `#[deny(missing_fragment_specifier)]` on by default
 
 error: missing fragment specifier
   --> $DIR/macro-match-nonterminal.rs:2:10
diff --git a/src/test/ui/macros/macro-missing-fragment-deduplication.stderr b/src/test/ui/macros/macro-missing-fragment-deduplication.stderr
index 7622ca054c8..3b9e716e194 100644
--- a/src/test/ui/macros/macro-missing-fragment-deduplication.stderr
+++ b/src/test/ui/macros/macro-missing-fragment-deduplication.stderr
@@ -10,9 +10,9 @@ error: missing fragment specifier
 LL |     ($name) => {}
    |      ^^^^^
    |
-   = note: `#[deny(missing_fragment_specifier)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+   = note: `#[deny(missing_fragment_specifier)]` on by default
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/macro-missing-fragment.stderr b/src/test/ui/macros/macro-missing-fragment.stderr
index 1bf6f04ec7f..2aa1e58f6b1 100644
--- a/src/test/ui/macros/macro-missing-fragment.stderr
+++ b/src/test/ui/macros/macro-missing-fragment.stderr
@@ -10,13 +10,13 @@ warning: missing fragment specifier
 LL |     ( $( any_token $field_rust_type )* ) => {};
    |                    ^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 note: the lint level is defined here
   --> $DIR/macro-missing-fragment.rs:1:9
    |
 LL | #![warn(missing_fragment_specifier)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
 
 warning: missing fragment specifier
   --> $DIR/macro-missing-fragment.rs:12:7
diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.stderr b/src/test/ui/macros/macro-or-patterns-back-compat.stderr
index 9a5b8009f32..e04dfefa4e8 100644
--- a/src/test/ui/macros/macro-or-patterns-back-compat.stderr
+++ b/src/test/ui/macros/macro-or-patterns-back-compat.stderr
@@ -4,13 +4,13 @@ error: the meaning of the `pat` fragment specifier is changing in Rust 2021, whi
 LL | macro_rules! foo { ($x:pat | $y:pat) => {} }
    |                     ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>
 note: the lint level is defined here
   --> $DIR/macro-or-patterns-back-compat.rs:4:9
    |
 LL | #![deny(rust_2021_incompatible_or_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>
 
 error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
   --> $DIR/macro-or-patterns-back-compat.rs:13:23
diff --git a/src/test/ui/macros/macro-use-all-and-none.stderr b/src/test/ui/macros/macro-use-all-and-none.stderr
index 6de7ffb2f63..00b10dccd00 100644
--- a/src/test/ui/macros/macro-use-all-and-none.stderr
+++ b/src/test/ui/macros/macro-use-all-and-none.stderr
@@ -4,12 +4,12 @@ warning: unused attribute
 LL | #[macro_use()]
    | ^^^^^^^^^^^^^^ help: remove this attribute
    |
+   = note: attribute `macro_use` with an empty list has no effect
 note: the lint level is defined here
   --> $DIR/macro-use-all-and-none.rs:4:9
    |
 LL | #![warn(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
-   = note: attribute `macro_use` with an empty list has no effect
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs
index e7a01f105de..140cc5b0fd8 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.rs
+++ b/src/test/ui/macros/macros-nonfatal-errors.rs
@@ -116,3 +116,24 @@ fn main() {
 
     trace_macros!(invalid); //~ ERROR
 }
+
+/// Check that `#[derive(Default)]` does use a `T : Default` bound when the
+/// `#[default]` variant is `#[non_exhaustive]` (should this end up allowed).
+const _: () = {
+    #[derive(Default)]
+    enum NonExhaustiveDefaultGeneric<T> {
+        #[default]
+        #[non_exhaustive]
+        Foo, //~ ERROR default variant must be exhaustive
+        Bar(T),
+    }
+
+    fn assert_impls_default<T: Default>() {}
+
+    enum NotDefault {}
+
+    // Note: the `derive(Default)` currently bails early enough for trait-checking
+    // not to happen. Should it bail late enough, or even pass, make sure to
+    // assert that the following line fails.
+    let _ = assert_impls_default::<NonExhaustiveDefaultGeneric<NotDefault>>;
+};
diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr
index b3c6d07f967..d42f6c179b7 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.stderr
+++ b/src/test/ui/macros/macros-nonfatal-errors.stderr
@@ -215,11 +215,21 @@ error: trace_macros! accepts only `true` or `false`
 LL |     trace_macros!(invalid);
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
+error: default variant must be exhaustive
+  --> $DIR/macros-nonfatal-errors.rs:127:9
+   |
+LL |         #[non_exhaustive]
+   |         ----------------- declared `#[non_exhaustive]` here
+LL |         Foo,
+   |         ^^^
+   |
+   = help: consider a manual implementation of `Default`
+
 error: cannot find macro `llvm_asm` in this scope
   --> $DIR/macros-nonfatal-errors.rs:99:5
    |
 LL |     llvm_asm!(invalid);
    |     ^^^^^^^^
 
-error: aborting due to 27 previous errors
+error: aborting due to 28 previous errors
 
diff --git a/src/test/ui/macros/must-use-in-macro-55516.stderr b/src/test/ui/macros/must-use-in-macro-55516.stderr
index b56b00cc7d9..8878b0eea0f 100644
--- a/src/test/ui/macros/must-use-in-macro-55516.stderr
+++ b/src/test/ui/macros/must-use-in-macro-55516.stderr
@@ -4,8 +4,8 @@ warning: unused `Result` that must be used
 LL |     write!(&mut example, "{}", 42);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-W unused-must-use` implied by `-W unused`
    = note: this `Result` may be an `Err` variant, which should be handled
+   = note: `-W unused-must-use` implied by `-W unused`
    = note: this warning originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 1 warning emitted
diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index 8c2625bdf0d..9bfbe7ebafd 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -4,9 +4,9 @@ error: attribute must be of the form `#[doc(hidden|inline|...)]` or `#[doc = "st
 LL | #[doc]
    | ^^^^^^
    |
-   = note: `#[deny(ill_formed_attribute_input)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
+   = note: `#[deny(ill_formed_attribute_input)]` on by default
 
 error: attribute must be of the form `#[ignore]` or `#[ignore = "reason"]`
   --> $DIR/malformed-regressions.rs:3:1
diff --git a/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr b/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr
index fca98662708..649e58915d0 100644
--- a/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr
+++ b/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/match/issue-41255.stderr b/src/test/ui/match/issue-41255.stderr
index bf81c8d371c..596d6fad38b 100644
--- a/src/test/ui/match/issue-41255.stderr
+++ b/src/test/ui/match/issue-41255.stderr
@@ -4,13 +4,13 @@ error: floating-point types cannot be used in patterns
 LL |         5.0 => {},
    |         ^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
 note: the lint level is defined here
   --> $DIR/issue-41255.rs:6:11
    |
 LL | #![forbid(illegal_floating_point_literal_pattern)]
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
 
 error: floating-point types cannot be used in patterns
   --> $DIR/issue-41255.rs:13:9
diff --git a/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr b/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr
index 9e07d5ea31e..394c1ac3c09 100644
--- a/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr
+++ b/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr
@@ -7,13 +7,13 @@ LL |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
 LL |     S.late::<'static>(&0, &0);
    |              ^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
 note: the lint level is defined here
   --> $DIR/method-call-lifetime-args-lint-fail.rs:1:9
    |
 LL | #![deny(late_bound_lifetime_arguments)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
 
 error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-lint-fail.rs:26:14
diff --git a/src/test/ui/methods/method-call-lifetime-args-lint.stderr b/src/test/ui/methods/method-call-lifetime-args-lint.stderr
index f31f510a3a7..b4fc2d71761 100644
--- a/src/test/ui/methods/method-call-lifetime-args-lint.stderr
+++ b/src/test/ui/methods/method-call-lifetime-args-lint.stderr
@@ -7,13 +7,13 @@ LL |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
 LL |     S.late::<'static>(&0, &0);
    |              ^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
 note: the lint level is defined here
   --> $DIR/method-call-lifetime-args-lint.rs:1:9
    |
 LL | #![deny(late_bound_lifetime_arguments)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
 
 error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
   --> $DIR/method-call-lifetime-args-lint.rs:16:23
diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr
index 78af19586a1..62f20d6d50c 100644
--- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr
+++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr
@@ -17,9 +17,9 @@ LL |     0.clone::<'a>();
 LL |     fn clone(&self) -> Self;
    |              - the late bound lifetime parameter is introduced here
    |
-   = note: `#[warn(late_bound_lifetime_arguments)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
+   = note: `#[warn(late_bound_lifetime_arguments)]` on by default
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
index 59075397ea5..82addab9479 100644
--- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
+++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals, unsized_fn_params)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0308]: mismatched types
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24
diff --git a/src/test/ui/mir/thir-constparam-temp.stderr b/src/test/ui/mir/thir-constparam-temp.stderr
index ed2766c000e..b77d67e084f 100644
--- a/src/test/ui/mir/thir-constparam-temp.stderr
+++ b/src/test/ui/mir/thir-constparam-temp.stderr
@@ -4,7 +4,6 @@ warning: taking a mutable reference to a `const` item
 LL |     YIKES.mut_self()
    |     ^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(const_item_mutation)]` on by default
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: mutable reference created due to call to this method
@@ -17,6 +16,7 @@ note: `const` item defined here
    |
 LL | fn foo<const YIKES: Yikes>() {
    |        ^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(const_item_mutation)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/modules/special_module_name.stderr b/src/test/ui/modules/special_module_name.stderr
index 8b3da29386d..bc4b4f1b318 100644
--- a/src/test/ui/modules/special_module_name.stderr
+++ b/src/test/ui/modules/special_module_name.stderr
@@ -20,9 +20,9 @@ warning: found module declaration for lib.rs
 LL | mod lib;
    | ^^^^^^^^
    |
-   = note: `#[warn(special_module_name)]` on by default
    = note: lib.rs is the root of this crate's library target
    = help: to refer to it from other targets, use the library's name as the path
+   = note: `#[warn(special_module_name)]` on by default
 
 warning: found module declaration for main.rs
   --> $DIR/special_module_name.rs:4:1
diff --git a/src/test/ui/moves/move-out-of-slice-2.stderr b/src/test/ui/moves/move-out-of-slice-2.stderr
index 93b0dcfc2d1..46357ce6f2e 100644
--- a/src/test/ui/moves/move-out-of-slice-2.stderr
+++ b/src/test/ui/moves/move-out-of-slice-2.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0508]: cannot move out of type `[A]`, a non-copy slice
   --> $DIR/move-out-of-slice-2.rs:10:11
diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr
index 3c0daa4c55f..0910e9ad77a 100644
--- a/src/test/ui/never_type/issue-52443.stderr
+++ b/src/test/ui/never_type/issue-52443.stderr
@@ -47,8 +47,8 @@ LL |     [(); { for _ in 0usize.. {}; 0}];
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
    |
-LL | impl<I: ~const Iterator> const IntoIterator for I {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<I: Iterator> const IntoIterator for I {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error[E0658]: mutable references are not allowed in constants
diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr
index 70a83e46ff0..1b35165db45 100644
--- a/src/test/ui/nll/issue-48623-generator.stderr
+++ b/src/test/ui/nll/issue-48623-generator.stderr
@@ -4,8 +4,8 @@ warning: unused generator that must be used
 LL |     move || { d; yield; &mut *r };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unused_must_use)]` on by default
    = note: generators are lazy and do nothing unless resumed
+   = note: `#[warn(unused_must_use)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/nll/issue-51191.stderr b/src/test/ui/nll/issue-51191.stderr
index 9f4e971f909..63ca6ae5c28 100644
--- a/src/test/ui/nll/issue-51191.stderr
+++ b/src/test/ui/nll/issue-51191.stderr
@@ -7,8 +7,8 @@ LL |     fn bar(self: &mut Self) {
 LL |         (&mut self).bar();
    |         ----------------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
   --> $DIR/issue-51191.rs:7:9
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
index 330c6fafa2d..6a8a1ad1caa 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -1,14 +1,14 @@
-error[E0700]: hidden type for `Opaque(DefId(0:11 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReStatic, T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds
+error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReStatic, T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds
   --> $DIR/impl-trait-captures.rs:11:5
    |
 LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
-   |                  -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_)) T` captures the anonymous lifetime defined here
+   |                  -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_)) T` captures the anonymous lifetime defined here
 LL |     x
    |     ^
    |
-help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_))` lifetime bound
+help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_))` lifetime bound
    |
-LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_)) {
+LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_)) {
    |                                      ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to previous error
diff --git a/src/test/ui/no-patterns-in-args-2.stderr b/src/test/ui/no-patterns-in-args-2.stderr
index 98932349a79..6adcbb9dccd 100644
--- a/src/test/ui/no-patterns-in-args-2.stderr
+++ b/src/test/ui/no-patterns-in-args-2.stderr
@@ -10,13 +10,13 @@ error: patterns aren't allowed in functions without bodies
 LL |     fn f1(mut arg: u8);
    |           ^^^^^^^ help: remove `mut` from the parameter: `arg`
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
 note: the lint level is defined here
   --> $DIR/no-patterns-in-args-2.rs:1:9
    |
 LL | #![deny(patterns_in_fns_without_body)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/non-fmt-panic.stderr b/src/test/ui/non-fmt-panic.stderr
index 6e4434e6f33..162802b7f61 100644
--- a/src/test/ui/non-fmt-panic.stderr
+++ b/src/test/ui/non-fmt-panic.stderr
@@ -4,8 +4,8 @@ warning: panic message contains a brace
 LL |     panic!("here's a brace: {");
    |                             ^
    |
-   = note: `#[warn(non_fmt_panics)]` on by default
    = note: this message is not used as a format string, but will be in Rust 2021
+   = note: `#[warn(non_fmt_panics)]` on by default
 help: add a "{}" format string to use the message literally
    |
 LL |     panic!("{}", "here's a brace: {");
diff --git a/src/test/ui/packed/issue-27060-rpass.stderr b/src/test/ui/packed/issue-27060-rpass.stderr
index 667b70afb87..adf9ae9f56f 100644
--- a/src/test/ui/packed/issue-27060-rpass.stderr
+++ b/src/test/ui/packed/issue-27060-rpass.stderr
@@ -5,15 +5,15 @@ warning: reference to packed field is unaligned
 LL |     let _ = &good.data; // ok
    |             ^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/issue-27060-rpass.rs:11:9
    |
 LL | #[allow(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 warning: reference to packed field is unaligned
@@ -22,15 +22,15 @@ warning: reference to packed field is unaligned
 LL |     let _ = &good.data2[0]; // ok
    |             ^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/issue-27060-rpass.rs:11:9
    |
 LL | #[allow(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 warning: reference to packed field is unaligned
@@ -39,15 +39,15 @@ warning: reference to packed field is unaligned
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/issue-27060-rpass.rs:11:9
    |
 LL | #[allow(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 warning: reference to packed field is unaligned
@@ -56,13 +56,13 @@ warning: reference to packed field is unaligned
 LL |     let _ = &good.data2[0];
    |             ^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/issue-27060-rpass.rs:11:9
    |
 LL | #[allow(unaligned_references)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
diff --git a/src/test/ui/packed/issue-27060.stderr b/src/test/ui/packed/issue-27060.stderr
index 1bab16e6dda..85e08fa02dd 100644
--- a/src/test/ui/packed/issue-27060.stderr
+++ b/src/test/ui/packed/issue-27060.stderr
@@ -4,11 +4,11 @@ error: reference to packed field is unaligned
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 error: reference to packed field is unaligned
   --> $DIR/issue-27060.rs:17:13
@@ -52,11 +52,11 @@ error: reference to packed field is unaligned
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -65,11 +65,11 @@ error: reference to packed field is unaligned
 LL |     let _ = &good.data2[0];
    |             ^^^^^^^^^^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -78,11 +78,11 @@ error: reference to packed field is unaligned
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
 Future breakage diagnostic:
 error: reference to packed field is unaligned
@@ -91,9 +91,9 @@ error: reference to packed field is unaligned
 LL |     let _ = &good.data2[0];
    |             ^^^^^^^^^^^^^^
    |
-   = note: `#[deny(unaligned_references)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: `#[deny(unaligned_references)]` on by default
 
diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr
index dcd1c19fa16..fb2f5615c53 100644
--- a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr
+++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr
@@ -4,15 +4,15 @@ warning: reference to packed field is unaligned
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/packed-struct-borrow-element-64bit.rs:12:8
    |
 LL | #[warn(unaligned_references)]
    |        ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 warning: 1 warning emitted
 
@@ -23,13 +23,13 @@ warning: reference to packed field is unaligned
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/packed-struct-borrow-element-64bit.rs:12:8
    |
 LL | #[warn(unaligned_references)]
    |        ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
diff --git a/src/test/ui/packed/packed-struct-borrow-element.stderr b/src/test/ui/packed/packed-struct-borrow-element.stderr
index fb483227e20..75d55c4f693 100644
--- a/src/test/ui/packed/packed-struct-borrow-element.stderr
+++ b/src/test/ui/packed/packed-struct-borrow-element.stderr
@@ -4,15 +4,15 @@ warning: reference to packed field is unaligned
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/packed-struct-borrow-element.rs:23:8
    |
 LL | #[warn(unaligned_references)]
    |        ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 warning: reference to packed field is unaligned
   --> $DIR/packed-struct-borrow-element.rs:31:15
@@ -34,15 +34,15 @@ warning: reference to packed field is unaligned
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/packed-struct-borrow-element.rs:23:8
    |
 LL | #[warn(unaligned_references)]
    |        ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 Future breakage diagnostic:
 warning: reference to packed field is unaligned
@@ -51,13 +51,13 @@ warning: reference to packed field is unaligned
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 note: the lint level is defined here
   --> $DIR/packed-struct-borrow-element.rs:23:8
    |
 LL | #[warn(unaligned_references)]
    |        ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
-   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
-   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr
index 7ae092cee67..8a74f49b95c 100644
--- a/src/test/ui/parser/assoc-static-semantic-fail.stderr
+++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr
@@ -168,9 +168,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: aborting due to 24 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr
index 5b763ae72f5..37aa48ccf52 100644
--- a/src/test/ui/parser/default.stderr
+++ b/src/test/ui/parser/default.stderr
@@ -29,9 +29,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0046]: not all trait items implemented, missing: `foo`
   --> $DIR/default.rs:22:1
diff --git a/src/test/ui/parser/doc-after-struct-field.rs b/src/test/ui/parser/doc-after-struct-field.rs
index 5b6f0803603..03faa6733e2 100644
--- a/src/test/ui/parser/doc-after-struct-field.rs
+++ b/src/test/ui/parser/doc-after-struct-field.rs
@@ -1,13 +1,13 @@
 struct X {
     a: u8 /** document a */,
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
 }
 
 struct Y {
     a: u8 /// document a
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
 }
 
 fn main() {
diff --git a/src/test/ui/parser/doc-after-struct-field.stderr b/src/test/ui/parser/doc-after-struct-field.stderr
index e3b32a7f035..ae177f1a2d1 100644
--- a/src/test/ui/parser/doc-after-struct-field.stderr
+++ b/src/test/ui/parser/doc-after-struct-field.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     a: u8 /** document a */,
    |           ^^^^^^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error[E0585]: found a documentation comment that doesn't document anything
   --> $DIR/doc-after-struct-field.rs:8:11
@@ -12,7 +12,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     a: u8 /// document a
    |           ^^^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/doc-before-extern-rbrace.stderr b/src/test/ui/parser/doc-before-extern-rbrace.stderr
index 0edceb268a7..8fa12ec261e 100644
--- a/src/test/ui/parser/doc-before-extern-rbrace.stderr
+++ b/src/test/ui/parser/doc-before-extern-rbrace.stderr
@@ -4,7 +4,7 @@ error[E0584]: found a documentation comment that doesn't document anything
 LL |     /// hi
    |     ^^^^^^ this doc comment doesn't document anything
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-before-fn-rbrace.rs b/src/test/ui/parser/doc-before-fn-rbrace.rs
index eb355136f1e..c8502164854 100644
--- a/src/test/ui/parser/doc-before-fn-rbrace.rs
+++ b/src/test/ui/parser/doc-before-fn-rbrace.rs
@@ -1,5 +1,5 @@
 fn main() {
     /// document
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
 }
diff --git a/src/test/ui/parser/doc-before-fn-rbrace.stderr b/src/test/ui/parser/doc-before-fn-rbrace.stderr
index 56241de7092..6ea68e42b4c 100644
--- a/src/test/ui/parser/doc-before-fn-rbrace.stderr
+++ b/src/test/ui/parser/doc-before-fn-rbrace.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     /// document
    |     ^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-before-rbrace.rs b/src/test/ui/parser/doc-before-rbrace.rs
index 8ff946344ae..570306f2cdf 100644
--- a/src/test/ui/parser/doc-before-rbrace.rs
+++ b/src/test/ui/parser/doc-before-rbrace.rs
@@ -1,5 +1,5 @@
 fn main() {
     println!("Hi"); /// hi
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
 }
diff --git a/src/test/ui/parser/doc-before-rbrace.stderr b/src/test/ui/parser/doc-before-rbrace.stderr
index 55719cf6411..4d4741dfe59 100644
--- a/src/test/ui/parser/doc-before-rbrace.stderr
+++ b/src/test/ui/parser/doc-before-rbrace.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     println!("Hi"); /// hi
    |                     ^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-before-semi.rs b/src/test/ui/parser/doc-before-semi.rs
index 405a7e1e2a3..444b5874ea2 100644
--- a/src/test/ui/parser/doc-before-semi.rs
+++ b/src/test/ui/parser/doc-before-semi.rs
@@ -1,6 +1,6 @@
 fn main() {
     /// hi
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
     ;
 }
diff --git a/src/test/ui/parser/doc-before-semi.stderr b/src/test/ui/parser/doc-before-semi.stderr
index e6bade18d0a..a879e13ffbd 100644
--- a/src/test/ui/parser/doc-before-semi.stderr
+++ b/src/test/ui/parser/doc-before-semi.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     /// hi
    |     ^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.rs b/src/test/ui/parser/doc-before-struct-rbrace-1.rs
index 3866a3105c2..0c8d90c3b03 100644
--- a/src/test/ui/parser/doc-before-struct-rbrace-1.rs
+++ b/src/test/ui/parser/doc-before-struct-rbrace-1.rs
@@ -2,7 +2,7 @@ struct X {
     a: u8,
     /// document
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
 }
 
 fn main() {
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
index 92b5133b74d..94934f734b3 100644
--- a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
+++ b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
@@ -7,7 +7,7 @@ LL |     a: u8,
 LL |     /// document
    |     ^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.rs b/src/test/ui/parser/doc-before-struct-rbrace-2.rs
index dda138f1a88..2b2aadf7984 100644
--- a/src/test/ui/parser/doc-before-struct-rbrace-2.rs
+++ b/src/test/ui/parser/doc-before-struct-rbrace-2.rs
@@ -1,7 +1,7 @@
 struct X {
     a: u8 /// document
     //~^ ERROR found a documentation comment that doesn't document anything
-    //~| HELP maybe a comment was intended
+    //~| HELP if a comment was intended use `//`
 }
 
 fn main() {
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.stderr b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr
index b25ccab79f9..6b5c8c1f8b5 100644
--- a/src/test/ui/parser/doc-before-struct-rbrace-2.stderr
+++ b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     a: u8 /// document
    |           ^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-inside-trait-item.stderr b/src/test/ui/parser/doc-inside-trait-item.stderr
index 246255a0a46..900124adcc3 100644
--- a/src/test/ui/parser/doc-inside-trait-item.stderr
+++ b/src/test/ui/parser/doc-inside-trait-item.stderr
@@ -4,7 +4,7 @@ error[E0584]: found a documentation comment that doesn't document anything
 LL |     /// empty doc
    |     ^^^^^^^^^^^^^ this doc comment doesn't document anything
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr
index 9b939f05e02..2b6314c38ce 100644
--- a/src/test/ui/parser/expr-as-stmt-2.stderr
+++ b/src/test/ui/parser/expr-as-stmt-2.stderr
@@ -36,11 +36,6 @@ LL | /     &&
 LL | |     if let Some(y) = a { true } else { false }
    | |______________________________________________^ expected `bool`, found `&&bool`
    |
-help: consider removing the `&&`
-   |
-LL -     &&
-LL +     if let Some(y) = a { true } else { false }
-   |
 help: parentheses are required to parse this as an expression
    |
 LL |     (if let Some(x) = a { true } else { false })
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index 858b4e8db05..6da4ac34067 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -170,11 +170,6 @@ LL | fn revenge_from_mars() -> bool {
 LL |     { true } && { true }
    |              ^^^^^^^^^^^ expected `bool`, found `&&bool`
    |
-help: consider removing the `&&`
-   |
-LL -     { true } && { true }
-LL +     { true } { true }
-   |
 help: parentheses are required to parse this as an expression
    |
 LL |     ({ true }) && { true }
@@ -201,10 +196,6 @@ LL |     { true } || { true }
    |
    = note: expected type `bool`
            found closure `[closure@$DIR/expr-as-stmt.rs:51:14: 51:16]`
-help: use parentheses to call this closure
-   |
-LL |     { true } (|| { true })()
-   |              +           +++
 help: parentheses are required to parse this as an expression
    |
 LL |     ({ true }) || { true }
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.rs b/src/test/ui/parser/fn-field-parse-error-ice.rs
index 4ea55062fc4..188257ea53a 100644
--- a/src/test/ui/parser/fn-field-parse-error-ice.rs
+++ b/src/test/ui/parser/fn-field-parse-error-ice.rs
@@ -3,7 +3,7 @@
 struct Baz {
     inner : dyn fn ()
     //~^ ERROR expected `,`, or `}`, found keyword `fn`
-    //~| ERROR functions are not allowed in struct definitions
+    //~| ERROR expected identifier, found keyword `fn`
     //~| ERROR cannot find type `dyn` in this scope
 }
 
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.stderr b/src/test/ui/parser/fn-field-parse-error-ice.stderr
index e9583f55b8e..3bf68e8cc04 100644
--- a/src/test/ui/parser/fn-field-parse-error-ice.stderr
+++ b/src/test/ui/parser/fn-field-parse-error-ice.stderr
@@ -4,16 +4,18 @@ error: expected `,`, or `}`, found keyword `fn`
 LL |     inner : dyn fn ()
    |                ^ help: try adding a comma: `,`
 
-error: functions are not allowed in struct definitions
+error: expected identifier, found keyword `fn`
   --> $DIR/fn-field-parse-error-ice.rs:4:17
    |
 LL | struct Baz {
    |        --- while parsing this struct
 LL |     inner : dyn fn ()
-   |                 ^^
+   |                 ^^ expected identifier, found keyword
    |
-   = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
-   = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+help: escape `fn` to use it as an identifier
+   |
+LL |     inner : dyn r#fn ()
+   |                 ++
 
 error[E0412]: cannot find type `dyn` in this scope
   --> $DIR/fn-field-parse-error-ice.rs:4:13
diff --git a/src/test/ui/parser/issues/issue-34222-1.stderr b/src/test/ui/parser/issues/issue-34222-1.stderr
index 0799656b06b..b451484ba22 100644
--- a/src/test/ui/parser/issues/issue-34222-1.stderr
+++ b/src/test/ui/parser/issues/issue-34222-1.stderr
@@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything
 LL |     /// comment
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issues/issue-48636.stderr b/src/test/ui/parser/issues/issue-48636.stderr
index 1a6e4cfd2b2..6177870d1ce 100644
--- a/src/test/ui/parser/issues/issue-48636.stderr
+++ b/src/test/ui/parser/issues/issue-48636.stderr
@@ -8,7 +8,7 @@ LL |     x: u8
 LL |     /// The ID of the parent core
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: doc comments must come before what they document, maybe a comment was intended with `//`?
+   = help: doc comments must come before what they document, if a comment was intended use `//`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr
index 39d49fd03f1..0dca090fb87 100644
--- a/src/test/ui/parser/macro/issue-33569.stderr
+++ b/src/test/ui/parser/macro/issue-33569.stderr
@@ -22,9 +22,9 @@ error: missing fragment specifier
 LL |     { $+ } => {
    |        ^
    |
-   = note: `#[deny(missing_fragment_specifier)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+   = note: `#[deny(missing_fragment_specifier)]` on by default
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr
index d0979b23f60..6c081052ddf 100644
--- a/src/test/ui/parser/recover-range-pats.stderr
+++ b/src/test/ui/parser/recover-range-pats.stderr
@@ -199,13 +199,13 @@ error: `...` range patterns are deprecated
 LL |     if let 0...3 = 0 {}
    |             ^^^ help: use `..=` for an inclusive range
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/recover-range-pats.rs:8:9
    |
 LL | #![deny(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 
 error: `...` range patterns are deprecated
   --> $DIR/recover-range-pats.rs:45:13
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
index 76fa860334d..be858cd651d 100644
--- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
@@ -52,9 +52,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: aborting due to 6 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr
index 823f75bfac8..5e07a3fe6c7 100644
--- a/src/test/ui/parser/trait-object-trait-parens.stderr
+++ b/src/test/ui/parser/trait-object-trait-parens.stderr
@@ -22,9 +22,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL |     let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
diff --git a/src/test/ui/parser/type-alias-where-fixable.stderr b/src/test/ui/parser/type-alias-where-fixable.stderr
index 2e516d5c478..f0acb388b97 100644
--- a/src/test/ui/parser/type-alias-where-fixable.stderr
+++ b/src/test/ui/parser/type-alias-where-fixable.stderr
@@ -4,8 +4,8 @@ warning: where clause not allowed here
 LL |     type Assoc where u32: Copy = ();
    |                ^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(deprecated_where_clause_location)]` on by default
    = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
+   = note: `#[warn(deprecated_where_clause_location)]` on by default
 help: move it to the end of the type declaration
    |
 LL -     type Assoc where u32: Copy = ();
diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr
index 71509fe41a8..44548c72ff5 100644
--- a/src/test/ui/parser/unicode-control-codepoints.stderr
+++ b/src/test/ui/parser/unicode-control-codepoints.stderr
@@ -92,8 +92,8 @@ LL |     // if access_level != "user" { // Check if admin
    |     |                        '\u{202b}'
    |     this comment contains invisible unicode text flow control codepoints
    |
-   = note: `#[deny(text_direction_codepoint_in_comment)]` on by default
    = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = note: `#[deny(text_direction_codepoint_in_comment)]` on by default
    = help: if their presence wasn't intentional, you can remove them
 
 error: unicode codepoint changing visible direction of text present in comment
@@ -123,8 +123,8 @@ LL |     println!("{:?}", "/* } if isAdmin  begin admins only ");
    |                      |  '\u{202e}'
    |                      this literal contains invisible unicode text flow control codepoints
    |
-   = note: `#[deny(text_direction_codepoint_in_literal)]` on by default
    = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
+   = note: `#[deny(text_direction_codepoint_in_literal)]` on by default
    = help: if their presence wasn't intentional, you can remove them
 help: if you want to keep them but make them visible in your source code, you can escape them
    |
diff --git a/src/test/ui/pattern/usefulness/consts-opaque.stderr b/src/test/ui/pattern/usefulness/consts-opaque.stderr
index 05c009a6f3f..35396751abe 100644
--- a/src/test/ui/pattern/usefulness/consts-opaque.stderr
+++ b/src/test/ui/pattern/usefulness/consts-opaque.stderr
@@ -40,9 +40,9 @@ warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated w
 LL |         FOO_REF_REF => {}
    |         ^^^^^^^^^^^
    |
-   = note: `#[warn(indirect_structural_match)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: `#[warn(indirect_structural_match)]` on by default
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/consts-opaque.rs:53:9
diff --git a/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr
index b97683526ba..cdb6b5c7a49 100644
--- a/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr
@@ -4,13 +4,13 @@ error: irrefutable `if let` pattern
 LL |     if let _ = 5 {}
    |        ^^^^^^^^^
    |
+   = note: this pattern will always match, so the `if let` is useless
+   = help: consider replacing the `if let` with a `let`
 note: the lint level is defined here
   --> $DIR/deny-irrefutable-let-patterns.rs:3:9
    |
 LL | #![deny(irrefutable_let_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: this pattern will always match, so the `if let` is useless
-   = help: consider replacing the `if let` with a `let`
 
 error: irrefutable `while let` pattern
   --> $DIR/deny-irrefutable-let-patterns.rs:8:11
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
index 24c0419e1dd..ea0e8f6e49e 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
@@ -6,12 +6,12 @@ LL |     m!(0u8, 20..=30, 30..=40);
    |             |
    |             this range overlaps on `30_u8`...
    |
+   = note: you likely meant to write mutually exclusive ranges
 note: the lint level is defined here
   --> $DIR/overlapping_range_endpoints.rs:2:9
    |
 LL | #![deny(overlapping_range_endpoints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: you likely meant to write mutually exclusive ranges
 
 error: multiple patterns overlap on their endpoints
   --> $DIR/overlapping_range_endpoints.rs:16:22
diff --git a/src/test/ui/polymorphization/const_parameters/closures.stderr b/src/test/ui/polymorphization/const_parameters/closures.stderr
index fdf817caea7..4e927f7732f 100644
--- a/src/test/ui/polymorphization/const_parameters/closures.stderr
+++ b/src/test/ui/polymorphization/const_parameters/closures.stderr
@@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to
 LL | #![feature(generic_const_exprs, rustc_attrs)]
    |            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: item has unused generic parameters
   --> $DIR/closures.rs:19:19
diff --git a/src/test/ui/polymorphization/const_parameters/functions.stderr b/src/test/ui/polymorphization/const_parameters/functions.stderr
index f2b5a730738..9d0922ac7ca 100644
--- a/src/test/ui/polymorphization/const_parameters/functions.stderr
+++ b/src/test/ui/polymorphization/const_parameters/functions.stderr
@@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to
 LL | #![feature(generic_const_exprs, rustc_attrs)]
    |            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: item has unused generic parameters
   --> $DIR/functions.rs:15:8
diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr
index a24eee5fed1..84888f6fb2f 100644
--- a/src/test/ui/polymorphization/generators.stderr
+++ b/src/test/ui/polymorphization/generators.stderr
@@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to
 LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)]
    |            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: item has unused generic parameters
   --> $DIR/generators.rs:35:5
diff --git a/src/test/ui/polymorphization/promoted-function-2.stderr b/src/test/ui/polymorphization/promoted-function-2.stderr
index 4d7bab6aaa0..547569df7dc 100644
--- a/src/test/ui/polymorphization/promoted-function-2.stderr
+++ b/src/test/ui/polymorphization/promoted-function-2.stderr
@@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to
 LL | #![feature(generic_const_exprs, rustc_attrs)]
    |            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: item has unused generic parameters
   --> $DIR/promoted-function-2.rs:8:4
diff --git a/src/test/ui/privacy/issue-30079.stderr b/src/test/ui/privacy/issue-30079.stderr
index dc98cfe3bb6..9179ff339bf 100644
--- a/src/test/ui/privacy/issue-30079.stderr
+++ b/src/test/ui/privacy/issue-30079.stderr
@@ -4,9 +4,9 @@ warning: private type `m1::Priv` in public interface (error E0446)
 LL |         pub fn f(_: Priv) {}
    |         ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(private_in_public)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
+   = note: `#[warn(private_in_public)]` on by default
 
 error[E0446]: private type `m2::Priv` in public interface
   --> $DIR/issue-30079.rs:18:9
diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr
index 1abeafe398f..a59027d81d2 100644
--- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr
+++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr
@@ -13,9 +13,9 @@ warning: private trait `PrivTr` in public interface (error E0445)
 LL |         type Alias1: PrivTr;
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(private_in_public)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
+   = note: `#[warn(private_in_public)]` on by default
 
 warning: private type `Priv` in public interface (error E0446)
   --> $DIR/private-in-public-assoc-ty.rs:27:9
diff --git a/src/test/ui/privacy/private-in-public-non-principal.stderr b/src/test/ui/privacy/private-in-public-non-principal.stderr
index 5b4123ea82a..de20cada42e 100644
--- a/src/test/ui/privacy/private-in-public-non-principal.stderr
+++ b/src/test/ui/privacy/private-in-public-non-principal.stderr
@@ -4,9 +4,9 @@ warning: private trait `PrivNonPrincipal` in public interface (error E0445)
 LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(private_in_public)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
+   = note: `#[warn(private_in_public)]` on by default
 
 error: missing documentation for an associated function
   --> $DIR/private-in-public-non-principal.rs:14:9
diff --git a/src/test/ui/privacy/private-in-public-warn.stderr b/src/test/ui/privacy/private-in-public-warn.stderr
index f2ff6cf2fdb..66f91ce6fd6 100644
--- a/src/test/ui/privacy/private-in-public-warn.stderr
+++ b/src/test/ui/privacy/private-in-public-warn.stderr
@@ -4,13 +4,13 @@ error: private type `types::Priv` in public interface (error E0446)
 LL |     pub type Alias = Priv;
    |     ^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 note: the lint level is defined here
   --> $DIR/private-in-public-warn.rs:5:9
    |
 LL | #![deny(private_in_public)]
    |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 error: private type `types::Priv` in public interface (error E0446)
   --> $DIR/private-in-public-warn.rs:18:12
diff --git a/src/test/ui/privacy/where-priv-type.stderr b/src/test/ui/privacy/where-priv-type.stderr
index 7eb71346ae9..c5fb2cdb0cf 100644
--- a/src/test/ui/privacy/where-priv-type.stderr
+++ b/src/test/ui/privacy/where-priv-type.stderr
@@ -4,9 +4,9 @@ warning: private type `PrivTy` in public interface (error E0446)
 LL | pub struct S
    | ^^^^^^^^^^^^
    |
-   = note: `#[warn(private_in_public)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
+   = note: `#[warn(private_in_public)]` on by default
 
 warning: private type `PrivTy` in public interface (error E0446)
   --> $DIR/where-priv-type.rs:27:1
diff --git a/src/test/ui/proc-macro/attr-complex-fn.stdout b/src/test/ui/proc-macro/attr-complex-fn.stdout
index fc69a13ddb9..b12eb587fc7 100644
--- a/src/test/ui/proc-macro/attr-complex-fn.stdout
+++ b/src/test/ui/proc-macro/attr-complex-fn.stdout
@@ -53,12 +53,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '>',
         spacing: Joint,
-        span: $DIR/attr-complex-fn.rs:19:36: 19:38 (#0),
+        span: $DIR/attr-complex-fn.rs:19:36: 19:37 (#0),
     },
     Punct {
         ch: '>',
         spacing: Joint,
-        span: $DIR/attr-complex-fn.rs:19:36: 19:38 (#0),
+        span: $DIR/attr-complex-fn.rs:19:37: 19:38 (#0),
     },
     Punct {
         ch: '>',
diff --git a/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout b/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
index 4de8746a1b4..b88fbd3e897 100644
--- a/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
+++ b/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
@@ -177,12 +177,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:18 (#0),
+                span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:17 (#0),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:18 (#0),
+                span: $DIR/capture-macro-rules-invoke.rs:45:17: 45:18 (#0),
             },
             Ident {
                 ident: "option",
@@ -191,12 +191,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:26 (#0),
+                span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:25 (#0),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:26 (#0),
+                span: $DIR/capture-macro-rules-invoke.rs:45:25: 45:26 (#0),
             },
             Ident {
                 ident: "Option",
@@ -231,12 +231,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
                     Punct {
                         ch: ':',
                         spacing: Joint,
-                        span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:26 (#0),
+                        span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:25 (#0),
                     },
                     Punct {
                         ch: ':',
                         spacing: Alone,
-                        span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:26 (#0),
+                        span: $DIR/capture-macro-rules-invoke.rs:46:25: 46:26 (#0),
                     },
                     Ident {
                         ident: "path",
diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs
index fd34eb974c0..102bd6b7b17 100644
--- a/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs
+++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs
@@ -2,6 +2,7 @@
 // aux-build:macro-dump-debug.rs
 // compile-flags: -Z span-debug
 
+
 extern crate macro_dump_debug;
 use macro_dump_debug::dump_debug;
 
@@ -9,7 +10,11 @@ dump_debug! {
     ident   // ident
     r#ident // raw ident
     ,       // alone punct
-    ==>     // joint punct
+    &&      // joint punct, two-char op
+    ||>     // joint punct, two-char op + one-char op
+    ||<<    // joint punct, two-char op + two-char op
+    ..=     // joint punct, three-char op
+    <<=!    // joint punct, three-char op + one-char-op
     ()      // empty group
     [_]     // nonempty group
 
diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr
index 2c05bdbc492..fa65cbbf1ea 100644
--- a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr
+++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr
@@ -1,166 +1,231 @@
-TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 (#0) }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 (#0) }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0) }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 (#0) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 (#0) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0) }], span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 (#0) }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 (#0) }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 (#0) }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 (#0) }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 (#0) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 (#0) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 (#0) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0) }]
+TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:10 (#0) }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:11:5: 11:12 (#0) }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:5: 12:6 (#0) }, Punct { ch: '&', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:13:5: 13:6 (#0) }, Punct { ch: '&', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:13:6: 13:7 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:14:5: 14:6 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0) }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:14:7: 14:8 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:15:5: 15:6 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:15:6: 15:7 (#0) }, Punct { ch: '<', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:15:7: 15:8 (#0) }, Punct { ch: '<', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:15:8: 15:9 (#0) }, Punct { ch: '.', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:16:5: 16:6 (#0) }, Punct { ch: '.', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:16:6: 16:7 (#0) }, Punct { ch: '=', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:16:7: 16:8 (#0) }, Punct { ch: '<', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0) }, Punct { ch: '<', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:17:6: 17:7 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:17:7: 17:8 (#0) }, Punct { ch: '!', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:17:8: 17:9 (#0) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:18:5: 18:7 (#0) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:19:6: 19:7 (#0) }], span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0) }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:6 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:8 (#0) }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:8 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:9 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:27:5: 27:13 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:28:5: 28:11 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:29:5: 29:15 (#0) }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:30:5: 30:8 (#0) }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:7 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:9 (#0) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:9 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:10 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:39:5: 39:14 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:40:5: 40:12 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:41:5: 41:16 (#0) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:42:5: 42:9 (#0) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:43:5: 43:10 (#0) }]
 TokenStream [
     Ident {
         ident: "ident",
-        span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 (#0),
+        span: $DIR/dump-debug-span-debug.rs:10:5: 10:10 (#0),
     },
     Ident {
         ident: "r#ident",
-        span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 (#0),
+        span: $DIR/dump-debug-span-debug.rs:11:5: 11:12 (#0),
     },
     Punct {
         ch: ',',
         spacing: Alone,
-        span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 (#0),
+        span: $DIR/dump-debug-span-debug.rs:12:5: 12:6 (#0),
+    },
+    Punct {
+        ch: '&',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:13:5: 13:6 (#0),
+    },
+    Punct {
+        ch: '&',
+        spacing: Alone,
+        span: $DIR/dump-debug-span-debug.rs:13:6: 13:7 (#0),
+    },
+    Punct {
+        ch: '|',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:14:5: 14:6 (#0),
+    },
+    Punct {
+        ch: '|',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0),
+    },
+    Punct {
+        ch: '>',
+        spacing: Alone,
+        span: $DIR/dump-debug-span-debug.rs:14:7: 14:8 (#0),
+    },
+    Punct {
+        ch: '|',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:15:5: 15:6 (#0),
+    },
+    Punct {
+        ch: '|',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:15:6: 15:7 (#0),
+    },
+    Punct {
+        ch: '<',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:15:7: 15:8 (#0),
+    },
+    Punct {
+        ch: '<',
+        spacing: Alone,
+        span: $DIR/dump-debug-span-debug.rs:15:8: 15:9 (#0),
+    },
+    Punct {
+        ch: '.',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:16:5: 16:6 (#0),
+    },
+    Punct {
+        ch: '.',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:16:6: 16:7 (#0),
     },
     Punct {
         ch: '=',
+        spacing: Alone,
+        span: $DIR/dump-debug-span-debug.rs:16:7: 16:8 (#0),
+    },
+    Punct {
+        ch: '<',
         spacing: Joint,
-        span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0),
+        span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0),
+    },
+    Punct {
+        ch: '<',
+        spacing: Joint,
+        span: $DIR/dump-debug-span-debug.rs:17:6: 17:7 (#0),
     },
     Punct {
         ch: '=',
         spacing: Joint,
-        span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0),
+        span: $DIR/dump-debug-span-debug.rs:17:7: 17:8 (#0),
     },
     Punct {
-        ch: '>',
+        ch: '!',
         spacing: Alone,
-        span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 (#0),
+        span: $DIR/dump-debug-span-debug.rs:17:8: 17:9 (#0),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [],
-        span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 (#0),
+        span: $DIR/dump-debug-span-debug.rs:18:5: 18:7 (#0),
     },
     Group {
         delimiter: Bracket,
         stream: TokenStream [
             Ident {
                 ident: "_",
-                span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0),
+                span: $DIR/dump-debug-span-debug.rs:19:6: 19:7 (#0),
             },
         ],
-        span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 (#0),
+        span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0),
     },
     Literal {
         kind: Integer,
         symbol: "0",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0),
+        span: $DIR/dump-debug-span-debug.rs:22:5: 22:6 (#0),
     },
     Literal {
         kind: Float,
         symbol: "1.0",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 (#0),
+        span: $DIR/dump-debug-span-debug.rs:23:5: 23:8 (#0),
     },
     Literal {
         kind: Str,
         symbol: "S",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0),
+        span: $DIR/dump-debug-span-debug.rs:24:5: 24:8 (#0),
     },
     Literal {
         kind: ByteStr,
         symbol: "B",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 (#0),
+        span: $DIR/dump-debug-span-debug.rs:25:5: 25:9 (#0),
     },
     Literal {
         kind: StrRaw(0),
         symbol: "R",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 (#0),
+        span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0),
     },
     Literal {
         kind: StrRaw(2),
         symbol: "R",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 (#0),
+        span: $DIR/dump-debug-span-debug.rs:27:5: 27:13 (#0),
     },
     Literal {
         kind: ByteStrRaw(0),
         symbol: "BR",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 (#0),
+        span: $DIR/dump-debug-span-debug.rs:28:5: 28:11 (#0),
     },
     Literal {
         kind: ByteStrRaw(2),
         symbol: "BR",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 (#0),
+        span: $DIR/dump-debug-span-debug.rs:29:5: 29:15 (#0),
     },
     Literal {
         kind: Char,
         symbol: "C",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 (#0),
+        span: $DIR/dump-debug-span-debug.rs:30:5: 30:8 (#0),
     },
     Literal {
         kind: Byte,
         symbol: "B",
         suffix: None,
-        span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0),
+        span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0),
     },
     Literal {
         kind: Integer,
         symbol: "0",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 (#0),
+        span: $DIR/dump-debug-span-debug.rs:34:5: 34:7 (#0),
     },
     Literal {
         kind: Float,
         symbol: "1.0",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 (#0),
+        span: $DIR/dump-debug-span-debug.rs:35:5: 35:9 (#0),
     },
     Literal {
         kind: Str,
         symbol: "S",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0),
+        span: $DIR/dump-debug-span-debug.rs:36:5: 36:9 (#0),
     },
     Literal {
         kind: ByteStr,
         symbol: "B",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 (#0),
+        span: $DIR/dump-debug-span-debug.rs:37:5: 37:10 (#0),
     },
     Literal {
         kind: StrRaw(0),
         symbol: "R",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 (#0),
+        span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0),
     },
     Literal {
         kind: StrRaw(2),
         symbol: "R",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 (#0),
+        span: $DIR/dump-debug-span-debug.rs:39:5: 39:14 (#0),
     },
     Literal {
         kind: ByteStrRaw(0),
         symbol: "BR",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 (#0),
+        span: $DIR/dump-debug-span-debug.rs:40:5: 40:12 (#0),
     },
     Literal {
         kind: ByteStrRaw(2),
         symbol: "BR",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 (#0),
+        span: $DIR/dump-debug-span-debug.rs:41:5: 41:16 (#0),
     },
     Literal {
         kind: Char,
         symbol: "C",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 (#0),
+        span: $DIR/dump-debug-span-debug.rs:42:5: 42:9 (#0),
     },
     Literal {
         kind: Byte,
         symbol: "B",
         suffix: Some("q"),
-        span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0),
+        span: $DIR/dump-debug-span-debug.rs:43:5: 43:10 (#0),
     },
 ]
diff --git a/src/test/ui/proc-macro/debug/dump-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug.stderr
index 0aedefd4e60..db422b6012a 100644
--- a/src/test/ui/proc-macro/debug/dump-debug.stderr
+++ b/src/test/ui/proc-macro/debug/dump-debug.stderr
@@ -1,4 +1,4 @@
-TokenStream [Ident { ident: "ident", span: #0 bytes(130..135) }, Ident { ident: "r#ident", span: #0 bytes(151..158) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(176..177) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(203..205) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(203..205) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(205..206) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(230..232) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: #0 bytes(258..259) }], span: #0 bytes(257..260) }, Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(315..316) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: #0 bytes(321..324) }, Literal { kind: Str, symbol: "S", suffix: None, span: #0 bytes(329..332) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: #0 bytes(337..341) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: #0 bytes(346..350) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: #0 bytes(355..363) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: #0 bytes(368..374) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: #0 bytes(379..389) }, Literal { kind: Char, symbol: "C", suffix: None, span: #0 bytes(394..397) }, Literal { kind: Byte, symbol: "B", suffix: None, span: #0 bytes(402..406) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: #0 bytes(437..439) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: #0 bytes(444..448) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: #0 bytes(453..457) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: #0 bytes(462..467) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: #0 bytes(472..477) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: #0 bytes(482..491) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: #0 bytes(496..503) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: #0 bytes(508..519) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: #0 bytes(524..528) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: #0 bytes(533..538) }]
+TokenStream [Ident { ident: "ident", span: #0 bytes(130..135) }, Ident { ident: "r#ident", span: #0 bytes(151..158) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(176..177) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(203..204) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(204..205) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(205..206) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(230..232) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: #0 bytes(258..259) }], span: #0 bytes(257..260) }, Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(315..316) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: #0 bytes(321..324) }, Literal { kind: Str, symbol: "S", suffix: None, span: #0 bytes(329..332) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: #0 bytes(337..341) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: #0 bytes(346..350) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: #0 bytes(355..363) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: #0 bytes(368..374) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: #0 bytes(379..389) }, Literal { kind: Char, symbol: "C", suffix: None, span: #0 bytes(394..397) }, Literal { kind: Byte, symbol: "B", suffix: None, span: #0 bytes(402..406) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: #0 bytes(437..439) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: #0 bytes(444..448) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: #0 bytes(453..457) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: #0 bytes(462..467) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: #0 bytes(472..477) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: #0 bytes(482..491) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: #0 bytes(496..503) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: #0 bytes(508..519) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: #0 bytes(524..528) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: #0 bytes(533..538) }]
 TokenStream [
     Ident {
         ident: "ident",
@@ -16,12 +16,12 @@ TokenStream [
     Punct {
         ch: '=',
         spacing: Joint,
-        span: #0 bytes(203..205),
+        span: #0 bytes(203..204),
     },
     Punct {
         ch: '=',
         spacing: Joint,
-        span: #0 bytes(203..205),
+        span: #0 bytes(204..205),
     },
     Punct {
         ch: '>',
diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
index d8287eb73db..9c52ca42241 100644
--- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr
+++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
@@ -80,9 +80,9 @@ LL | #[empty_helper]
 LL | #[derive(Empty)]
    |          ----- the attribute is introduced here
    |
-   = note: `#[warn(legacy_derive_helpers)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
+   = note: `#[warn(legacy_derive_helpers)]` on by default
 
 error: aborting due to 5 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout
index c0c9ed72c5a..2622c005d93 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout
+++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout
@@ -18,12 +18,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/dollar-crate-issue-57089.rs:17:28: 17:30 (#4),
+                span: $DIR/dollar-crate-issue-57089.rs:17:28: 17:29 (#4),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/dollar-crate-issue-57089.rs:17:28: 17:30 (#4),
+                span: $DIR/dollar-crate-issue-57089.rs:17:29: 17:30 (#4),
             },
             Ident {
                 ident: "S",
@@ -58,12 +58,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/dollar-crate-issue-57089.rs:21:24: 21:26 (#4),
+                span: $DIR/dollar-crate-issue-57089.rs:21:24: 21:25 (#4),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/dollar-crate-issue-57089.rs:21:24: 21:26 (#4),
+                span: $DIR/dollar-crate-issue-57089.rs:21:25: 21:26 (#4),
             },
             Ident {
                 ident: "S",
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
index e6148a687fd..a91908239c3 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
+++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
@@ -30,12 +30,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
                     Punct {
                         ch: ':',
                         spacing: Joint,
-                        span: $DIR/dollar-crate-issue-62325.rs:19:30: 19:32 (#4),
+                        span: $DIR/dollar-crate-issue-62325.rs:19:30: 19:31 (#4),
                     },
                     Punct {
                         ch: ':',
                         spacing: Alone,
-                        span: $DIR/dollar-crate-issue-62325.rs:19:30: 19:32 (#4),
+                        span: $DIR/dollar-crate-issue-62325.rs:19:31: 19:32 (#4),
                     },
                     Ident {
                         ident: "S",
@@ -85,12 +85,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
                     Punct {
                         ch: ':',
                         spacing: Joint,
-                        span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:32 (#12),
+                        span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:31 (#12),
                     },
                     Punct {
                         ch: ':',
                         spacing: Alone,
-                        span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:32 (#12),
+                        span: $DIR/auxiliary/dollar-crate-external.rs:21:31: 21:32 (#12),
                     },
                     Ident {
                         ident: "S",
diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout
index d01fcb9d0e4..4e169d47e1a 100644
--- a/src/test/ui/proc-macro/dollar-crate.stdout
+++ b/src/test/ui/proc-macro/dollar-crate.stdout
@@ -18,12 +18,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/dollar-crate.rs:20:32: 20:34 (#4),
+                span: $DIR/dollar-crate.rs:20:32: 20:33 (#4),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/dollar-crate.rs:20:32: 20:34 (#4),
+                span: $DIR/dollar-crate.rs:20:33: 20:34 (#4),
             },
             Ident {
                 ident: "S",
@@ -58,12 +58,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/dollar-crate.rs:24:28: 24:30 (#4),
+                span: $DIR/dollar-crate.rs:24:28: 24:29 (#4),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/dollar-crate.rs:24:28: 24:30 (#4),
+                span: $DIR/dollar-crate.rs:24:29: 24:30 (#4),
             },
             Ident {
                 ident: "S",
@@ -98,12 +98,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/dollar-crate.rs:27:28: 27:30 (#4),
+                span: $DIR/dollar-crate.rs:27:28: 27:29 (#4),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/dollar-crate.rs:27:28: 27:30 (#4),
+                span: $DIR/dollar-crate.rs:27:29: 27:30 (#4),
             },
             Ident {
                 ident: "S",
@@ -138,12 +138,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:30 (#15),
+                span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:29 (#15),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:30 (#15),
+                span: $DIR/auxiliary/dollar-crate-external.rs:7:29: 7:30 (#15),
             },
             Ident {
                 ident: "S",
@@ -178,12 +178,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:26 (#15),
+                span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:25 (#15),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:26 (#15),
+                span: $DIR/auxiliary/dollar-crate-external.rs:11:25: 11:26 (#15),
             },
             Ident {
                 ident: "S",
@@ -218,12 +218,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:26 (#15),
+                span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:25 (#15),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:26 (#15),
+                span: $DIR/auxiliary/dollar-crate-external.rs:14:25: 14:26 (#15),
             },
             Ident {
                 ident: "S",
diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr
index f1a167e37b4..39bf28dba96 100644
--- a/src/test/ui/proc-macro/generate-mod.stderr
+++ b/src/test/ui/proc-macro/generate-mod.stderr
@@ -44,9 +44,9 @@ error: cannot find type `FromOutside` in this scope
 LL | #[derive(generate_mod::CheckDerive)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
-   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
+   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: cannot find type `OuterDerive` in this scope
@@ -89,9 +89,9 @@ error: cannot find type `FromOutside` in this scope
 LL | #[derive(generate_mod::CheckDerive)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
-   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
+   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -101,9 +101,9 @@ error: cannot find type `OuterDerive` in this scope
 LL | #[derive(generate_mod::CheckDerive)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
-   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
+   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -113,9 +113,9 @@ error: cannot find type `FromOutside` in this scope
 LL |     #[derive(generate_mod::CheckDerive)]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
-   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
+   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -125,9 +125,9 @@ error: cannot find type `OuterDerive` in this scope
 LL |     #[derive(generate_mod::CheckDerive)]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
-   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
+   = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default
    = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -137,13 +137,13 @@ warning: cannot find type `FromOutside` in this scope
 LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
 note: the lint level is defined here
   --> $DIR/generate-mod.rs:30:10
    |
 LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
    = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 Future breakage diagnostic:
@@ -153,12 +153,12 @@ warning: cannot find type `OuterDeriveLint` in this scope
 LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
 note: the lint level is defined here
   --> $DIR/generate-mod.rs:30:10
    |
 LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
    = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr
index 45b014c4b69..9441cdcc8cf 100644
--- a/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr
+++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr
@@ -26,9 +26,9 @@ LL | #[empty_helper]
 LL | #[derive(Empty)]
    |          ----- the attribute is introduced here
    |
-   = note: `#[warn(legacy_derive_helpers)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
+   = note: `#[warn(legacy_derive_helpers)]` on by default
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr b/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr
index 4286896dfc3..2d357d04d5c 100644
--- a/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr
+++ b/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr
@@ -31,9 +31,9 @@ error: custom inner attributes are unstable
 LL | #![rustfmt::skip]
    |    ^^^^^^^^^^^^^
    |
-   = note: `#[deny(soft_unstable)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
+   = note: `#[deny(soft_unstable)]` on by default
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/proc-macro/inner-attrs.stdout b/src/test/ui/proc-macro/inner-attrs.stdout
index 490fc02f510..ee8adf0b4a9 100644
--- a/src/test/ui/proc-macro/inner-attrs.stdout
+++ b/src/test/ui/proc-macro/inner-attrs.stdout
@@ -627,12 +627,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
                                     Punct {
                                         ch: '=',
                                         spacing: Joint,
-                                        span: $DIR/inner-attrs.rs:39:15: 39:17 (#0),
+                                        span: $DIR/inner-attrs.rs:39:15: 39:16 (#0),
                                     },
                                     Punct {
                                         ch: '>',
                                         spacing: Alone,
-                                        span: $DIR/inner-attrs.rs:39:15: 39:17 (#0),
+                                        span: $DIR/inner-attrs.rs:39:16: 39:17 (#0),
                                     },
                                     Group {
                                         delimiter: Brace,
diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
index be4239089e8..ebb8e825e6a 100644
--- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
+++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
@@ -4,10 +4,10 @@ error: using `procedural-masquerade` crate
 LL | enum ProceduralMasqueradeDummyType {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(proc_macro_back_compat)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
    = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
+   = note: `#[deny(proc_macro_back_compat)]` on by default
 
 error: using `procedural-masquerade` crate
   --> $DIR/issue-73933-procedural-masquerade.rs:7:6
@@ -48,10 +48,10 @@ error: using `procedural-masquerade` crate
 LL | enum ProceduralMasqueradeDummyType {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(proc_macro_back_compat)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
    = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
+   = note: `#[deny(proc_macro_back_compat)]` on by default
 
 Future breakage diagnostic:
 error: using `procedural-masquerade` crate
@@ -60,10 +60,10 @@ error: using `procedural-masquerade` crate
 LL | enum ProceduralMasqueradeDummyType {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(proc_macro_back_compat)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
    = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
+   = note: `#[deny(proc_macro_back_compat)]` on by default
 
 Future breakage diagnostic:
 error: using `procedural-masquerade` crate
@@ -72,10 +72,10 @@ error: using `procedural-masquerade` crate
 LL | enum ProceduralMasqueradeDummyType {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(proc_macro_back_compat)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
    = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
+   = note: `#[deny(proc_macro_back_compat)]` on by default
 
 Future breakage diagnostic:
 error: using `procedural-masquerade` crate
@@ -84,8 +84,8 @@ error: using `procedural-masquerade` crate
 LL | enum ProceduralMasqueradeDummyType {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(proc_macro_back_compat)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
    = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
+   = note: `#[deny(proc_macro_back_compat)]` on by default
 
diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr b/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr
index 69d72b55cdf..6d1efb0dc28 100644
--- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr
+++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr
@@ -7,9 +7,9 @@ LL | #[print_helper(a)]
 LL | #[derive(Print)]
    |          ----- the attribute is introduced here
    |
-   = note: `#[warn(legacy_derive_helpers)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
+   = note: `#[warn(legacy_derive_helpers)]` on by default
 
 warning: derive helper attribute is used before it is introduced
   --> $DIR/issue-75930-derive-cfg.rs:19:3
diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
index c81fa201cbc..83afd0d3eae 100644
--- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
+++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
@@ -489,12 +489,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
                                     Punct {
                                         ch: '=',
                                         spacing: Joint,
-                                        span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:34 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:33 (#0),
                                     },
                                     Punct {
                                         ch: '>',
                                         spacing: Alone,
-                                        span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:34 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:33:33: 33:34 (#0),
                                     },
                                     Group {
                                         delimiter: Brace,
@@ -567,12 +567,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
                                     Punct {
                                         ch: '=',
                                         spacing: Joint,
-                                        span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:61 (#0),
                                     },
                                     Punct {
                                         ch: '>',
                                         spacing: Alone,
-                                        span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:34:61: 34:62 (#0),
                                     },
                                     Group {
                                         delimiter: Brace,
@@ -591,12 +591,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
                                     Punct {
                                         ch: '=',
                                         spacing: Joint,
-                                        span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:16 (#0),
                                     },
                                     Punct {
                                         ch: '>',
                                         spacing: Alone,
-                                        span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:35:16: 35:17 (#0),
                                     },
                                     Group {
                                         delimiter: Brace,
@@ -1519,12 +1519,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
                                     Punct {
                                         ch: '=',
                                         spacing: Joint,
-                                        span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:61 (#0),
                                     },
                                     Punct {
                                         ch: '>',
                                         spacing: Alone,
-                                        span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:34:61: 34:62 (#0),
                                     },
                                     Group {
                                         delimiter: Brace,
@@ -1543,12 +1543,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
                                     Punct {
                                         ch: '=',
                                         spacing: Joint,
-                                        span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:16 (#0),
                                     },
                                     Punct {
                                         ch: '>',
                                         spacing: Alone,
-                                        span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0),
+                                        span: $DIR/issue-75930-derive-cfg.rs:35:16: 35:17 (#0),
                                     },
                                     Group {
                                         delimiter: Brace,
diff --git a/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout b/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout
index 5493f9c7b60..09eb33f7e31 100644
--- a/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout
+++ b/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout
@@ -41,12 +41,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
                     Punct {
                         ch: '=',
                         spacing: Joint,
-                        span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:23 (#0),
+                        span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:22 (#0),
                     },
                     Punct {
                         ch: '>',
                         spacing: Alone,
-                        span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:23 (#0),
+                        span: $DIR/issue-76182-leading-vert-pat.rs:15:22: 15:23 (#0),
                     },
                     Group {
                         delimiter: Parenthesis,
diff --git a/src/test/ui/proc-macro/meta-macro-hygiene.stdout b/src/test/ui/proc-macro/meta-macro-hygiene.stdout
index 5d04fe1e3de..2494af1208f 100644
--- a/src/test/ui/proc-macro/meta-macro-hygiene.stdout
+++ b/src/test/ui/proc-macro/meta-macro-hygiene.stdout
@@ -1,5 +1,5 @@
 Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5)
-Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#4) }]
+Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:44 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:44: 24:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#4) }]
 Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }]
 #![feature /* 0#0 */(prelude_import)]
 // aux-build:make-macro.rs
diff --git a/src/test/ui/proc-macro/proc-macro-attributes.stderr b/src/test/ui/proc-macro/proc-macro-attributes.stderr
index b66e4575e11..140d8790690 100644
--- a/src/test/ui/proc-macro/proc-macro-attributes.stderr
+++ b/src/test/ui/proc-macro/proc-macro-attributes.stderr
@@ -85,9 +85,9 @@ LL | #[B]
 LL | #[derive(B)]
    |          - the attribute is introduced here
    |
-   = note: `#[warn(legacy_derive_helpers)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
+   = note: `#[warn(legacy_derive_helpers)]` on by default
 
 warning: derive helper attribute is used before it is introduced
   --> $DIR/proc-macro-attributes.rs:10:3
diff --git a/src/test/ui/proc-macro/proc-macro-gates.stderr b/src/test/ui/proc-macro/proc-macro-gates.stderr
index 118213a17d4..3feb9b8290f 100644
--- a/src/test/ui/proc-macro/proc-macro-gates.stderr
+++ b/src/test/ui/proc-macro/proc-macro-gates.stderr
@@ -82,9 +82,9 @@ error: inner macro attributes are unstable
 LL |     #![test]
    |        ^^^^
    |
-   = note: `#[deny(soft_unstable)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
+   = note: `#[deny(soft_unstable)]` on by default
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr
index 1ce5e02bd82..9cdb2a21b04 100644
--- a/src/test/ui/proc-macro/three-equals.stderr
+++ b/src/test/ui/proc-macro/three-equals.stderr
@@ -8,16 +8,16 @@ LL |     three_equals!(==);
    = note: this error originates in the macro `three_equals` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected EOF, found `=`.
-  --> $DIR/three-equals.rs:15:21
+  --> $DIR/three-equals.rs:15:22
    |
 LL |     three_equals!(=====);
-   |                     ^^
+   |                      ^
    |
 note: last good input was here
   --> $DIR/three-equals.rs:15:21
    |
 LL |     three_equals!(=====);
-   |                     ^^
+   |                     ^
    = help: input must be: `===`
 
 error: expected `=`, found `abc`.
diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs
index 08b30b600e7..d0a938c03e8 100644
--- a/src/test/ui/process/process-panic-after-fork.rs
+++ b/src/test/ui/process/process-panic-after-fork.rs
@@ -6,6 +6,7 @@
 // ignore-emscripten no processes
 // ignore-sgx no processes
 // ignore-android: FIXME(#85261)
+// ignore-fuchsia no fork
 
 #![feature(rustc_private)]
 #![feature(never_type)]
diff --git a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
index e4d73c6475d..c7fadc6f929 100644
--- a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
+++ b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
@@ -28,9 +28,9 @@ error: extern crate `core` is private, and cannot be re-exported (error E0365),
 LL | pub use core as reexported_core;
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(pub_use_of_private_extern_crate)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
+   = note: `#[deny(pub_use_of_private_extern_crate)]` on by default
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.stderr b/src/test/ui/range/range-inclusive-pattern-precedence.stderr
index 10513374cf8..f6788d034e6 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence.stderr
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.stderr
@@ -10,13 +10,13 @@ warning: `...` range patterns are deprecated
 LL |         &0...9 => {}
    |         ^^^^^^ help: use `..=` for an inclusive range: `&(0..=9)`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/range-inclusive-pattern-precedence.rs:7:9
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
index cdec41d7f75..bb4e3a13a5c 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
+++ b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
@@ -10,13 +10,13 @@ warning: `...` range patterns are deprecated
 LL |         box 0...9 => {}
    |              ^^^ help: use `..=` for an inclusive range
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/range-inclusive-pattern-precedence2.rs:5:9
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr
index 32f25faf3e8..59fba5af00e 100644
--- a/src/test/ui/recursion/issue-83150.stderr
+++ b/src/test/ui/recursion/issue-83150.stderr
@@ -6,8 +6,8 @@ LL | fn func<T: Iterator<Item = u8>>(iter: &mut T) {
 LL |     func(&mut iter.map(|x| x + 1))
    |     ------------------------------ recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
    |
diff --git a/src/test/ui/regions/issue-102374.rs b/src/test/ui/regions/issue-102374.rs
new file mode 100644
index 00000000000..e0a1164211a
--- /dev/null
+++ b/src/test/ui/regions/issue-102374.rs
@@ -0,0 +1,20 @@
+use std::cell::Cell;
+
+#[rustfmt::skip]
+fn f(
+    f: for<'a, 'b, 'c, 'd, 'e, 'f, 'g,
+           'h, 'i, 'j, 'k, 'l, 'm, 'n,
+           'o, 'p, 'q, 'r, 's, 't, 'u,
+           'v, 'w, 'x, 'y, 'z, 'z0>
+        fn(Cell<(&   i32, &'a i32, &'b i32, &'c i32, &'d i32,
+                 &'e i32, &'f i32, &'g i32, &'h i32, &'i i32,
+                 &'j i32, &'k i32, &'l i32, &'m i32, &'n i32,
+                 &'o i32, &'p i32, &'q i32, &'r i32, &'s i32,
+                 &'t i32, &'u i32, &'v i32, &'w i32, &'x i32,
+                 &'y i32, &'z i32, &'z0 i32)>),
+) -> i32 {
+    f
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/regions/issue-102374.stderr b/src/test/ui/regions/issue-102374.stderr
new file mode 100644
index 00000000000..31b855c36be
--- /dev/null
+++ b/src/test/ui/regions/issue-102374.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-102374.rs:16:5
+   |
+LL | ) -> i32 {
+   |      --- expected `i32` because of return type
+LL |     f
+   |     ^ expected `i32`, found fn pointer
+   |
+   = note:    expected type `i32`
+           found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<(&'z1 i32, &'a i32, &'b i32, &'c i32, &'d i32, &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, &'y i32, &'z i32, &'z0 i32)>)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr b/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr
index a2396ad4286..ea43dde11f8 100644
--- a/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr
+++ b/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr
@@ -7,8 +7,8 @@ LL |
 LL |     (|x| f(x))(call_rec(f))
    |                ----------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0505]: cannot move out of `f` because it is borrowed
   --> $DIR/region-bound-on-closure-outlives-call.rs:3:25
diff --git a/src/test/ui/repr/repr-transparent-issue-87496.stderr b/src/test/ui/repr/repr-transparent-issue-87496.stderr
index 3dc13b1c13c..aee31212b4e 100644
--- a/src/test/ui/repr/repr-transparent-issue-87496.stderr
+++ b/src/test/ui/repr/repr-transparent-issue-87496.stderr
@@ -4,13 +4,13 @@ warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
 LL |     fn good17(p: TransparentCustomZst);
    |                  ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
-   = note: `#[warn(improper_ctypes)]` on by default
    = note: this struct contains only zero-sized fields
 note: the type is defined here
   --> $DIR/repr-transparent-issue-87496.rs:6:1
    |
 LL | struct TransparentCustomZst(());
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(improper_ctypes)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/repr/repr-transparent-non-exhaustive.rs b/src/test/ui/repr/repr-transparent-non-exhaustive.rs
index 9ccd8610dad..506f1dcf3fc 100644
--- a/src/test/ui/repr/repr-transparent-non-exhaustive.rs
+++ b/src/test/ui/repr/repr-transparent-non-exhaustive.rs
@@ -35,62 +35,62 @@ pub struct T4(Sized, ExternalIndirection<(InternalPrivate, InternalNonExhaustive
 
 #[repr(transparent)]
 pub struct T5(Sized, Private);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T6(Sized, NonExhaustive);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T7(Sized, NonExhaustiveEnum);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T8(Sized, NonExhaustiveVariant);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T9(Sized, InternalIndirection<Private>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T10(Sized, InternalIndirection<NonExhaustive>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T13(Sized, ExternalIndirection<Private>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T14(Sized, ExternalIndirection<NonExhaustive>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 #[repr(transparent)]
 pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>);
-//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
 //~| WARN this was previously accepted by the compiler
 
 fn main() {}
diff --git a/src/test/ui/repr/repr-transparent-non-exhaustive.stderr b/src/test/ui/repr/repr-transparent-non-exhaustive.stderr
index 3b1e334a0cb..16edf59c7cc 100644
--- a/src/test/ui/repr/repr-transparent-non-exhaustive.stderr
+++ b/src/test/ui/repr/repr-transparent-non-exhaustive.stderr
@@ -1,19 +1,19 @@
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:37:22
    |
 LL | pub struct T5(Sized, Private);
    |                      ^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
+   = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
 note: the lint level is defined here
   --> $DIR/repr-transparent-non-exhaustive.rs:1:9
    |
 LL | #![deny(repr_transparent_external_private_fields)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
-   = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:42:22
    |
 LL | pub struct T6(Sized, NonExhaustive);
@@ -23,7 +23,7 @@ LL | pub struct T6(Sized, NonExhaustive);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:47:22
    |
 LL | pub struct T7(Sized, NonExhaustiveEnum);
@@ -33,7 +33,7 @@ LL | pub struct T7(Sized, NonExhaustiveEnum);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:52:22
    |
 LL | pub struct T8(Sized, NonExhaustiveVariant);
@@ -43,7 +43,7 @@ LL | pub struct T8(Sized, NonExhaustiveVariant);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:57:22
    |
 LL | pub struct T9(Sized, InternalIndirection<Private>);
@@ -53,7 +53,7 @@ LL | pub struct T9(Sized, InternalIndirection<Private>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:62:23
    |
 LL | pub struct T10(Sized, InternalIndirection<NonExhaustive>);
@@ -63,7 +63,7 @@ LL | pub struct T10(Sized, InternalIndirection<NonExhaustive>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:67:23
    |
 LL | pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>);
@@ -73,7 +73,7 @@ LL | pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:72:23
    |
 LL | pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>);
@@ -83,7 +83,7 @@ LL | pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:77:23
    |
 LL | pub struct T13(Sized, ExternalIndirection<Private>);
@@ -93,7 +93,7 @@ LL | pub struct T13(Sized, ExternalIndirection<Private>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:82:23
    |
 LL | pub struct T14(Sized, ExternalIndirection<NonExhaustive>);
@@ -103,7 +103,7 @@ LL | pub struct T14(Sized, ExternalIndirection<NonExhaustive>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:87:23
    |
 LL | pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>);
@@ -113,7 +113,7 @@ LL | pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>);
    = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
    = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
 
-error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
+error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types
   --> $DIR/repr-transparent-non-exhaustive.rs:92:23
    |
 LL | pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>);
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
index 659a9812672..10dd635ff96 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
@@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a
 LL |         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 note: the lint level is defined here
   --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9
    |
 LL | #![warn(indirect_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
index c8c36510542..66aecbc4f30 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
@@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a
 LL |         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 note: the lint level is defined here
   --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9
    |
 LL | #![warn(indirect_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
index 8abbd5d342b..ee92954a693 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
@@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a
 LL |         WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
    |         ^^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 note: the lint level is defined here
   --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9
    |
 LL | #![warn(indirect_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
index 3a716d54fcc..f0c492d6a73 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
@@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a
 LL |         WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
    |         ^^^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 note: the lint level is defined here
   --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9
    |
 LL | #![warn(indirect_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
index a50093a5b11..955ab4b548b 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
@@ -4,13 +4,13 @@ warning: to use a constant of type `B` in a pattern, `B` must be annotated with
 LL |         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
    |         ^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 note: the lint level is defined here
   --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9
    |
 LL | #![warn(indirect_structural_match, nontrivial_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
   --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
index 8cf87cc85a1..d6afc0255ec 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
@@ -4,13 +4,13 @@ warning: function pointers and unsized pointers in patterns behave unpredictably
 LL |     B(TEST) => println!("matched"),
    |       ^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
 note: the lint level is defined here
   --> $DIR/issue-63479-match-fnptr.rs:8:9
    |
 LL | #![warn(pointer_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr
index 4e2961e5e23..f37255d0828 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr
@@ -4,13 +4,13 @@ error: floating-point types cannot be used in patterns
 LL |         NAN => {},
    |         ^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
 note: the lint level is defined here
   --> $DIR/issue-6804.rs:4:9
    |
 LL | #![deny(illegal_floating_point_literal_pattern)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
 
 error: floating-point types cannot be used in patterns
   --> $DIR/issue-6804.rs:17:10
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr
index df4809dabf1..616ed9e484b 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr
@@ -10,9 +10,9 @@ warning: floating-point types cannot be used in patterns
 LL |         f32::INFINITY => { }
    |         ^^^^^^^^^^^^^
    |
-   = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
+   = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 7d81de43854..7c1390cdc64 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -13,7 +13,7 @@ LL | | }
 note: required by a bound in `assert_test_result`
   --> $SRC_DIR/test/src/lib.rs:LL:COL
    |
-LL | pub fn assert_test_result<T: Termination>(result: T) {
+LL | pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> {
    |                              ^^^^^^^^^^^ required by this bound in `assert_test_result`
    = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr
index 8a18ebc16fe..43c8e1015e6 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr
@@ -4,12 +4,12 @@ error: `extern` block uses type `NonExhaustiveEnum`, which is not FFI-safe
 LL |     pub fn non_exhaustive_enum(_: NonExhaustiveEnum);
    |                                   ^^^^^^^^^^^^^^^^^ not FFI-safe
    |
+   = note: this enum is non-exhaustive
 note: the lint level is defined here
   --> $DIR/extern_crate_improper.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = note: this enum is non-exhaustive
 
 error: `extern` block uses type `NormalStruct`, which is not FFI-safe
   --> $DIR/extern_crate_improper.rs:14:44
diff --git a/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
index 4b9f8564d23..996bd4a1298 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
@@ -4,13 +4,13 @@ warning: some fields are not explicitly listed
 LL |         VariantNonExhaustive::Bar { x, .. } => {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed
    |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:99:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
-   = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
   --> $DIR/omitted-patterns.rs:107:9
@@ -18,13 +18,13 @@ warning: some fields are not explicitly listed
 LL |     let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed
    |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:106:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
-   = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
   --> $DIR/omitted-patterns.rs:115:29
@@ -32,13 +32,13 @@ warning: some fields are not explicitly listed
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed
    |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:114:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
-   = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
   --> $DIR/omitted-patterns.rs:115:9
@@ -55,13 +55,13 @@ warning: some fields are not explicitly listed
 LL |     let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable2` not listed
    |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:172:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
-   = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
   --> $DIR/omitted-patterns.rs:181:9
@@ -69,13 +69,13 @@ warning: some fields are not explicitly listed
 LL |     let UnstableStruct { stable, stable2, .. } = UnstableStruct::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable` not listed
    |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:180:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
-   = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:58:9
@@ -83,13 +83,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `NonExhaustiveEnum::Struct { .. }` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:57:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:65:9
@@ -97,13 +97,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `NonExhaustiveEnum::Tuple(_)` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:64:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:75:9
@@ -111,13 +111,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `NonExhaustiveEnum::Unit` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:74:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:92:32
@@ -125,13 +125,13 @@ error: some variants are not matched explicitly
 LL |         NestedNonExhaustive::A(_) => {}
    |                                ^ patterns `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:89:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:94:9
@@ -148,13 +148,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `NonExhaustiveSingleVariant::A(_)` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:130:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:144:9
@@ -162,13 +162,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `UnstableEnum::Unstable` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:143:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/omitted-patterns.rs:168:9
@@ -176,13 +176,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `OnlyUnstableEnum::Unstable2` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/omitted-patterns.rs:165:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: aborting due to 8 previous errors; 6 warnings emitted
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
index 533e8abf2d6..f38368590fb 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
@@ -4,13 +4,13 @@ warning: some fields are not explicitly listed
 LL |     let UnstableStruct { stable, .. } = UnstableStruct::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `stable2` not listed
    |
+   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
+   = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/stable-omitted-patterns.rs:38:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all fields are mentioned explicitly by adding the suggested fields
-   = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
   --> $DIR/stable-omitted-patterns.rs:23:9
@@ -18,13 +18,13 @@ error: some variants are not matched explicitly
 LL |         _ => {}
    |         ^ pattern `UnstableEnum::Stable2` not covered
    |
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 note: the lint level is defined here
   --> $DIR/stable-omitted-patterns.rs:22:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.stderr b/src/test/ui/rfc-2294-if-let-guard/warns.stderr
index cf64513f9c8..75f22ac8dc0 100644
--- a/src/test/ui/rfc-2294-if-let-guard/warns.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/warns.stderr
@@ -4,13 +4,13 @@ error: irrefutable `if let` guard pattern
 LL |         Some(x) if let () = x => {}
    |                        ^^
    |
+   = note: this pattern will always match, so the guard is useless
+   = help: consider removing the guard and adding a `let` inside the match arm
 note: the lint level is defined here
   --> $DIR/warns.rs:3:8
    |
 LL | #[deny(irrefutable_let_patterns)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: this pattern will always match, so the guard is useless
-   = help: consider removing the guard and adding a `let` inside the match arm
 
 error: unreachable pattern
   --> $DIR/warns.rs:15:25
diff --git a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr
index d1d5288aea3..2570c36b810 100644
--- a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr
@@ -4,13 +4,13 @@ error: leading irrefutable pattern in let chain
 LL |     if let first = &opt && let Some(ref second) = first && let None = second.start {}
    |        ^^^^^^^^^^^^^^^^
    |
+   = note: this pattern will always match
+   = help: consider moving it outside of the construct
 note: the lint level is defined here
   --> $DIR/irrefutable-lets.rs:6:30
    |
 LL | #![cfg_attr(disallowed, deny(irrefutable_let_patterns))]
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: this pattern will always match
-   = help: consider moving it outside of the construct
 
 error: irrefutable `if let` patterns
   --> $DIR/irrefutable-lets.rs:19:8
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
index d3e14a53a2f..414a8c87d2c 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
@@ -2,13 +2,18 @@
 
 struct S;
 
-impl PartialEq for S {
+#[const_trait]
+trait Foo {
+    fn eq(&self, _: &Self) -> bool;
+}
+
+impl Foo for S {
     fn eq(&self, _: &S) -> bool {
         true
     }
 }
 
-const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
+const fn equals_self<T: ~const Foo>(t: &T) -> bool {
     true
 }
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
index 0a2a5f0f245..706f5234365 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
@@ -1,26 +1,21 @@
-error[E0277]: can't compare `S` with `S` in const contexts
-  --> $DIR/call-generic-method-nonconst.rs:18:34
+error[E0277]: the trait bound `S: ~const Foo` is not satisfied
+  --> $DIR/call-generic-method-nonconst.rs:23:34
    |
 LL | pub const EQ: bool = equals_self(&S);
-   |                      ----------- ^^ no implementation for `S == S`
+   |                      ----------- ^^ the trait `~const Foo` is not implemented for `S`
    |                      |
    |                      required by a bound introduced by this call
    |
-   = help: the trait `~const PartialEq` is not implemented for `S`
-note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
-  --> $DIR/call-generic-method-nonconst.rs:18:34
+note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
+  --> $DIR/call-generic-method-nonconst.rs:23:34
    |
 LL | pub const EQ: bool = equals_self(&S);
    |                                  ^^
 note: required by a bound in `equals_self`
-  --> $DIR/call-generic-method-nonconst.rs:11:25
-   |
-LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
-   |                         ^^^^^^^^^^^^^^^^ required by this bound in `equals_self`
-help: consider annotating `S` with `#[derive(PartialEq)]`
-   |
-LL | #[derive(PartialEq)]
+  --> $DIR/call-generic-method-nonconst.rs:16:25
    |
+LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
+   |                         ^^^^^^^^^^ required by this bound in `equals_self`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index 2295a822fa4..ddf0e2d91c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:43:5
+  --> $DIR/const-drop-fail.rs:44:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -9,7 +9,7 @@ LL |     NonTrivialDrop,
    |
    = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
@@ -21,7 +21,7 @@ LL |     &mut NonTrivialDrop,
    |     ++++
 
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -30,7 +30,7 @@ LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
    |
 note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue`
 LL | struct ConstImplWithDropGlue(NonTrivialDrop);
    |        ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
-  --> $DIR/const-drop-fail.rs:47:5
+  --> $DIR/const-drop-fail.rs:48:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -55,14 +55,14 @@ LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
    |
 note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
-  --> $DIR/const-drop-fail.rs:28:25
+  --> $DIR/const-drop-fail.rs:29:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
    |                         ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
index 001dd430a86..565e2c77ac5 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs
@@ -19,7 +19,8 @@ impl const Drop for ConstImplWithDropGlue {
     fn drop(&mut self) {}
 }
 
-trait A { fn a() { println!("A"); } }
+#[const_trait]
+trait A { fn a() { } }
 
 impl A for NonTrivialDrop {}
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index 2295a822fa4..ddf0e2d91c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:43:5
+  --> $DIR/const-drop-fail.rs:44:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -9,7 +9,7 @@ LL |     NonTrivialDrop,
    |
    = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
@@ -21,7 +21,7 @@ LL |     &mut NonTrivialDrop,
    |     ++++
 
 error[E0277]: can't drop `NonTrivialDrop` in const contexts
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -30,7 +30,7 @@ LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
    |
 note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
-  --> $DIR/const-drop-fail.rs:45:5
+  --> $DIR/const-drop-fail.rs:46:5
    |
 LL |     ConstImplWithDropGlue(NonTrivialDrop),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue`
 LL | struct ConstImplWithDropGlue(NonTrivialDrop);
    |        ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
 
 error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied
-  --> $DIR/const-drop-fail.rs:47:5
+  --> $DIR/const-drop-fail.rs:48:5
    |
 LL |         const _: () = check($exp);
    |                       ----- required by a bound introduced by this call
@@ -55,14 +55,14 @@ LL |     ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>`
    |
 note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
-  --> $DIR/const-drop-fail.rs:28:25
+  --> $DIR/const-drop-fail.rs:29:25
    |
 LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
    |                         ^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct`
 note: required by a bound in `check`
-  --> $DIR/const-drop-fail.rs:34:19
+  --> $DIR/const-drop-fail.rs:35:19
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                   ^^^^^^^^^^^^^^^ required by this bound in `check`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
index 1aff0562785..2b4963991db 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
@@ -1,9 +1,9 @@
 #![feature(const_trait_impl)]
 
 pub trait A {}
-//~^ NOTE: this trait must be annotated with `#[const_trait]`
+//~^ HELP: mark `A` as const
 
 impl const A for () {}
-//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]`
+//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
 
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
index 6b465a9c62e..478adcf3e9e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
@@ -1,14 +1,14 @@
-error: const `impl`s must be for traits marked with `#[const_trait]`
-  --> $DIR/const-impl-requires-const-trait.rs:6:1
+error: const `impl` for trait `A` which is not marked with `#[const_trait]`
+  --> $DIR/const-impl-requires-const-trait.rs:6:12
    |
+LL | pub trait A {}
+   | - help: mark `A` as const: `#[const_trait]`
+...
 LL | impl const A for () {}
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-note: this trait must be annotated with `#[const_trait]`
-  --> $DIR/const-impl-requires-const-trait.rs:3:1
+   |            ^
    |
-LL | pub trait A {}
-   | ^^^^^^^^^^^
+   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+   = note: adding a non-const method body in the future would be a breaking change
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
index d27291231fb..96acdc300e0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs
@@ -1,5 +1,6 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Tr {}
 impl Tr for () {}
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
index 7542b81fe2a..d102956cd2e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
@@ -1,16 +1,16 @@
 error[E0277]: the trait bound `(): ~const Tr` is not satisfied
-  --> $DIR/default-method-body-is-const-body-checking.rs:11:15
+  --> $DIR/default-method-body-is-const-body-checking.rs:12:15
    |
 LL |         foo::<()>();
    |               ^^ the trait `~const Tr` is not implemented for `()`
    |
 note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
-  --> $DIR/default-method-body-is-const-body-checking.rs:11:15
+  --> $DIR/default-method-body-is-const-body-checking.rs:12:15
    |
 LL |         foo::<()>();
    |               ^^
 note: required by a bound in `foo`
-  --> $DIR/default-method-body-is-const-body-checking.rs:6:28
+  --> $DIR/default-method-body-is-const-body-checking.rs:7:28
    |
 LL | const fn foo<T>() where T: ~const Tr {}
    |                            ^^^^^^^^^ required by this bound in `foo`
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs
new file mode 100644
index 00000000000..fe4e9108130
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs
@@ -0,0 +1,15 @@
+#![feature(allocator_api)]
+#![feature(const_trait_impl)]
+
+use core::convert::{From, TryFrom};
+//~^ ERROR
+//~| ERROR
+
+use std::pin::Pin;
+use std::alloc::Allocator;
+impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
+where
+    A: 'static,
+{}
+
+pub fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr
new file mode 100644
index 00000000000..8bf00eaff1f
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr
@@ -0,0 +1,19 @@
+error[E0433]: failed to resolve: maybe a missing crate `core`?
+  --> $DIR/issue-102156.rs:4:5
+   |
+LL | use core::convert::{From, TryFrom};
+   |     ^^^^ maybe a missing crate `core`?
+   |
+   = help: consider adding `extern crate core` to use the `core` crate
+
+error[E0433]: failed to resolve: maybe a missing crate `core`?
+  --> $DIR/issue-102156.rs:4:5
+   |
+LL | use core::convert::{From, TryFrom};
+   |     ^^^^ maybe a missing crate `core`?
+   |
+   = help: consider adding `extern crate core` to use the `core` crate
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
new file mode 100644
index 00000000000..b86acb2cc9a
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:11:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
new file mode 100644
index 00000000000..b86acb2cc9a
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-2.rs:11:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
index 7b38c15afc2..d183efde2df 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs
@@ -1,14 +1,19 @@
 #![feature(const_trait_impl)]
 
+// revisions: yy yn ny nn
+
+#[cfg_attr(any(yy, yn), const_trait)]
 trait Foo {
     fn a(&self);
 }
+
+#[cfg_attr(any(yy, ny), const_trait)]
 trait Bar: ~const Foo {}
+//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
 
 const fn foo<T: Bar>(x: &T) {
     x.a();
-    //~^ ERROR the trait bound
-    //~| ERROR cannot call
+    //[yn,yy]~^ ERROR the trait bound
 }
 
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr
deleted file mode 100644
index 1766cdbee8a..00000000000
--- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error[E0277]: the trait bound `T: ~const Foo` is not satisfied
-  --> $DIR/super-traits-fail-2.rs:9:7
-   |
-LL |     x.a();
-   |       ^^^ the trait `~const Foo` is not implemented for `T`
-   |
-note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/super-traits-fail-2.rs:9:7
-   |
-LL |     x.a();
-   |       ^^^
-
-error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
-  --> $DIR/super-traits-fail-2.rs:9:7
-   |
-LL |     x.a();
-   |       ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0015, E0277.
-For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
new file mode 100644
index 00000000000..b52eb2c0332
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^ - required by a bound introduced by this call
+   |     |
+   |     the trait `~const Foo` is not implemented for `T`
+   |
+note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^
+help: consider further restricting this bound
+   |
+LL | const fn foo<T: Bar + ~const Foo>(x: &T) {
+   |                     ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
new file mode 100644
index 00000000000..b52eb2c0332
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `T: ~const Foo` is not satisfied
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^ - required by a bound introduced by this call
+   |     |
+   |     the trait `~const Foo` is not implemented for `T`
+   |
+note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
+  --> $DIR/super-traits-fail-2.rs:15:5
+   |
+LL |     x.a();
+   |     ^
+help: consider further restricting this bound
+   |
+LL | const fn foo<T: Bar + ~const Foo>(x: &T) {
+   |                     ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
new file mode 100644
index 00000000000..191edca1761
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
@@ -0,0 +1,14 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:12:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:15:17
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                 ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
new file mode 100644
index 00000000000..a3b4c302a57
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:12:12
+   |
+LL | trait Bar: ~const Foo {}
+   |            ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
new file mode 100644
index 00000000000..70d2936d3b2
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs
@@ -0,0 +1,20 @@
+#![feature(const_trait_impl)]
+
+// revisions: yy yn ny nn
+//[yy] check-pass
+
+#[cfg_attr(any(yy, yn), const_trait)]
+trait Foo {
+    fn a(&self);
+}
+
+#[cfg_attr(any(yy, ny), const_trait)]
+trait Bar: ~const Foo {}
+//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
+
+const fn foo<T: ~const Bar>(x: &T) {
+    //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
+    x.a();
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
new file mode 100644
index 00000000000..9d611665465
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
@@ -0,0 +1,8 @@
+error: ~const can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:15:17
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                 ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
index 350be4d8250..5bd52151f42 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs
@@ -1,6 +1,7 @@
 #![feature(const_trait_impl)]
 #![feature(associated_type_bounds)]
 
+#[const_trait]
 trait T {}
 struct S;
 impl T for S {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
index 8d781d063d1..5d213315634 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
@@ -1,5 +1,5 @@
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:8:19
+  --> $DIR/tilde-const-invalid-places.rs:9:19
    |
 LL | fn rpit() -> impl ~const T { S }
    |                   ^^^^^^^^
@@ -7,7 +7,7 @@ LL | fn rpit() -> impl ~const T { S }
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:11:17
+  --> $DIR/tilde-const-invalid-places.rs:12:17
    |
 LL | fn apit(_: impl ~const T) {}
    |                 ^^^^^^^^
@@ -15,7 +15,7 @@ LL | fn apit(_: impl ~const T) {}
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:14:50
+  --> $DIR/tilde-const-invalid-places.rs:15:50
    |
 LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
    |                                                  ^^^^^^^^
@@ -23,7 +23,7 @@ LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-invalid-places.rs:17:48
+  --> $DIR/tilde-const-invalid-places.rs:18:48
    |
 LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
    |                                                ^^^^^^^^
@@ -31,7 +31,7 @@ LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
    = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
 
 error: `~const` and `?` are mutually exclusive
-  --> $DIR/tilde-const-invalid-places.rs:20:25
+  --> $DIR/tilde-const-invalid-places.rs:21:25
    |
 LL | struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>);
    |                         ^^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
index 47c38c979c3..bfe98b98c74 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs
@@ -4,8 +4,10 @@
 // test is not enough.
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Bar {}
 
+#[const_trait]
 trait Foo {
     fn a();
     fn b() where Self: ~const Bar;
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
index 13d8639de30..f2846b6a662 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
-  --> $DIR/trait-where-clause-const.rs:17:5
+  --> $DIR/trait-where-clause-const.rs:19:5
    |
 LL |     T::b();
    |     ^^^^^^ the trait `~const Bar` is not implemented for `T`
    |
 note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/trait-where-clause-const.rs:17:5
+  --> $DIR/trait-where-clause-const.rs:19:5
    |
 LL |     T::b();
    |     ^^^^^^
@@ -15,13 +15,13 @@ LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() {
    |                                    ++++++++++++
 
 error[E0277]: the trait bound `T: ~const Bar` is not satisfied
-  --> $DIR/trait-where-clause-const.rs:19:5
+  --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::c::<T>();
    |     ^^^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
    |
 note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
-  --> $DIR/trait-where-clause-const.rs:19:5
+  --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::c::<T>();
    |     ^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
index acea58eaecb..3b028ac48db 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Foo {
     fn bar() where Self: ~const Foo;
 }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
index 5bd23a8cb20..85ca5fc9048 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs
@@ -1,5 +1,6 @@
 #![feature(const_trait_impl)]
 
+#[const_trait]
 trait Bar {}
 
 trait Foo {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 96365d33433..11f0c40160d 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:13:5
+  --> $DIR/trait-where-clause.rs:14:5
    |
 LL |     T::b();
    |     ^^^^ the trait `Bar` is not implemented for `T`
    |
 note: required by a bound in `Foo::b`
-  --> $DIR/trait-where-clause.rs:7:24
+  --> $DIR/trait-where-clause.rs:8:24
    |
 LL |     fn b() where Self: ~const Bar;
    |                        ^^^^^^^^^^ required by this bound in `Foo::b`
@@ -15,13 +15,13 @@ LL | fn test1<T: Foo + Bar>() {
    |                 +++++
 
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:15:12
+  --> $DIR/trait-where-clause.rs:16:12
    |
 LL |     T::c::<T>();
    |            ^ the trait `Bar` is not implemented for `T`
    |
 note: required by a bound in `Foo::c`
-  --> $DIR/trait-where-clause.rs:8:13
+  --> $DIR/trait-where-clause.rs:9:13
    |
 LL |     fn c<T: ~const Bar>();
    |             ^^^^^^^^^^ required by this bound in `Foo::c`
diff --git a/src/test/ui/rust-2018/async-ident-allowed.stderr b/src/test/ui/rust-2018/async-ident-allowed.stderr
index 5b63eab8e46..992b2975009 100644
--- a/src/test/ui/rust-2018/async-ident-allowed.stderr
+++ b/src/test/ui/rust-2018/async-ident-allowed.stderr
@@ -4,14 +4,14 @@ error: `async` is a keyword in the 2018 edition
 LL |     let async = 3;
    |         ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/async-ident-allowed.rs:3:9
    |
 LL | #![deny(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[deny(keyword_idents)]` implied by `#[deny(rust_2018_compatibility)]`
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rust-2018/async-ident.stderr b/src/test/ui/rust-2018/async-ident.stderr
index 6396e9deee2..d15250c54ec 100644
--- a/src/test/ui/rust-2018/async-ident.stderr
+++ b/src/test/ui/rust-2018/async-ident.stderr
@@ -4,13 +4,13 @@ error: `async` is a keyword in the 2018 edition
 LL | fn async() {}
    |    ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/async-ident.rs:2:9
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
   --> $DIR/async-ident.rs:12:7
diff --git a/src/test/ui/rust-2018/dyn-keyword.stderr b/src/test/ui/rust-2018/dyn-keyword.stderr
index 699242f2dcb..b6f5b10cf03 100644
--- a/src/test/ui/rust-2018/dyn-keyword.stderr
+++ b/src/test/ui/rust-2018/dyn-keyword.stderr
@@ -4,13 +4,13 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     let dyn = ();
    |         ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/dyn-keyword.rs:5:9
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
index 6f529fa9114..e1709db0990 100644
--- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
@@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL |     let _: <foo::Baz as ::foo::Foo>::Bar = ();
    |                         ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 note: the lint level is defined here
   --> $DIR/edition-lint-fully-qualified-paths.rs:4:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
   --> $DIR/edition-lint-fully-qualified-paths.rs:23:13
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
index e47c320f78f..8769cbb35b0 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
@@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL | use foo::{bar::{baz::{}}};
    |     ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 note: the lint level is defined here
   --> $DIR/edition-lint-nested-empty-paths.rs:4:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
   --> $DIR/edition-lint-nested-empty-paths.rs:21:5
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
index 24b17f212eb..354a6fe3252 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
@@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL | use foo::{a, b};
    |     ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 note: the lint level is defined here
   --> $DIR/edition-lint-nested-paths.rs:4:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
   --> $DIR/edition-lint-nested-paths.rs:6:5
diff --git a/src/test/ui/rust-2018/edition-lint-paths.stderr b/src/test/ui/rust-2018/edition-lint-paths.stderr
index 1ded8cd3694..42652be9401 100644
--- a/src/test/ui/rust-2018/edition-lint-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-paths.stderr
@@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL |     use bar::Bar;
    |         ^^^^^^^^ help: use `crate`: `crate::bar::Bar`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 note: the lint level is defined here
   --> $DIR/edition-lint-paths.rs:5:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
   --> $DIR/edition-lint-paths.rs:19:9
diff --git a/src/test/ui/rust-2018/extern-crate-rename.stderr b/src/test/ui/rust-2018/extern-crate-rename.stderr
index 4bccbc51223..eb040f5de54 100644
--- a/src/test/ui/rust-2018/extern-crate-rename.stderr
+++ b/src/test/ui/rust-2018/extern-crate-rename.stderr
@@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL | use my_crate::foo;
    |     ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 note: the lint level is defined here
   --> $DIR/extern-crate-rename.rs:8:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rust-2018/extern-crate-submod.stderr b/src/test/ui/rust-2018/extern-crate-submod.stderr
index 3c75319aeda..1a9aa75787a 100644
--- a/src/test/ui/rust-2018/extern-crate-submod.stderr
+++ b/src/test/ui/rust-2018/extern-crate-submod.stderr
@@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL | use m::edition_lint_paths::foo;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 note: the lint level is defined here
   --> $DIR/extern-crate-submod.rs:9:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr
index 3d93b433cf2..74015ac9da4 100644
--- a/src/test/ui/rust-2018/try-ident.stderr
+++ b/src/test/ui/rust-2018/try-ident.stderr
@@ -4,14 +4,14 @@ warning: `try` is a keyword in the 2018 edition
 LL |     try();
    |     ^^^ help: you can use a raw identifier to stay compatible: `r#try`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/try-ident.rs:4:9
    |
 LL | #![warn(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]`
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: `try` is a keyword in the 2018 edition
   --> $DIR/try-ident.rs:12:4
diff --git a/src/test/ui/rust-2018/try-macro.stderr b/src/test/ui/rust-2018/try-macro.stderr
index f315b4d4a9e..760378f0955 100644
--- a/src/test/ui/rust-2018/try-macro.stderr
+++ b/src/test/ui/rust-2018/try-macro.stderr
@@ -4,14 +4,14 @@ warning: `try` is a keyword in the 2018 edition
 LL |     try!(x);
    |     ^^^ help: you can use a raw identifier to stay compatible: `r#try`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 note: the lint level is defined here
   --> $DIR/try-macro.rs:6:9
    |
 LL | #![warn(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]`
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
-   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
index fac8d21c7b4..2a724bd3072 100644
--- a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
@@ -4,13 +4,13 @@ warning: trait method `into_iter` will become ambiguous in Rust 2021
 LL |     let y = points.into_iter();
    |             ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
    |
+   = warning: this changes meaning in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
 note: the lint level is defined here
   --> $DIR/array-into-iter-ambiguous.rs:5:9
    |
 LL | #![warn(array_into_iter)]
    |         ^^^^^^^^^^^^^^^
-   = warning: this changes meaning in Rust 2021
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
index 14ad9b017b6..f38da132b5e 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
@@ -4,13 +4,13 @@ warning: trait-associated function `try_from` will become ambiguous in Rust 2021
 LL |         U::try_from(self)
    |         ^^^^^^^^^^^ help: disambiguate the associated function: `<U as PyTryFrom<'_, _>>::try_from`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/future-prelude-collision-generic-trait.rs:5:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
index e1d3f3c0a46..9893b3ebaa6 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
@@ -4,13 +4,13 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202
 LL |     Generic::from_iter(1);
    |     ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<'_, _> as MyFromIter>::from_iter`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/future-prelude-collision-generic.rs:5:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision-generic.rs:31:5
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
index 56abb8abd4d..c1d72d0df21 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
@@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |         let _: u32 = 3u8.try_into().unwrap();
    |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/future-prelude-collision-imported.rs:4:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision-imported.rs:40:22
diff --git a/src/test/ui/rust-2021/future-prelude-collision-macros.stderr b/src/test/ui/rust-2021/future-prelude-collision-macros.stderr
index 4c3543ca782..4d4a0769958 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-macros.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-macros.stderr
@@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |     foo!().try_into(todo!());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyTry::try_into(foo!(), todo!())`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/future-prelude-collision-macros.rs:4:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: trait-associated function `try_from` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision-macros.rs:42:5
diff --git a/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr b/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr
index 2de9020bce7..c0ef80fd841 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr
@@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |     x.try_into::<usize>().or(Err("foo"))?.checked_sub(1);
    |     ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `AnnotatableTryInto::try_into::<usize>(x)`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/future-prelude-collision-turbofish.rs:6:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision-turbofish.rs:23:5
diff --git a/src/test/ui/rust-2021/future-prelude-collision.stderr b/src/test/ui/rust-2021/future-prelude-collision.stderr
index 889e66de03f..cae113ff711 100644
--- a/src/test/ui/rust-2021/future-prelude-collision.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision.stderr
@@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |     let _: u32 = 3u8.try_into().unwrap();
    |                  ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/future-prelude-collision.rs:4:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: trait-associated function `try_from` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision.rs:61:13
diff --git a/src/test/ui/rust-2021/generic-type-collision.stderr b/src/test/ui/rust-2021/generic-type-collision.stderr
index e6ea28d718d..1ec61044f4a 100644
--- a/src/test/ui/rust-2021/generic-type-collision.stderr
+++ b/src/test/ui/rust-2021/generic-type-collision.stderr
@@ -4,13 +4,13 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202
 LL |     <Vec<i32>>::from_iter(None);
    |     ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<i32> as MyTrait<_>>::from_iter`
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/generic-type-collision.rs:4:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.stderr b/src/test/ui/rust-2021/inherent-dyn-collision.stderr
index 77b4c385132..f5905574ac3 100644
--- a/src/test/ui/rust-2021/inherent-dyn-collision.stderr
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.stderr
@@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |         get_dyn_trait().try_into().unwrap()
    |         ^^^^^^^^^^^^^^^ help: disambiguate the method call: `(&*get_dyn_trait())`
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 note: the lint level is defined here
   --> $DIR/inherent-dyn-collision.rs:8:9
    |
 LL | #![warn(rust_2021_prelude_collisions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
index c6bc082cf18..20914d1b9d1 100644
--- a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
@@ -4,13 +4,13 @@ warning: prefix `z` is unknown
 LL |     m2!(z"hey");
    |         ^ unknown prefix
    |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
 note: the lint level is defined here
   --> $DIR/reserved-prefixes-migration.rs:5:9
    |
 LL | #![warn(rust_2021_prefixes_incompatible_syntax)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
 help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
    |
 LL |     m2!(z "hey");
diff --git a/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr b/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr
index a14ab8fe4bc..e9a4c1dd52f 100644
--- a/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr
+++ b/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr
@@ -4,13 +4,13 @@ error: unknown `doc` attribute `x`
 LL | #![doc(x)]
    |        ^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/deny-invalid-doc-attrs.rs:1:9
    |
 LL | #![deny(invalid_doc_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rustdoc/doc-test-attr.stderr b/src/test/ui/rustdoc/doc-test-attr.stderr
index 7f5e2d6bc70..5e6014954a4 100644
--- a/src/test/ui/rustdoc/doc-test-attr.stderr
+++ b/src/test/ui/rustdoc/doc-test-attr.stderr
@@ -4,13 +4,13 @@ error: `#[doc(test(...)]` takes a list of attributes
 LL | #![doc(test)]
    |        ^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 note: the lint level is defined here
   --> $DIR/doc-test-attr.rs:2:9
    |
 LL | #![deny(invalid_doc_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
 
 error: `#[doc(test(...)]` takes a list of attributes
   --> $DIR/doc-test-attr.rs:7:8
diff --git a/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr b/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr
index 736bf29c580..194b2d87db2 100644
--- a/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr
+++ b/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr
@@ -4,9 +4,9 @@ warning: `doc(primitive)` should never have been stable
 LL | #[doc(primitive = "usize")]
    |       ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(invalid_doc_attributes)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: `#[warn(invalid_doc_attributes)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/sanitize/inline-always.stderr b/src/test/ui/sanitize/inline-always.stderr
index 918762d1f66..74fba3c0e0e 100644
--- a/src/test/ui/sanitize/inline-always.stderr
+++ b/src/test/ui/sanitize/inline-always.stderr
@@ -4,12 +4,12 @@ warning: `no_sanitize` will have no effect after inlining
 LL | #[no_sanitize(address)]
    | ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(inline_no_sanitize)]` on by default
 note: inlining requested here
   --> $DIR/inline-always.rs:5:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
+   = note: `#[warn(inline_no_sanitize)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/simd/target-feature-mixup.rs b/src/test/ui/simd/target-feature-mixup.rs
index 6d7688191b7..5dd163715eb 100644
--- a/src/test/ui/simd/target-feature-mixup.rs
+++ b/src/test/ui/simd/target-feature-mixup.rs
@@ -5,6 +5,7 @@
 
 // ignore-emscripten
 // ignore-sgx no processes
+// ignore-fuchsia must translate zircon signal to SIGILL, FIXME (#58590)
 
 #![feature(repr_simd, target_feature, cfg_target_feature)]
 #![feature(avx512_target_feature)]
diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
index 2c1fa7b36b6..ee72a0c65c8 100644
--- a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
+++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr
@@ -67,8 +67,8 @@ LL | |     crate(move || {} ).await
 LL | |     }
    | |_____^
    |
-   = note: requested on the command line with `-W rust-2021-incompatible-closure-captures`
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+   = note: requested on the command line with `-W rust-2021-incompatible-closure-captures`
 help: add a dummy let to cause `path` to be fully captured
    |
 LL |     async fn create(path: impl AsRef<std::path::Path>)  { let _ = &path;
diff --git a/src/test/ui/specialization/assoc-ty-graph-cycle.stderr b/src/test/ui/specialization/assoc-ty-graph-cycle.stderr
index 17da34caa70..f5529c24d3e 100644
--- a/src/test/ui/specialization/assoc-ty-graph-cycle.stderr
+++ b/src/test/ui/specialization/assoc-ty-graph-cycle.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/cross-crate-defaults.stderr b/src/test/ui/specialization/cross-crate-defaults.stderr
index e368c2e73b6..ee5c77a76be 100644
--- a/src/test/ui/specialization/cross-crate-defaults.stderr
+++ b/src/test/ui/specialization/cross-crate-defaults.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/default-associated-type-bound-1.stderr b/src/test/ui/specialization/default-associated-type-bound-1.stderr
index af9f2f7c2e9..e498187c0a1 100644
--- a/src/test/ui/specialization/default-associated-type-bound-1.stderr
+++ b/src/test/ui/specialization/default-associated-type-bound-1.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the trait bound `str: Clone` is not satisfied
   --> $DIR/default-associated-type-bound-1.rs:18:22
diff --git a/src/test/ui/specialization/default-associated-type-bound-2.stderr b/src/test/ui/specialization/default-associated-type-bound-2.stderr
index 91778ed0f4c..4dbe251ed5e 100644
--- a/src/test/ui/specialization/default-associated-type-bound-2.stderr
+++ b/src/test/ui/specialization/default-associated-type-bound-2.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: can't compare `&'static B` with `B`
   --> $DIR/default-associated-type-bound-2.rs:16:22
diff --git a/src/test/ui/specialization/default-generic-associated-type-bound.stderr b/src/test/ui/specialization/default-generic-associated-type-bound.stderr
index 44c24c1e578..c597eed3790 100644
--- a/src/test/ui/specialization/default-generic-associated-type-bound.stderr
+++ b/src/test/ui/specialization/default-generic-associated-type-bound.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: can't compare `T` with `T`
   --> $DIR/default-generic-associated-type-bound.rs:17:26
diff --git a/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr
index d8b9c48c72e..02f13d461c3 100644
--- a/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr
+++ b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/defaultimpl/out-of-order.stderr b/src/test/ui/specialization/defaultimpl/out-of-order.stderr
index 9ca915686e8..2cf1ac90959 100644
--- a/src/test/ui/specialization/defaultimpl/out-of-order.stderr
+++ b/src/test/ui/specialization/defaultimpl/out-of-order.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/defaultimpl/overlap-projection.stderr b/src/test/ui/specialization/defaultimpl/overlap-projection.stderr
index 31d0e6e3882..75fdfafd9d1 100644
--- a/src/test/ui/specialization/defaultimpl/overlap-projection.stderr
+++ b/src/test/ui/specialization/defaultimpl/overlap-projection.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/defaultimpl/projection.stderr b/src/test/ui/specialization/defaultimpl/projection.stderr
index 2d5c80d05f0..cc3fe8237a7 100644
--- a/src/test/ui/specialization/defaultimpl/projection.stderr
+++ b/src/test/ui/specialization/defaultimpl/projection.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
index 360b7bc787a..770be2af281 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
   --> $DIR/specialization-no-default.rs:20:5
diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr
index 163c93550fb..407c1ab7720 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr
index 250f0017bea..f19975060a4 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0046]: not all trait items implemented, missing: `foo_two`
   --> $DIR/specialization-trait-item-not-implemented.rs:18:1
diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
index d1004a69058..33ca7a2c210 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait bounds were not satisfied
   --> $DIR/specialization-trait-not-implemented.rs:22:29
diff --git a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr
index a8fdbc52884..e7801603493 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the trait bound `U: Eq` is not satisfied
   --> $DIR/specialization-wfcheck.rs:7:17
diff --git a/src/test/ui/specialization/defaultimpl/validation.stderr b/src/test/ui/specialization/defaultimpl/validation.stderr
index cbf0cef5e74..eb6dc9355a3 100644
--- a/src/test/ui/specialization/defaultimpl/validation.stderr
+++ b/src/test/ui/specialization/defaultimpl/validation.stderr
@@ -14,9 +14,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: impls of auto traits cannot be default
   --> $DIR/validation.rs:9:21
diff --git a/src/test/ui/specialization/issue-35376.stderr b/src/test/ui/specialization/issue-35376.stderr
index 835277d408e..6c4167f3f9f 100644
--- a/src/test/ui/specialization/issue-35376.stderr
+++ b/src/test/ui/specialization/issue-35376.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/issue-36804.stderr b/src/test/ui/specialization/issue-36804.stderr
index 783a38e6bdc..c2113b25f19 100644
--- a/src/test/ui/specialization/issue-36804.stderr
+++ b/src/test/ui/specialization/issue-36804.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/issue-38091-2.stderr b/src/test/ui/specialization/issue-38091-2.stderr
index 31ae4b26e45..117fb10bb7e 100644
--- a/src/test/ui/specialization/issue-38091-2.stderr
+++ b/src/test/ui/specialization/issue-38091-2.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0275]: overflow evaluating the requirement `i32: Check`
    |
diff --git a/src/test/ui/specialization/issue-38091.stderr b/src/test/ui/specialization/issue-38091.stderr
index cc5536c9e9a..f2210a40719 100644
--- a/src/test/ui/specialization/issue-38091.stderr
+++ b/src/test/ui/specialization/issue-38091.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the trait bound `(): Valid` is not satisfied
   --> $DIR/issue-38091.rs:12:23
diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr
index 9b74f684b8f..60157d9a3e1 100644
--- a/src/test/ui/specialization/issue-39448.stderr
+++ b/src/test/ui/specialization/issue-39448.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0275]: overflow evaluating the requirement `T: FromA<U>`
   --> $DIR/issue-39448.rs:45:13
diff --git a/src/test/ui/specialization/issue-39618.stderr b/src/test/ui/specialization/issue-39618.stderr
index 77a45806edb..19de60c7c17 100644
--- a/src/test/ui/specialization/issue-39618.stderr
+++ b/src/test/ui/specialization/issue-39618.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/issue-50452-fail.stderr b/src/test/ui/specialization/issue-50452-fail.stderr
index 7249ad73871..5c136adc451 100644
--- a/src/test/ui/specialization/issue-50452-fail.stderr
+++ b/src/test/ui/specialization/issue-50452-fail.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
   --> $DIR/issue-50452-fail.rs:10:5
diff --git a/src/test/ui/specialization/issue-50452.stderr b/src/test/ui/specialization/issue-50452.stderr
index 2f05c41346f..48cab9dcdb7 100644
--- a/src/test/ui/specialization/issue-50452.stderr
+++ b/src/test/ui/specialization/issue-50452.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/issue-52050.stderr b/src/test/ui/specialization/issue-52050.stderr
index 6d24997a5bf..c263fe46724 100644
--- a/src/test/ui/specialization/issue-52050.stderr
+++ b/src/test/ui/specialization/issue-52050.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0119]: conflicting implementations of trait `IntoPyDictPointer` for type `()`
   --> $DIR/issue-52050.rs:28:1
diff --git a/src/test/ui/specialization/issue-63716-parse-async.stderr b/src/test/ui/specialization/issue-63716-parse-async.stderr
index cde17872d6b..a00572da8f5 100644
--- a/src/test/ui/specialization/issue-63716-parse-async.stderr
+++ b/src/test/ui/specialization/issue-63716-parse-async.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/issue-70442.stderr b/src/test/ui/specialization/issue-70442.stderr
index 5ee82e9915b..aa72c32866a 100644
--- a/src/test/ui/specialization/issue-70442.stderr
+++ b/src/test/ui/specialization/issue-70442.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/non-defaulted-item-fail.stderr b/src/test/ui/specialization/non-defaulted-item-fail.stderr
index 8b7d6797275..faa14555a4f 100644
--- a/src/test/ui/specialization/non-defaulted-item-fail.stderr
+++ b/src/test/ui/specialization/non-defaulted-item-fail.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization, associated_type_defaults)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default`
   --> $DIR/non-defaulted-item-fail.rs:30:5
diff --git a/src/test/ui/specialization/specialization-allowed-cross-crate.stderr b/src/test/ui/specialization/specialization-allowed-cross-crate.stderr
index 9605bd08935..3eea4a53bf5 100644
--- a/src/test/ui/specialization/specialization-allowed-cross-crate.stderr
+++ b/src/test/ui/specialization/specialization-allowed-cross-crate.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-assoc-fns.stderr b/src/test/ui/specialization/specialization-assoc-fns.stderr
index a7c0661a825..69f7cece79d 100644
--- a/src/test/ui/specialization/specialization-assoc-fns.stderr
+++ b/src/test/ui/specialization/specialization-assoc-fns.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-basics.stderr b/src/test/ui/specialization/specialization-basics.stderr
index afb2af3803f..7714d4af4c6 100644
--- a/src/test/ui/specialization/specialization-basics.stderr
+++ b/src/test/ui/specialization/specialization-basics.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-cross-crate.stderr b/src/test/ui/specialization/specialization-cross-crate.stderr
index c69130c0aef..06818bb5627 100644
--- a/src/test/ui/specialization/specialization-cross-crate.stderr
+++ b/src/test/ui/specialization/specialization-cross-crate.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-default-methods.stderr b/src/test/ui/specialization/specialization-default-methods.stderr
index ef6365ed31f..d78d30bd802 100644
--- a/src/test/ui/specialization/specialization-default-methods.stderr
+++ b/src/test/ui/specialization/specialization-default-methods.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr
index 7a2b75a1c1f..b8b81876d81 100644
--- a/src/test/ui/specialization/specialization-default-projection.stderr
+++ b/src/test/ui/specialization/specialization-default-projection.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0308]: mismatched types
   --> $DIR/specialization-default-projection.rs:21:5
diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr
index 5ba38facee0..61a556a9311 100644
--- a/src/test/ui/specialization/specialization-default-types.stderr
+++ b/src/test/ui/specialization/specialization-default-types.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0308]: mismatched types
   --> $DIR/specialization-default-types.rs:15:9
diff --git a/src/test/ui/specialization/specialization-no-default.stderr b/src/test/ui/specialization/specialization-no-default.stderr
index 28c869a7055..842cec9c79f 100644
--- a/src/test/ui/specialization/specialization-no-default.stderr
+++ b/src/test/ui/specialization/specialization-no-default.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
   --> $DIR/specialization-no-default.rs:20:5
diff --git a/src/test/ui/specialization/specialization-on-projection.stderr b/src/test/ui/specialization/specialization-on-projection.stderr
index d051ffe0a02..00fc7ffc547 100644
--- a/src/test/ui/specialization/specialization-on-projection.stderr
+++ b/src/test/ui/specialization/specialization-on-projection.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-out-of-order.stderr b/src/test/ui/specialization/specialization-out-of-order.stderr
index 785ec29239b..b524e00f01c 100644
--- a/src/test/ui/specialization/specialization-out-of-order.stderr
+++ b/src/test/ui/specialization/specialization-out-of-order.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-overlap-negative.stderr b/src/test/ui/specialization/specialization-overlap-negative.stderr
index 552b04a6019..fb3d9723aff 100644
--- a/src/test/ui/specialization/specialization-overlap-negative.stderr
+++ b/src/test/ui/specialization/specialization-overlap-negative.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
   --> $DIR/specialization-overlap-negative.rs:9:1
diff --git a/src/test/ui/specialization/specialization-overlap-projection.stderr b/src/test/ui/specialization/specialization-overlap-projection.stderr
index c92db73074d..708c0817fd9 100644
--- a/src/test/ui/specialization/specialization-overlap-projection.stderr
+++ b/src/test/ui/specialization/specialization-overlap-projection.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-overlap.stderr b/src/test/ui/specialization/specialization-overlap.stderr
index 3ccbe1616e8..98926446765 100644
--- a/src/test/ui/specialization/specialization-overlap.stderr
+++ b/src/test/ui/specialization/specialization-overlap.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0119]: conflicting implementations of trait `Foo` for type `std::vec::Vec<_>`
   --> $DIR/specialization-overlap.rs:5:1
diff --git a/src/test/ui/specialization/specialization-polarity.stderr b/src/test/ui/specialization/specialization-polarity.stderr
index be013552f5d..f287018ba7f 100644
--- a/src/test/ui/specialization/specialization-polarity.stderr
+++ b/src/test/ui/specialization/specialization-polarity.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`:
   --> $DIR/specialization-polarity.rs:10:1
diff --git a/src/test/ui/specialization/specialization-projection-alias.stderr b/src/test/ui/specialization/specialization-projection-alias.stderr
index 6d2bca5d2df..c94d9ed07b1 100644
--- a/src/test/ui/specialization/specialization-projection-alias.stderr
+++ b/src/test/ui/specialization/specialization-projection-alias.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-projection.stderr b/src/test/ui/specialization/specialization-projection.stderr
index 0f1ecf5e379..bfc4e0a0f5d 100644
--- a/src/test/ui/specialization/specialization-projection.stderr
+++ b/src/test/ui/specialization/specialization-projection.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-supertraits.stderr b/src/test/ui/specialization/specialization-supertraits.stderr
index d32e47a24c2..e716bc21596 100644
--- a/src/test/ui/specialization/specialization-supertraits.stderr
+++ b/src/test/ui/specialization/specialization-supertraits.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr
index d30f7af2cbd..c7aad3c0fee 100644
--- a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr
+++ b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-translate-projections-with-params.stderr b/src/test/ui/specialization/specialization-translate-projections-with-params.stderr
index 1762248f695..1c4fd9325a6 100644
--- a/src/test/ui/specialization/specialization-translate-projections-with-params.stderr
+++ b/src/test/ui/specialization/specialization-translate-projections-with-params.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/specialization-translate-projections.stderr b/src/test/ui/specialization/specialization-translate-projections.stderr
index 94a0e79dd56..22bbb12a09b 100644
--- a/src/test/ui/specialization/specialization-translate-projections.stderr
+++ b/src/test/ui/specialization/specialization-translate-projections.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/specialization/transmute-specialization.stderr b/src/test/ui/specialization/transmute-specialization.stderr
index a0ea72415a1..b1c26d7dacc 100644
--- a/src/test/ui/specialization/transmute-specialization.stderr
+++ b/src/test/ui/specialization/transmute-specialization.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr
index 310f02024ca..7645f3c7ef5 100644
--- a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr
@@ -4,8 +4,8 @@ error: an `#[unstable]` annotation here has no effect
 LL | #[unstable(feature = "h", issue = "none")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(ineffective_unstable_trait_impl)]` on by default
    = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
+   = note: `#[deny(ineffective_unstable_trait_impl)]` on by default
 
 error: module has missing stability attribute
   --> $DIR/stability-attribute-trait-impl.rs:1:1
diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr
index 6d37de8ff3f..ef794bb36ac 100644
--- a/src/test/ui/statics/uninhabited-static.stderr
+++ b/src/test/ui/statics/uninhabited-static.stderr
@@ -4,14 +4,14 @@ error: static of uninhabited type
 LL |     static VOID: Void;
    |     ^^^^^^^^^^^^^^^^^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
+   = note: uninhabited statics cannot be initialized, and any access would be an immediate error
 note: the lint level is defined here
   --> $DIR/uninhabited-static.rs:2:9
    |
 LL | #![deny(uninhabited_static)]
    |         ^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
-   = note: uninhabited statics cannot be initialized, and any access would be an immediate error
 
 error: static of uninhabited type
   --> $DIR/uninhabited-static.rs:8:5
@@ -58,12 +58,12 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
    |                               this code causes undefined behavior when executed
    |                               help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
-   = note: `#[warn(invalid_value)]` on by default
 note: enums with no inhabited variants have no valid value
   --> $DIR/uninhabited-static.rs:4:1
    |
 LL | enum Void {}
    | ^^^^^^^^^
+   = note: `#[warn(invalid_value)]` on by default
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/uninhabited-static.rs:16:32
diff --git a/src/test/ui/stats/hir-stats.rs b/src/test/ui/stats/hir-stats.rs
index 5102574d4be..a24b3ada57e 100644
--- a/src/test/ui/stats/hir-stats.rs
+++ b/src/test/ui/stats/hir-stats.rs
@@ -1,7 +1,6 @@
 // check-pass
 // compile-flags: -Zhir-stats
 // only-x86_64
-// ignore-stage1
 
 // The aim here is to include at least one of every different type of top-level
 // AST/HIR node reported by `-Zhir-stats`.
diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr
index 8d977606530..350b140aada 100644
--- a/src/test/ui/stats/hir-stats.stderr
+++ b/src/test/ui/stats/hir-stats.stderr
@@ -118,61 +118,61 @@ ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
 hir-stats ----------------------------------------------------------------
-hir-stats ForeignItemRef            24 ( 0.2%)             1            24
-hir-stats Lifetime                  32 ( 0.3%)             1            32
-hir-stats Mod                       32 ( 0.3%)             1            32
+hir-stats ForeignItemRef            24 ( 0.3%)             1            24
+hir-stats Lifetime                  32 ( 0.4%)             1            32
+hir-stats Mod                       32 ( 0.4%)             1            32
 hir-stats ExprField                 40 ( 0.4%)             1            40
 hir-stats TraitItemRef              56 ( 0.6%)             2            28
 hir-stats Local                     64 ( 0.7%)             1            64
 hir-stats Param                     64 ( 0.7%)             2            32
-hir-stats InlineAsm                 72 ( 0.7%)             1            72
-hir-stats ImplItemRef               72 ( 0.7%)             2            36
-hir-stats Body                      96 ( 1.0%)             3            32
-hir-stats GenericArg                96 ( 1.0%)             4            24
-hir-stats - Type                      24 ( 0.2%)             1
-hir-stats - Lifetime                  72 ( 0.7%)             3
-hir-stats FieldDef                  96 ( 1.0%)             2            48
-hir-stats Arm                       96 ( 1.0%)             2            48
-hir-stats Stmt                      96 ( 1.0%)             3            32
-hir-stats - Local                     32 ( 0.3%)             1
-hir-stats - Semi                      32 ( 0.3%)             1
-hir-stats - Expr                      32 ( 0.3%)             1
-hir-stats FnDecl                   120 ( 1.2%)             3            40
-hir-stats Attribute                128 ( 1.3%)             4            32
-hir-stats GenericArgs              144 ( 1.5%)             3            48
-hir-stats Variant                  160 ( 1.7%)             2            80
-hir-stats WherePredicate           168 ( 1.7%)             3            56
-hir-stats - BoundPredicate           168 ( 1.7%)             3
-hir-stats GenericBound             192 ( 2.0%)             4            48
-hir-stats - Trait                    192 ( 2.0%)             4
-hir-stats Block                    288 ( 3.0%)             6            48
-hir-stats Pat                      360 ( 3.7%)             5            72
-hir-stats - Wild                      72 ( 0.7%)             1
-hir-stats - Struct                    72 ( 0.7%)             1
-hir-stats - Binding                  216 ( 2.2%)             3
-hir-stats GenericParam             400 ( 4.1%)             5            80
-hir-stats Generics                 560 ( 5.8%)            10            56
-hir-stats Ty                       720 ( 7.4%)            15            48
+hir-stats InlineAsm                 72 ( 0.8%)             1            72
+hir-stats ImplItemRef               72 ( 0.8%)             2            36
+hir-stats Body                      96 ( 1.1%)             3            32
+hir-stats GenericArg                96 ( 1.1%)             4            24
+hir-stats - Type                      24 ( 0.3%)             1
+hir-stats - Lifetime                  72 ( 0.8%)             3
+hir-stats FieldDef                  96 ( 1.1%)             2            48
+hir-stats Arm                       96 ( 1.1%)             2            48
+hir-stats Stmt                      96 ( 1.1%)             3            32
+hir-stats - Local                     32 ( 0.4%)             1
+hir-stats - Semi                      32 ( 0.4%)             1
+hir-stats - Expr                      32 ( 0.4%)             1
+hir-stats FnDecl                   120 ( 1.3%)             3            40
+hir-stats Attribute                128 ( 1.4%)             4            32
+hir-stats GenericArgs              144 ( 1.6%)             3            48
+hir-stats Variant                  160 ( 1.8%)             2            80
+hir-stats GenericBound             192 ( 2.1%)             4            48
+hir-stats - Trait                    192 ( 2.1%)             4
+hir-stats WherePredicate           192 ( 2.1%)             3            64
+hir-stats - BoundPredicate           192 ( 2.1%)             3
+hir-stats Block                    288 ( 3.2%)             6            48
+hir-stats Pat                      360 ( 3.9%)             5            72
+hir-stats - Wild                      72 ( 0.8%)             1
+hir-stats - Struct                    72 ( 0.8%)             1
+hir-stats - Binding                  216 ( 2.4%)             3
+hir-stats GenericParam             400 ( 4.4%)             5            80
+hir-stats Generics                 560 ( 6.1%)            10            56
+hir-stats Ty                       720 ( 7.9%)            15            48
 hir-stats - Ptr                       48 ( 0.5%)             1
 hir-stats - Rptr                      48 ( 0.5%)             1
-hir-stats - Path                     624 ( 6.4%)            13
-hir-stats Expr                     768 ( 7.9%)            12            64
+hir-stats - Path                     624 ( 6.8%)            13
+hir-stats Expr                     768 ( 8.4%)            12            64
 hir-stats - Path                      64 ( 0.7%)             1
 hir-stats - Struct                    64 ( 0.7%)             1
 hir-stats - Match                     64 ( 0.7%)             1
 hir-stats - InlineAsm                 64 ( 0.7%)             1
-hir-stats - Lit                      128 ( 1.3%)             2
-hir-stats - Block                    384 ( 4.0%)             6
-hir-stats Item                     960 ( 9.9%)            12            80
-hir-stats - Trait                     80 ( 0.8%)             1
-hir-stats - Enum                      80 ( 0.8%)             1
-hir-stats - ExternCrate               80 ( 0.8%)             1
-hir-stats - ForeignMod                80 ( 0.8%)             1
-hir-stats - Impl                      80 ( 0.8%)             1
-hir-stats - Fn                       160 ( 1.7%)             2
-hir-stats - Use                      400 ( 4.1%)             5
-hir-stats Path                   1_536 (15.9%)            32            48
-hir-stats PathSegment            2_240 (23.1%)            40            56
+hir-stats - Lit                      128 ( 1.4%)             2
+hir-stats - Block                    384 ( 4.2%)             6
+hir-stats Item                     960 (10.5%)            12            80
+hir-stats - Trait                     80 ( 0.9%)             1
+hir-stats - Enum                      80 ( 0.9%)             1
+hir-stats - ExternCrate               80 ( 0.9%)             1
+hir-stats - ForeignMod                80 ( 0.9%)             1
+hir-stats - Impl                      80 ( 0.9%)             1
+hir-stats - Fn                       160 ( 1.8%)             2
+hir-stats - Use                      400 ( 4.4%)             5
+hir-stats Path                   1_280 (14.0%)            32            40
+hir-stats PathSegment            1_920 (21.0%)            40            48
 hir-stats ----------------------------------------------------------------
-hir-stats Total                  9_680
+hir-stats Total                  9_128
 hir-stats
diff --git a/src/test/ui/structs-enums/rec-align-u32.rs b/src/test/ui/structs-enums/rec-align-u32.rs
index 889294daa34..ee704198d19 100644
--- a/src/test/ui/structs-enums/rec-align-u32.rs
+++ b/src/test/ui/structs-enums/rec-align-u32.rs
@@ -10,6 +10,7 @@ use std::mem;
 mod rusti {
     extern "rust-intrinsic" {
         pub fn pref_align_of<T>() -> usize;
+        #[rustc_safe_intrinsic]
         pub fn min_align_of<T>() -> usize;
     }
 }
diff --git a/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs
index 3bc2d16cf9d..40ede9705f1 100644
--- a/src/test/ui/structs-enums/rec-align-u64.rs
+++ b/src/test/ui/structs-enums/rec-align-u64.rs
@@ -12,6 +12,7 @@ use std::mem;
 mod rusti {
     extern "rust-intrinsic" {
         pub fn pref_align_of<T>() -> usize;
+        #[rustc_safe_intrinsic]
         pub fn min_align_of<T>() -> usize;
     }
 }
diff --git a/src/test/ui/structs/incomplete-fn-in-struct-definition.rs b/src/test/ui/structs/incomplete-fn-in-struct-definition.rs
new file mode 100644
index 00000000000..cd8a79ba687
--- /dev/null
+++ b/src/test/ui/structs/incomplete-fn-in-struct-definition.rs
@@ -0,0 +1,5 @@
+fn main() {}
+
+struct S {
+    fn: u8 //~ ERROR expected identifier, found keyword `fn`
+}
diff --git a/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr b/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr
new file mode 100644
index 00000000000..0d12ba9c916
--- /dev/null
+++ b/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr
@@ -0,0 +1,15 @@
+error: expected identifier, found keyword `fn`
+  --> $DIR/incomplete-fn-in-struct-definition.rs:4:5
+   |
+LL | struct S {
+   |        - while parsing this struct
+LL |     fn: u8
+   |     ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL |     r#fn: u8
+   |     ++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/boxed-variant-field.rs b/src/test/ui/suggestions/boxed-variant-field.rs
index e79be2f6127..6050963c4ee 100644
--- a/src/test/ui/suggestions/boxed-variant-field.rs
+++ b/src/test/ui/suggestions/boxed-variant-field.rs
@@ -9,7 +9,6 @@ fn foo(x: Ty) -> Ty {
         Ty::List(elem) => foo(elem),
         //~^ ERROR mismatched types
         //~| HELP consider unboxing the value
-        //~| HELP try wrapping
     }
 }
 
diff --git a/src/test/ui/suggestions/boxed-variant-field.stderr b/src/test/ui/suggestions/boxed-variant-field.stderr
index 6dfb73480a2..9ae36a06a71 100644
--- a/src/test/ui/suggestions/boxed-variant-field.stderr
+++ b/src/test/ui/suggestions/boxed-variant-field.stderr
@@ -17,10 +17,6 @@ help: consider unboxing the value
    |
 LL |         Ty::List(elem) => foo(*elem),
    |                               +
-help: try wrapping the expression in `Ty::List`
-   |
-LL |         Ty::List(elem) => foo(Ty::List(elem)),
-   |                               +++++++++    +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/into-convert.rs b/src/test/ui/suggestions/into-convert.rs
new file mode 100644
index 00000000000..1c9a9e0aaf5
--- /dev/null
+++ b/src/test/ui/suggestions/into-convert.rs
@@ -0,0 +1,26 @@
+use std::path::{Path, PathBuf};
+use std::sync::atomic::AtomicU32;
+use std::sync::Arc;
+
+fn main() {
+    let x: A = B;
+    //~^ ERROR mismatched types
+    //~| HELP call `Into::into` on this expression to convert `B` into `A`
+
+    let y: Arc<Path> = PathBuf::new();
+    //~^ ERROR mismatched types
+    //~| HELP call `Into::into` on this expression to convert `PathBuf` into `Arc<Path>`
+
+    let z: AtomicU32 = 1;
+    //~^ ERROR mismatched types
+    //~| HELP call `Into::into` on this expression to convert `{integer}` into `AtomicU32`
+}
+
+struct A;
+struct B;
+
+impl From<B> for A {
+    fn from(_: B) -> Self {
+        A
+    }
+}
diff --git a/src/test/ui/suggestions/into-convert.stderr b/src/test/ui/suggestions/into-convert.stderr
new file mode 100644
index 00000000000..d43104a2172
--- /dev/null
+++ b/src/test/ui/suggestions/into-convert.stderr
@@ -0,0 +1,44 @@
+error[E0308]: mismatched types
+  --> $DIR/into-convert.rs:6:16
+   |
+LL |     let x: A = B;
+   |            -   ^ expected struct `A`, found struct `B`
+   |            |
+   |            expected due to this
+   |
+help: call `Into::into` on this expression to convert `B` into `A`
+   |
+LL |     let x: A = B.into();
+   |                 +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/into-convert.rs:10:24
+   |
+LL |     let y: Arc<Path> = PathBuf::new();
+   |            ---------   ^^^^^^^^^^^^^^ expected struct `Arc`, found struct `PathBuf`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `Arc<Path>`
+              found struct `PathBuf`
+help: call `Into::into` on this expression to convert `PathBuf` into `Arc<Path>`
+   |
+LL |     let y: Arc<Path> = PathBuf::new().into();
+   |                                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/into-convert.rs:14:24
+   |
+LL |     let z: AtomicU32 = 1;
+   |            ---------   ^ expected struct `AtomicU32`, found integer
+   |            |
+   |            expected due to this
+   |
+help: call `Into::into` on this expression to convert `{integer}` into `AtomicU32`
+   |
+LL |     let z: AtomicU32 = 1.into();
+   |                         +++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr
index a788cab6e4e..b99b1b0b9b3 100644
--- a/src/test/ui/suggestions/issue-61963.stderr
+++ b/src/test/ui/suggestions/issue-61963.stderr
@@ -4,13 +4,13 @@ error: trait objects without an explicit `dyn` are deprecated
 LL |     bar: Box<Bar>,
    |              ^^^
    |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 note: the lint level is defined here
   --> $DIR/issue-61963.rs:3:9
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 help: use `dyn`
    |
 LL |     bar: Box<dyn Bar>,
diff --git a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr
index be6fc261562..00aa7d18a96 100644
--- a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr
+++ b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr
@@ -7,7 +7,7 @@ LL | fn not_all_paths(a: &str) -> u32 {
    |    implicitly returns `()` as its body has no tail or `return` expression
 ...
 LL |     };
-   |      - help: remove this semicolon
+   |      - help: remove this semicolon to return this value
 
 error[E0308]: `match` arms have incompatible types
   --> $DIR/match-with-different-arm-types-as-stmt-instead-of-expr.rs:26:14
diff --git a/src/test/ui/suggestions/sugg-else-for-closure.fixed b/src/test/ui/suggestions/sugg-else-for-closure.fixed
new file mode 100644
index 00000000000..cf381d9da8b
--- /dev/null
+++ b/src/test/ui/suggestions/sugg-else-for-closure.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+    let x = "com.example.app";
+    let y: Option<&str> = None;
+    let _s = y.unwrap_or_else(|| x.split('.').nth(1).unwrap());
+    //~^ ERROR: mismatched types [E0308]
+}
diff --git a/src/test/ui/suggestions/sugg-else-for-closure.rs b/src/test/ui/suggestions/sugg-else-for-closure.rs
new file mode 100644
index 00000000000..540ced91fc9
--- /dev/null
+++ b/src/test/ui/suggestions/sugg-else-for-closure.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+    let x = "com.example.app";
+    let y: Option<&str> = None;
+    let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap());
+    //~^ ERROR: mismatched types [E0308]
+}
diff --git a/src/test/ui/suggestions/sugg-else-for-closure.stderr b/src/test/ui/suggestions/sugg-else-for-closure.stderr
new file mode 100644
index 00000000000..55a0eee1817
--- /dev/null
+++ b/src/test/ui/suggestions/sugg-else-for-closure.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/sugg-else-for-closure.rs:6:26
+   |
+LL |     let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap());
+   |                --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found closure
+   |                |
+   |                arguments to this function are incorrect
+   |
+   = note: expected reference `&str`
+                found closure `[closure@$DIR/sugg-else-for-closure.rs:6:26: 6:28]`
+note: associated function defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL |     pub const fn unwrap_or(self, default: T) -> T
+   |                  ^^^^^^^^^
+help: try calling `unwrap_or_else` instead
+   |
+LL |     let _s = y.unwrap_or_else(|| x.split('.').nth(1).unwrap());
+   |                         +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index f716e6c17e2..ffd505fffb4 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -37,9 +37,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |                           ^^^^^^^^^^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
diff --git a/src/test/ui/test-attrs/test-on-not-fn.stderr b/src/test/ui/test-attrs/test-on-not-fn.stderr
index 23efd5bc0d9..fc2c5f62bed 100644
--- a/src/test/ui/test-attrs/test-on-not-fn.stderr
+++ b/src/test/ui/test-attrs/test-on-not-fn.stderr
@@ -2,7 +2,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:3:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | mod test {}
    | ----------- expected a non-associated function, found a module
    |
@@ -15,7 +15,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:6:1
    |
 LL |   #[test]
-   |   ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   |   ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | / mod loooooooooooooong_teeeeeeeeeest {
 LL | |     /*
 LL | |     this is a comment
@@ -34,7 +34,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:20:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | extern "C" {}
    | ------------- expected a non-associated function, found an extern block
    |
@@ -47,7 +47,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:23:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | trait Foo {}
    | ------------ expected a non-associated function, found a trait
    |
@@ -60,7 +60,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:26:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | impl Foo for i32 {}
    | ------------------- expected a non-associated function, found an implementation
    |
@@ -73,7 +73,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:29:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | const FOO: i32 = -1_i32;
    | ------------------------ expected a non-associated function, found a constant item
    |
@@ -86,7 +86,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:32:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | static BAR: u64 = 10_000_u64;
    | ----------------------------- expected a non-associated function, found a static item
    |
@@ -99,7 +99,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:35:1
    |
 LL |   #[test]
-   |   ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   |   ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | / enum MyUnit {
 LL | |     Unit,
 LL | | }
@@ -114,7 +114,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:40:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | struct NewI32(i32);
    | ------------------- expected a non-associated function, found a struct
    |
@@ -127,7 +127,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:43:1
    |
 LL |   #[test]
-   |   ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   |   ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | / union Spooky {
 LL | |     x: i32,
 LL | |     y: u32,
@@ -143,7 +143,7 @@ error: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:50:1
    |
 LL |   #[test]
-   |   ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   |   ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL |   #[derive(Copy, Clone, Debug)]
 LL | / struct MoreAttrs {
 LL | |     a: i32,
@@ -160,7 +160,7 @@ warning: the `#[test]` attribute may only be used on a non-associated function
   --> $DIR/test-on-not-fn.rs:61:1
    |
 LL | #[test]
-   | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+   | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions
 LL | foo!();
    | ------- expected a non-associated function, found an item macro invocation
    |
diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr
index 1c52629daa4..8da0b6d6b85 100644
--- a/src/test/ui/traits/bound/not-on-bare-trait.stderr
+++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | fn foo(_x: Foo + Send) {
    |            ^^^^^^^^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL | fn foo(_x: dyn Foo + Send) {
diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
index 6acf2fe65ce..61b6d4b08bb 100644
--- a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
+++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
@@ -9,8 +9,8 @@ LL |   {
 LL |       recurse(IteratorOfWrapped(elements).map(|t| t.0))
    |       ------------------------------------------------- recursive call site
    |
-   = note: `#[warn(unconditional_recursion)]` on by default
    = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
 
 error[E0275]: overflow evaluating the requirement `(): Sized`
    |
diff --git a/src/test/ui/traits/negative-impls/negative-default-impls.stderr b/src/test/ui/traits/negative-impls/negative-default-impls.stderr
index ceb86559d85..7b54cf54222 100644
--- a/src/test/ui/traits/negative-impls/negative-default-impls.stderr
+++ b/src/test/ui/traits/negative-impls/negative-default-impls.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0750]: negative impls cannot be default impls
   --> $DIR/negative-default-impls.rs:9:1
diff --git a/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr b/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr
index 9a846143d3d..751e29c3b23 100644
--- a/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr
+++ b/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr
index 77b4373a273..1cfa49b20f3 100644
--- a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr
+++ b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
   --> $DIR/negative-specializes-positive-item.rs:11:1
diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr
index e5dc81b3eb7..9f9e28678ab 100644
--- a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr
+++ b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
   --> $DIR/negative-specializes-positive.rs:7:1
diff --git a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr
index c091bc81da3..545f94143ad 100644
--- a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr
+++ b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr
@@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
   --> $DIR/positive-specializes-negative.rs:7:1
diff --git a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
index 77d71360b80..4ab777bd4df 100644
--- a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
+++ b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
@@ -6,13 +6,13 @@ LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 note: the lint level is defined here
   --> $DIR/issue-33140-traitobject-crate.rs:3:9
    |
 LL | #![warn(order_dependent_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
 warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:89:1
diff --git a/src/test/ui/traits/static-method-generic-inference.stderr b/src/test/ui/traits/static-method-generic-inference.stderr
index f1b8f23ecc7..5f74d0c3b92 100644
--- a/src/test/ui/traits/static-method-generic-inference.stderr
+++ b/src/test/ui/traits/static-method-generic-inference.stderr
@@ -9,8 +9,8 @@ LL |     let _f: base::Foo = base::HasNew::new();
    |
 help: use the fully-qualified path to the only available implementation
    |
-LL |     let _f: base::Foo = base::<::base::Foo as HasNew>::new();
-   |                               +++++++++++++++       +
+LL |     let _f: base::Foo = base::<Foo as HasNew>::new();
+   |                               +++++++       +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr
index 35af9112a27..6c359b69836 100644
--- a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr
+++ b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr
@@ -4,13 +4,13 @@ error: `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
 LL |     take_a(b)
    |            ^
    |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
 note: the lint level is defined here
   --> $DIR/migrate-lint-deny.rs:1:9
    |
 LL | #![deny(deref_into_dyn_supertrait)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/unspecified-self-in-trait-ref.stderr b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr
index 7869176bb3a..b5e8e88676c 100644
--- a/src/test/ui/traits/unspecified-self-in-trait-ref.stderr
+++ b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr
@@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let a = Foo::lol();
    |             ^^^
    |
-   = note: `#[warn(bare_trait_objects)]` on by default
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
 help: use `dyn`
    |
 LL |     let a = <dyn Foo>::lol();
diff --git a/src/test/ui/transmutability/issue-101739-1.rs b/src/test/ui/transmutability/issue-101739-1.rs
new file mode 100644
index 00000000000..bcb8b158edf
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-1.rs
@@ -0,0 +1,21 @@
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::BikeshedIntrinsicFrom;
+
+    pub fn is_transmutable<Src, Context, const ASSUME_ALIGNMENT: bool>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
+        //~^ ERROR mismatched types
+    {
+    }
+}
+
+fn via_const() {
+    struct Context;
+    struct Src;
+
+    assert::is_transmutable::<Src, Context, false>();
+}
+
+fn main() {}
diff --git a/src/test/ui/transmutability/issue-101739-1.stderr b/src/test/ui/transmutability/issue-101739-1.stderr
new file mode 100644
index 00000000000..5fa741f26fd
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-1.stderr
@@ -0,0 +1,16 @@
+error[E0412]: cannot find type `Dst` in this scope
+  --> $DIR/issue-101739-1.rs:8:9
+   |
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
+   |         ^^^ not found in this scope
+
+error[E0308]: mismatched types
+  --> $DIR/issue-101739-1.rs:8:50
+   |
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
+   |                                                  ^^^^^^^^^^^^^^^^ expected struct `Assume`, found `bool`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0412.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/transmutability/issue-101739-2.rs b/src/test/ui/transmutability/issue-101739-2.rs
new file mode 100644
index 00000000000..964a7e49ee6
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-2.rs
@@ -0,0 +1,37 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+mod assert {
+    use std::mem::BikeshedIntrinsicFrom;
+
+    pub fn is_transmutable<
+        Src,
+        Dst,
+        Context,
+        const ASSUME_ALIGNMENT: bool,
+        const ASSUME_LIFETIMES: bool,
+        const ASSUME_VALIDITY: bool,
+        const ASSUME_VISIBILITY: bool,
+    >()
+    where
+        Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+            Src,
+            Context,
+            ASSUME_ALIGNMENT,
+            ASSUME_LIFETIMES,
+            ASSUME_VALIDITY,
+            ASSUME_VISIBILITY,
+        >,
+    {}
+}
+
+fn via_const() {
+    struct Context;
+    #[repr(C)] struct Src;
+    #[repr(C)] struct Dst;
+
+    const FALSE: bool = false;
+
+    assert::is_transmutable::<Src, Dst, Context, FALSE, FALSE, FALSE, FALSE>();
+}
diff --git a/src/test/ui/transmutability/issue-101739-2.stderr b/src/test/ui/transmutability/issue-101739-2.stderr
new file mode 100644
index 00000000000..3f83d6583b0
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-2.stderr
@@ -0,0 +1,20 @@
+error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+  --> $DIR/issue-101739-2.rs:18:14
+   |
+LL |           Dst: BikeshedIntrinsicFrom<
+   |                ^^^^^^^^^^^^^^^^^^^^^ expected at most 3 generic arguments
+...
+LL | /             ASSUME_LIFETIMES,
+LL | |             ASSUME_VALIDITY,
+LL | |             ASSUME_VISIBILITY,
+   | |_____________________________- help: remove these generic arguments
+   |
+note: trait defined here, with at most 3 generic parameters: `Src`, `Context`, `ASSUME`
+  --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
+   |
+LL | pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
+   |                  ^^^^^^^^^^^^^^^^^^^^^ ---  -------  ------------------------------------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
index aaa3159e0b0..0202a2fea49 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
@@ -4,7 +4,6 @@ error: ambiguous associated item
 LL |     fn f() -> Self::V { 0 }
    |               ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V`
    |
-   = note: `#[deny(ambiguous_associated_items)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
 note: `V` could refer to the variant defined here
@@ -17,6 +16,7 @@ note: `V` could also refer to the associated type defined here
    |
 LL |     type V;
    |     ^^^^^^
+   = note: `#[deny(ambiguous_associated_items)]` on by default
 
 error: ambiguous associated item
   --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15
diff --git a/src/test/ui/type/issue-101866.rs b/src/test/ui/type/issue-101866.rs
new file mode 100644
index 00000000000..d332c4adb00
--- /dev/null
+++ b/src/test/ui/type/issue-101866.rs
@@ -0,0 +1,15 @@
+trait TraitA<T> {
+    fn func();
+}
+
+struct StructA {}
+
+impl TraitA<i32> for StructA {
+    fn func() {}
+}
+
+fn main() {
+    TraitA::<i32>::func();
+    //~^ ERROR: cannot call associated function on trait without specifying the corresponding `impl` type [E0790]
+    //~| help: use the fully-qualified path to the only available implementation
+}
diff --git a/src/test/ui/type/issue-101866.stderr b/src/test/ui/type/issue-101866.stderr
new file mode 100644
index 00000000000..fe99821198e
--- /dev/null
+++ b/src/test/ui/type/issue-101866.stderr
@@ -0,0 +1,18 @@
+error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
+  --> $DIR/issue-101866.rs:12:5
+   |
+LL |     fn func();
+   |     ---------- `TraitA::func` defined here
+...
+LL |     TraitA::<i32>::func();
+   |     ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |
+help: use the fully-qualified path to the only available implementation
+   |
+LL -     TraitA::<i32>::func();
+LL +     <StructA as TraitA<i32>>::func();
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0790`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr
index ba4b3dac670..6450cc30ac0 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr
@@ -12,8 +12,8 @@ warning: value assigned to `counter` is never read
 LL |         counter += 1;
    |         ^^^^^^^
    |
-   = note: `#[warn(unused_assignments)]` on by default
    = help: maybe it is overwritten before being read?
+   = note: `#[warn(unused_assignments)]` on by default
 
 warning: unused variable: `counter`
   --> $DIR/unboxed-closures-counter-not-moved.rs:24:9
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr
index 1254f8dbc5e..5c06f4e621c 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr
@@ -4,8 +4,8 @@ warning: unused variable: `x`
 LL |         move || x += 1;
    |                 ^
    |
-   = note: `#[warn(unused_variables)]` on by default
    = help: did you mean to capture by reference instead?
+   = note: `#[warn(unused_variables)]` on by default
 
 warning: unused variable: `x`
   --> $DIR/unboxed-closures-move-mutable.rs:21:17
diff --git a/src/test/ui/union/union-repr-c.stderr b/src/test/ui/union/union-repr-c.stderr
index 9abf440f735..49124eee5ee 100644
--- a/src/test/ui/union/union-repr-c.stderr
+++ b/src/test/ui/union/union-repr-c.stderr
@@ -4,11 +4,6 @@ error: `extern` block uses type `W`, which is not FFI-safe
 LL |     static FOREIGN2: W;
    |                      ^ not FFI-safe
    |
-note: the lint level is defined here
-  --> $DIR/union-repr-c.rs:2:9
-   |
-LL | #![deny(improper_ctypes)]
-   |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
    = note: this union has unspecified layout
 note: the type is defined here
@@ -16,6 +11,11 @@ note: the type is defined here
    |
 LL | union W {
    | ^^^^^^^
+note: the lint level is defined here
+  --> $DIR/union-repr-c.rs:2:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr
index 7e6885bd706..aa73b824a57 100644
--- a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr
+++ b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr
@@ -1,8 +1,8 @@
 error: unknown lint: `test_unstable_lint`
    |
-   = note: requested on the command line with `-D unknown-lints`
    = note: the `test_unstable_lint` lint is unstable
    = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = note: requested on the command line with `-D unknown-lints`
 
 error: unknown lint: `test_unstable_lint`
    |
diff --git a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr
index 2d1027dd0e0..2a2a9811bfb 100644
--- a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr
+++ b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr
@@ -4,13 +4,13 @@ error: unknown lint: `test_unstable_lint`
 LL | #![allow(test_unstable_lint)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: the `test_unstable_lint` lint is unstable
+   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
 note: the lint level is defined here
   --> $DIR/deny-unstable-lint-inline.rs:3:9
    |
 LL | #![deny(unknown_lints)]
    |         ^^^^^^^^^^^^^
-   = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
 
 error: unknown lint: `test_unstable_lint`
   --> $DIR/deny-unstable-lint-inline.rs:4:1
diff --git a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr
index 799d740b00e..82851c80064 100644
--- a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr
+++ b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr
@@ -1,8 +1,8 @@
 warning: unknown lint: `test_unstable_lint`
    |
-   = note: requested on the command line with `-W unknown-lints`
    = note: the `test_unstable_lint` lint is unstable
    = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
+   = note: requested on the command line with `-W unknown-lints`
 
 warning: unknown lint: `test_unstable_lint`
    |
diff --git a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr
index 142558b471b..0548cd226d8 100644
--- a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr
+++ b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr
@@ -4,13 +4,13 @@ warning: unknown lint: `test_unstable_lint`
 LL | #![allow(test_unstable_lint)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: the `test_unstable_lint` lint is unstable
+   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
 note: the lint level is defined here
   --> $DIR/warn-unknown-unstable-lint-inline.rs:3:9
    |
 LL | #![warn(unknown_lints)]
    |         ^^^^^^^^^^^^^
-   = note: the `test_unstable_lint` lint is unstable
-   = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
 
 warning: unknown lint: `test_unstable_lint`
   --> $DIR/warn-unknown-unstable-lint-inline.rs:4:1
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
index b968174dd2d..6f005fe8958 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
@@ -4,12 +4,12 @@ error: call to unsafe function is unsafe and requires unsafe block (error E0133)
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
    |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 note: the lint level is defined here
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
    |
 LL | #![deny(unsafe_op_in_unsafe_fn)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5
@@ -45,13 +45,13 @@ error: call to unsafe function is unsafe and requires unsafe block (error E0133)
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
    |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 note: the lint level is defined here
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8
    |
 LL | #[deny(warnings)]
    |        ^^^^^^^^
    = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]`
-   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
index e365293657e..13c080e5b6a 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
@@ -4,12 +4,12 @@ error: call to unsafe function `unsf` is unsafe and requires unsafe block (error
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
    |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 note: the lint level is defined here
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
    |
 LL | #![deny(unsafe_op_in_unsafe_fn)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5
@@ -45,13 +45,13 @@ error: call to unsafe function `unsf` is unsafe and requires unsafe block (error
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
    |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 note: the lint level is defined here
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8
    |
 LL | #[deny(warnings)]
    |        ^^^^^^^^
    = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]`
-   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
   --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
diff --git a/src/test/ui/unsized-locals/borrow-after-move.stderr b/src/test/ui/unsized-locals/borrow-after-move.stderr
index 4f2bc06d4ab..28ae1c0688c 100644
--- a/src/test/ui/unsized-locals/borrow-after-move.stderr
+++ b/src/test/ui/unsized-locals/borrow-after-move.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals, unsized_fn_params)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0382]: borrow of moved value: `x`
   --> $DIR/borrow-after-move.rs:21:24
diff --git a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr
index 59d91bc0cfd..4f13ec7ac08 100644
--- a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr
+++ b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error: the `foo` method cannot be invoked on a trait object
   --> $DIR/by-value-trait-object-safety.rs:20:7
diff --git a/src/test/ui/unsized-locals/double-move.stderr b/src/test/ui/unsized-locals/double-move.stderr
index 4bb2ad88faf..dfae6cc75d9 100644
--- a/src/test/ui/unsized-locals/double-move.stderr
+++ b/src/test/ui/unsized-locals/double-move.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals, unsized_fn_params)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0382]: use of moved value: `y`
   --> $DIR/double-move.rs:21:22
diff --git a/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr b/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr
index 0f0ff579377..b6002cf895f 100644
--- a/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr
+++ b/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
   --> $DIR/issue-30276-feature-flagged.rs:7:29
diff --git a/src/test/ui/unsized-locals/issue-50940-with-feature.stderr b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr
index 4523d41b600..8bbe317ec74 100644
--- a/src/test/ui/unsized-locals/issue-50940-with-feature.stderr
+++ b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr
@@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a
 LL | #![feature(unsized_locals, unsized_fn_params)]
    |            ^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/issue-50940-with-feature.rs:6:5
diff --git a/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr b/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr
index a67f46cd2e3..214ddc45ce9 100644
--- a/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr
+++ b/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr
@@ -4,10 +4,10 @@ warning: unknown lint: `ffi_unwind_calls`
 LL | #![allow(ffi_unwind_calls)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(unknown_lints)]` on by default
    = note: the `ffi_unwind_calls` lint is unstable
    = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
    = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+   = note: `#[warn(unknown_lints)]` on by default
 
 error[E0658]: C-unwind ABI is experimental and subject to change
   --> $DIR/feature-gate-c-unwind.rs:8:8
diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
new file mode 100644
index 00000000000..d9950a3d9b7
--- /dev/null
+++ b/src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
+  --> $DIR/higher-ranked-fn-type.rs:20:5
+   |
+LL |     called()
+   |     ^^^^^^ the trait `for<'b> Foo` is not implemented for `for<'b> fn(&'b ())`
+   |
+note: required by a bound in `called`
+  --> $DIR/higher-ranked-fn-type.rs:12:25
+   |
+LL | fn called()
+   |    ------ required by a bound in this
+LL | where
+LL |     for<'b> fn(&'b ()): Foo,
+   |                         ^^^ required by this bound in `called`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.rs b/src/test/ui/where-clauses/higher-ranked-fn-type.rs
new file mode 100644
index 00000000000..0d8893e08d3
--- /dev/null
+++ b/src/test/ui/where-clauses/higher-ranked-fn-type.rs
@@ -0,0 +1,25 @@
+// revisions: quiet verbose
+// [verbose]compile-flags: -Zverbose
+
+#![allow(unused_parens)]
+
+trait Foo {
+    type Assoc;
+}
+
+fn called()
+where
+    for<'b> fn(&'b ()): Foo,
+{
+}
+
+fn caller()
+where
+    (for<'a> fn(&'a ())): Foo,
+{
+    called()
+    //[quiet]~^ ERROR the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
+    //[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound(
+}
+
+fn main() {}
diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
new file mode 100644
index 00000000000..24660ec3539
--- /dev/null
+++ b/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `for<'b> fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ()): Foo` is not satisfied
+  --> $DIR/higher-ranked-fn-type.rs:20:5
+   |
+LL |     called()
+   |     ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ())`
+   |
+note: required by a bound in `called`
+  --> $DIR/higher-ranked-fn-type.rs:12:25
+   |
+LL | fn called()
+   |    ------ required by a bound in this
+LL | where
+LL |     for<'b> fn(&'b ()): Foo,
+   |                         ^^^ required by this bound in `called`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 14311cff5c8..b0006cb90bd 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -193,6 +193,12 @@ macro_rules! t {
             Err(e) => panic!("{} failed with {}", stringify!($e), e),
         }
     };
+    ($e:expr, $extra:expr) => {
+        match $e {
+            Ok(e) => e,
+            Err(e) => panic!("{} failed with {}: {}", stringify!($e), e, $extra),
+        }
+    };
 }
 
 struct Builder {
@@ -437,7 +443,7 @@ impl Builder {
             host_component("rustfmt-preview"),
             host_component("llvm-tools-preview"),
             host_component("rust-analysis"),
-            host_component("rust-docs-json"),
+            host_component("rust-docs-json-preview"),
         ]);
 
         extensions.extend(
@@ -584,7 +590,7 @@ impl Builder {
         self.shipped_files.insert(name.clone());
 
         let dst = self.output.join(name);
-        t!(fs::write(&dst, contents));
+        t!(fs::write(&dst, contents), format!("failed to create manifest {}", dst.display()));
     }
 
     fn write_shipped_files(&self, path: &Path) {
diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs
index 92ef9968fe5..0186194a41f 100644
--- a/src/tools/build-manifest/src/versions.rs
+++ b/src/tools/build-manifest/src/versions.rs
@@ -20,6 +20,7 @@ pub(crate) enum PkgType {
     Rustfmt,
     LlvmTools,
     Miri,
+    JsonDocs,
     Other(String),
 }
 
@@ -36,6 +37,7 @@ impl PkgType {
             "rustfmt" | "rustfmt-preview" => PkgType::Rustfmt,
             "llvm-tools" | "llvm-tools-preview" => PkgType::LlvmTools,
             "miri" | "miri-preview" => PkgType::Miri,
+            "rust-docs-json" | "rust-docs-json-preview" => PkgType::JsonDocs,
             other => PkgType::Other(other.into()),
         }
     }
@@ -53,6 +55,7 @@ impl PkgType {
             PkgType::Rustfmt => "rustfmt",
             PkgType::LlvmTools => "llvm-tools",
             PkgType::Miri => "miri",
+            PkgType::JsonDocs => "rust-docs-json",
             PkgType::Other(component) => component,
         }
     }
@@ -72,6 +75,7 @@ impl PkgType {
             PkgType::Rust => true,
             PkgType::RustSrc => true,
             PkgType::Rustc => true,
+            PkgType::JsonDocs => true,
             PkgType::Other(_) => true,
         }
     }
@@ -113,6 +117,9 @@ impl Versions {
             Some(version) => Ok(version.clone()),
             None => {
                 let version_info = self.load_version_from_tarball(package)?;
+                if *package == PkgType::Rust && version_info.version.is_none() {
+                    panic!("missing version info for toolchain");
+                }
                 self.versions.insert(package.clone(), version_info.clone());
                 Ok(version_info)
             }
@@ -127,6 +134,7 @@ impl Versions {
             Ok(file) => file,
             Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
                 // Missing tarballs do not return an error, but return empty data.
+                println!("warning: missing tarball {}", tarball.display());
                 return Ok(VersionInfo::default());
             }
             Err(err) => return Err(err.into()),
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject f5fed93ba24607980647962c59863bbabb03ce1
+Subproject 0b84a35c2c7d70df4875a03eb19084b0e7a543e
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index e54d71fc8e4..f0d5ed6f594 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1238,7 +1238,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
             ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => {
                 Position::ReborrowStable(precedence).into()
             },
-            ty::Adt(_, substs) if substs.has_param_types_or_consts() => {
+            ty::Adt(_, substs) if substs.has_non_region_param() => {
                 TyPosition::new_deref_stable_for_result(precedence, ty)
             },
             ty::Bool
diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs
index 22071ab3044..102b9fbae83 100644
--- a/src/tools/clippy/clippy_lints/src/module_style.rs
+++ b/src/tools/clippy/clippy_lints/src/module_style.rs
@@ -117,11 +117,13 @@ impl EarlyLintPass for ModStyle {
                     cx.struct_span_lint(
                         SELF_NAMED_MODULE_FILES,
                         Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
-                        |build| {
-                            let mut lint =
-                                build.build(&format!("`mod.rs` files are required, found `{}`", path.display()));
-                            lint.help(&format!("move `{}` to `{}`", path.display(), correct.display(),));
-                            lint.emit();
+                        format!("`mod.rs` files are required, found `{}`", path.display()),
+                        |lint| {
+                            lint.help(format!(
+                                "move `{}` to `{}`",
+                                path.display(),
+                                correct.display(),
+                            ))
                         },
                     );
                 }
@@ -156,11 +158,8 @@ fn check_self_named_mod_exists(cx: &EarlyContext<'_>, path: &Path, file: &Source
         cx.struct_span_lint(
             MOD_MODULE_FILES,
             Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
-            |build| {
-                let mut lint = build.build(&format!("`mod.rs` files are not allowed, found `{}`", path.display()));
-                lint.help(&format!("move `{}` to `{}`", path.display(), mod_file.display(),));
-                lint.emit();
-            },
+            format!("`mod.rs` files are not allowed, found `{}`", path.display()),
+            |lint| lint.help(format!("move `{}` to `{}`", path.display(), mod_file.display())),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index a25be93b8d6..2be22884027 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
                 if !bound_predicate.span.from_expansion();
                 if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
                 if let Some(PathSegment {
-                    res: Res::SelfTy{ trait_: Some(def_id), alias_to: _ }, ..
+                    res: Res::SelfTyParam { trait_: def_id }, ..
                 }) = segments.first();
                 if let Some(
                     Node::Item(
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 6a767967ef4..2c4f5075e98 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -206,7 +206,12 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
                 ref types_to_skip,
             }) = self.stack.last();
             if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
-            if !matches!(path.res, Res::SelfTy { .. } | Res::Def(DefKind::TyParam, _));
+            if !matches!(
+                path.res,
+                Res::SelfTyParam { .. }
+                | Res::SelfTyAlias { .. }
+                | Res::Def(DefKind::TyParam, _)
+            );
             if !types_to_skip.contains(&hir_ty.hir_id);
             let ty = if in_body > 0 {
                 cx.typeck_results().node_type(hir_ty.hir_id)
@@ -230,7 +235,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         }
         match expr.kind {
             ExprKind::Struct(QPath::Resolved(_, path), ..) => match path.res {
-                Res::SelfTy { .. } => (),
+                Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => (),
                 Res::Def(DefKind::Variant, _) => lint_path_to_variant(cx, path),
                 _ => span_lint(cx, path.span),
             },
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index ad95369b9ef..78960d1ab1d 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -47,10 +47,9 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) {
 ///    |     ^^^^^^^^^^^^^^^^^^^^^^^
 /// ```
 pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: &str) {
-    cx.struct_span_lint(lint, sp, |diag| {
-        let mut diag = diag.build(msg);
-        docs_link(&mut diag, lint);
-        diag.emit();
+    cx.struct_span_lint(lint, sp, msg, |diag| {
+        docs_link(diag, lint);
+        diag
     });
 }
 
@@ -82,15 +81,14 @@ pub fn span_lint_and_help<'a, T: LintContext>(
     help_span: Option<Span>,
     help: &str,
 ) {
-    cx.struct_span_lint(lint, span, |diag| {
-        let mut diag = diag.build(msg);
+    cx.struct_span_lint(lint, span, msg, |diag| {
         if let Some(help_span) = help_span {
             diag.span_help(help_span, help);
         } else {
             diag.help(help);
         }
-        docs_link(&mut diag, lint);
-        diag.emit();
+        docs_link(diag, lint);
+        diag
     });
 }
 
@@ -125,15 +123,14 @@ pub fn span_lint_and_note<'a, T: LintContext>(
     note_span: Option<Span>,
     note: &str,
 ) {
-    cx.struct_span_lint(lint, span, |diag| {
-        let mut diag = diag.build(msg);
+    cx.struct_span_lint(lint, span, msg, |diag| {
         if let Some(note_span) = note_span {
             diag.span_note(note_span, note);
         } else {
             diag.note(note);
         }
-        docs_link(&mut diag, lint);
-        diag.emit();
+        docs_link(diag, lint);
+        diag
     });
 }
 
@@ -147,19 +144,17 @@ where
     S: Into<MultiSpan>,
     F: FnOnce(&mut Diagnostic),
 {
-    cx.struct_span_lint(lint, sp, |diag| {
-        let mut diag = diag.build(msg);
-        f(&mut diag);
-        docs_link(&mut diag, lint);
-        diag.emit();
+    cx.struct_span_lint(lint, sp, msg, |diag| {
+        f(diag);
+        docs_link(diag, lint);
+        diag
     });
 }
 
 pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) {
-    cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| {
-        let mut diag = diag.build(msg);
-        docs_link(&mut diag, lint);
-        diag.emit();
+    cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| {
+        docs_link(diag, lint);
+        diag
     });
 }
 
@@ -171,11 +166,10 @@ pub fn span_lint_hir_and_then(
     msg: &str,
     f: impl FnOnce(&mut Diagnostic),
 ) {
-    cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| {
-        let mut diag = diag.build(msg);
-        f(&mut diag);
-        docs_link(&mut diag, lint);
-        diag.emit();
+    cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| {
+        f(diag);
+        docs_link(diag, lint);
+        diag
     });
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 627d6b51944..8f79c07c977 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1535,7 +1535,7 @@ pub fn is_self(slf: &Param<'_>) -> bool {
 
 pub fn is_self_ty(slf: &hir::Ty<'_>) -> bool {
     if let TyKind::Path(QPath::Resolved(None, path)) = slf.kind {
-        if let Res::SelfTy { .. } = path.res {
+        if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path.res {
             return true;
         }
     }
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
index 62c45b54634..4c75998437f 100644
--- a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
@@ -4,8 +4,8 @@ error: `std::string::String` may not be held across an `await` point per `clippy
 LL |     let _x = String::from("hello");
    |         ^^
    |
-   = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`
    = note: strings are bad
+   = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`
 
 error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml`
   --> $DIR/await_holding_invalid_type.rs:10:9
diff --git a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
index 4c560299ebd..b2b57bdde89 100644
--- a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr
@@ -8,8 +8,8 @@ error: the function has a cognitive complexity of (3/2)
 LL | fn cognitive_complexity() {
    |    ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
    = help: you could split it up into multiple smaller functions
+   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
 
 error: aborting due to previous error; 2 warnings emitted
 
diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
index c5d95cb8a14..28a08599c67 100644
--- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr
@@ -4,8 +4,8 @@ error: used `expect()` on `an Option` value
 LL |     let _ = opt.expect("");
    |             ^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::expect-used` implied by `-D warnings`
    = help: if this value is `None`, it will panic
+   = note: `-D clippy::expect-used` implied by `-D warnings`
 
 error: used `expect()` on `a Result` value
   --> $DIR/expect_used.rs:11:13
diff --git a/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr b/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr
index d05adc3d36e..87bdb61c6a5 100644
--- a/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr
@@ -4,8 +4,8 @@ error: more than 1 bools in function parameters
 LL | fn g(_: bool, _: bool) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
    = help: consider refactoring bools into two-variant enums
+   = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
index 6a685a58318..7b5fb9e8765 100644
--- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
@@ -4,8 +4,8 @@ error: attempted to include a large file
 LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::large-include-file` implied by `-D warnings`
    = note: the configuration allows a maximum size of 600 bytes
+   = note: `-D clippy::large-include-file` implied by `-D warnings`
    = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: attempted to include a large file
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
index d80ad49f308..15fa4f42f9b 100644
--- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
@@ -4,12 +4,12 @@ error: use of irregular braces for `vec!` macro
 LL |     let _ = vec! {1, 2, 3};
    |             ^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings`
 help: consider writing `vec![1, 2, 3]`
   --> $DIR/conf_nonstandard_macro_braces.rs:43:13
    |
 LL |     let _ = vec! {1, 2, 3};
    |             ^^^^^^^^^^^^^^
+   = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings`
 
 error: use of irregular braces for `format!` macro
   --> $DIR/conf_nonstandard_macro_braces.rs:44:13
diff --git a/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr b/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
index 49eecf18b4c..c72f8c6488d 100644
--- a/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
@@ -4,13 +4,13 @@ error: some fields in `NoGeneric` are not safe to be sent to another thread
 LL | unsafe impl Send for NoGeneric {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
 note: it is not safe to send field `rc_is_not_send` to another thread
   --> $DIR/test.rs:8:5
    |
 LL |     rc_is_not_send: Rc<String>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use a thread-safe type that implements `Send`
+   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
 
 error: some fields in `MultiField<T>` are not safe to be sent to another thread
   --> $DIR/test.rs:19:1
diff --git a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr
index 65861d10d0f..4e7c70d1838 100644
--- a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr
@@ -6,8 +6,8 @@ LL | |     a: bool,
 LL | | }
    | |_^
    |
-   = note: `-D clippy::struct-excessive-bools` implied by `-D warnings`
    = help: consider using a state machine or refactoring bools into two-variant enums
+   = note: `-D clippy::struct-excessive-bools` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
index 6bcfa0a8b56..681b5eaf54d 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
@@ -16,8 +16,8 @@ error: used `unwrap()` on `an Option` value
 LL |         let _ = boxed_slice.get(1).unwrap();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::unwrap-used` implied by `-D warnings`
    = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
+   = note: `-D clippy::unwrap-used` implied by `-D warnings`
 
 error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
   --> $DIR/unwrap_used.rs:36:17
diff --git a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr
index 6de554378aa..21cb11fa1bb 100644
--- a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr
+++ b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr
@@ -4,8 +4,8 @@ error: this comparison involving the minimum or maximum element for this type co
 LL |     u <= 0;
    |     ^^^^^^
    |
-   = note: `-D clippy::absurd-extreme-comparisons` implied by `-D warnings`
    = help: because `0` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == 0` instead
+   = note: `-D clippy::absurd-extreme-comparisons` implied by `-D warnings`
 
 error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
   --> $DIR/absurd-extreme-comparisons.rs:15:5
diff --git a/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr b/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr
index cd040a144aa..23f17e9a7af 100644
--- a/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr
+++ b/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr
@@ -4,12 +4,12 @@ error: `allow` attribute without specifying a reason
 LL | #[allow(dead_code)]
    | ^^^^^^^^^^^^^^^^^^^
    |
+   = help: try adding a reason at the end with `, reason = ".."`
 note: the lint level is defined here
   --> $DIR/allow_attributes_without_reason.rs:2:9
    |
 LL | #![deny(clippy::allow_attributes_without_reason)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: try adding a reason at the end with `, reason = ".."`
 
 error: `allow` attribute without specifying a reason
   --> $DIR/allow_attributes_without_reason.rs:6:1
diff --git a/src/tools/clippy/tests/ui/approx_const.stderr b/src/tools/clippy/tests/ui/approx_const.stderr
index 4da1b8215ae..0932a2eec52 100644
--- a/src/tools/clippy/tests/ui/approx_const.stderr
+++ b/src/tools/clippy/tests/ui/approx_const.stderr
@@ -4,8 +4,8 @@ error: approximate value of `f{32, 64}::consts::E` found
 LL |     let my_e = 2.7182;
    |                ^^^^^^
    |
-   = note: `-D clippy::approx-constant` implied by `-D warnings`
    = help: consider using the constant directly
+   = note: `-D clippy::approx-constant` implied by `-D warnings`
 
 error: approximate value of `f{32, 64}::consts::E` found
   --> $DIR/approx_const.rs:5:20
diff --git a/src/tools/clippy/tests/ui/as_conversions.stderr b/src/tools/clippy/tests/ui/as_conversions.stderr
index d11b56171b0..f5d59e1e5d8 100644
--- a/src/tools/clippy/tests/ui/as_conversions.stderr
+++ b/src/tools/clippy/tests/ui/as_conversions.stderr
@@ -4,8 +4,8 @@ error: using a potentially dangerous silent `as` conversion
 LL |     let i = 0u32 as u64;
    |             ^^^^^^^^^^^
    |
-   = note: `-D clippy::as-conversions` implied by `-D warnings`
    = help: consider using a safe wrapper for this conversion
+   = note: `-D clippy::as-conversions` implied by `-D warnings`
 
 error: using a potentially dangerous silent `as` conversion
   --> $DIR/as_conversions.rs:17:13
diff --git a/src/tools/clippy/tests/ui/asm_syntax.stderr b/src/tools/clippy/tests/ui/asm_syntax.stderr
index e9b150121aa..9c7c3ba7d87 100644
--- a/src/tools/clippy/tests/ui/asm_syntax.stderr
+++ b/src/tools/clippy/tests/ui/asm_syntax.stderr
@@ -4,8 +4,8 @@ error: Intel x86 assembly syntax used
 LL |         asm!("");
    |         ^^^^^^^^
    |
-   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`
    = help: use AT&T x86 assembly syntax
+   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`
 
 error: Intel x86 assembly syntax used
   --> $DIR/asm_syntax.rs:9:9
@@ -29,8 +29,8 @@ error: AT&T x86 assembly syntax used
 LL |         asm!("", options(att_syntax));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`
    = help: use Intel x86 assembly syntax
+   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`
 
 error: AT&T x86 assembly syntax used
   --> $DIR/asm_syntax.rs:24:9
diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.stderr b/src/tools/clippy/tests/ui/assertions_on_constants.stderr
index e1f818814d5..29fe009035f 100644
--- a/src/tools/clippy/tests/ui/assertions_on_constants.stderr
+++ b/src/tools/clippy/tests/ui/assertions_on_constants.stderr
@@ -4,8 +4,8 @@ error: `assert!(true)` will be optimized out by the compiler
 LL |     assert!(true);
    |     ^^^^^^^^^^^^^
    |
-   = note: `-D clippy::assertions-on-constants` implied by `-D warnings`
    = help: remove it
+   = note: `-D clippy::assertions-on-constants` implied by `-D warnings`
 
 error: `assert!(false)` should probably be replaced
   --> $DIR/assertions_on_constants.rs:11:5
diff --git a/src/tools/clippy/tests/ui/await_holding_lock.stderr b/src/tools/clippy/tests/ui/await_holding_lock.stderr
index 976da8d9242..81a2d052438 100644
--- a/src/tools/clippy/tests/ui/await_holding_lock.stderr
+++ b/src/tools/clippy/tests/ui/await_holding_lock.stderr
@@ -4,7 +4,6 @@ error: this `MutexGuard` is held across an `await` point
 LL |         let guard = x.lock().unwrap();
    |             ^^^^^
    |
-   = note: `-D clippy::await-holding-lock` implied by `-D warnings`
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
   --> $DIR/await_holding_lock.rs:9:9
@@ -13,6 +12,7 @@ LL | /         let guard = x.lock().unwrap();
 LL | |         baz().await
 LL | |     }
    | |_____^
+   = note: `-D clippy::await-holding-lock` implied by `-D warnings`
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:24:13
diff --git a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
index 4339fca735d..25c15ab8060 100644
--- a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
+++ b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
@@ -4,7 +4,6 @@ error: this `RefCell` reference is held across an `await` point
 LL |     let b = x.borrow();
    |         ^
    |
-   = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
   --> $DIR/await_holding_refcell_ref.rs:6:5
@@ -13,6 +12,7 @@ LL | /     let b = x.borrow();
 LL | |     baz().await
 LL | | }
    | |_^
+   = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
 
 error: this `RefCell` reference is held across an `await` point
   --> $DIR/await_holding_refcell_ref.rs:11:9
diff --git a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
index 537557f8b0a..e83eb4d605a 100644
--- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
+++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
@@ -4,8 +4,8 @@ error: restriction lints are not meant to be all enabled
 LL | #![warn(clippy::restriction)]
    |         ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
    = help: try enabling only the lints you really need
+   = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
 
 error: restriction lints are not meant to be all enabled
   --> $DIR/blanket_clippy_restriction_lints.rs:5:9
diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
index e695440f668..4cb5531bef6 100644
--- a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
+++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr
@@ -8,8 +8,8 @@ LL | |         0
 LL | |     };
    | |_____^ help: replace with from: `i32::from(a)`
    |
-   = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`
    = note: `a as i32` or `a.into()` can also be valid options
+   = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`
 
 error: boolean to int conversion using if
   --> $DIR/bool_to_int_with_if.rs:20:5
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr
index 654a1ee7df6..b0cab977a03 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr
@@ -4,8 +4,8 @@ error: a `const` item with interior mutability should not be borrowed
 LL |     let _ = &UNFROZEN_VARIANT; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
    = help: assign this const to a local or static variable, and use the variable here
+   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
 
 error: a `const` item with interior mutability should not be borrowed
   --> $DIR/enums.rs:37:18
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr
index 9a908cf30e9..c87ad206c2a 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr
@@ -4,8 +4,8 @@ error: a `const` item with interior mutability should not be borrowed
 LL |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^
    |
-   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
    = help: assign this const to a local or static variable, and use the variable here
+   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
 
 error: a `const` item with interior mutability should not be borrowed
   --> $DIR/others.rs:55:16
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr
index 8f26403abd3..f34ae8814c3 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr
@@ -4,8 +4,8 @@ error: a `const` item with interior mutability should not be borrowed
 LL |         let _ = &Self::ATOMIC; //~ ERROR interior mutable
    |                  ^^^^^^^^^^^^
    |
-   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
    = help: assign this const to a local or static variable, and use the variable here
+   = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings`
 
 error: a `const` item with interior mutability should not be borrowed
   --> $DIR/traits.rs:26:18
diff --git a/src/tools/clippy/tests/ui/box_collection.stderr b/src/tools/clippy/tests/ui/box_collection.stderr
index 2b28598ded9..40b6f9be61d 100644
--- a/src/tools/clippy/tests/ui/box_collection.stderr
+++ b/src/tools/clippy/tests/ui/box_collection.stderr
@@ -4,8 +4,8 @@ error: you seem to be trying to use `Box<Vec<..>>`. Consider using just `Vec<..>
 LL | fn test1(foo: Box<Vec<bool>>) {}
    |               ^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::box-collection` implied by `-D warnings`
    = help: `Vec<..>` is already on the heap, `Box<Vec<..>>` makes an extra allocation
+   = note: `-D clippy::box-collection` implied by `-D warnings`
 
 error: you seem to be trying to use `Box<String>`. Consider using just `String`
   --> $DIR/box_collection.rs:28:15
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
index 5e1a68d216e..b919812e098 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr
@@ -7,12 +7,12 @@ LL | |         result
 LL | |     };
    | |_____^
    |
+   = note: the end suggestion probably needs some adjustments to use the expression result correctly
 note: the lint level is defined here
   --> $DIR/shared_at_bottom.rs:2:36
    |
 LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the end suggestion probably needs some adjustments to use the expression result correctly
 help: consider moving these statements after the if
    |
 LL ~     }
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr
index d890b12ecbb..fb3da641fb5 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr
@@ -103,11 +103,6 @@ LL | |         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
 LL | |     } else {
    | |_____^
    |
-note: the lint level is defined here
-  --> $DIR/shared_at_top.rs:2:9
-   |
-LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: same as this
   --> $DIR/shared_at_top.rs:98:12
    |
@@ -116,6 +111,11 @@ LL |       } else {
 LL | |         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
 LL | |     }
    | |_____^
+note: the lint level is defined here
+  --> $DIR/shared_at_top.rs:2:9
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
index a270f637f2b..3edb8e53a7d 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr
@@ -7,17 +7,17 @@ LL | |         let _overlap_start = t * 2;
 LL | |         let _overlap_end = 2 * t;
    | |_________________________________^
    |
-note: the lint level is defined here
-  --> $DIR/shared_at_top_and_bottom.rs:2:36
-   |
-LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: this code is shared at the end
   --> $DIR/shared_at_top_and_bottom.rs:28:5
    |
 LL | /         let _u = 9;
 LL | |     }
    | |_____^
+note: the lint level is defined here
+  --> $DIR/shared_at_top_and_bottom.rs:2:36
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider moving these statements before the if
    |
 LL ~     let t = 7;
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr
index a815995e717..d2acd6d9735 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr
@@ -6,11 +6,6 @@ LL |       if false {
 LL | |     } else {
    | |_____^
    |
-note: the lint level is defined here
-  --> $DIR/valid_if_blocks.rs:2:9
-   |
-LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: same as this
   --> $DIR/valid_if_blocks.rs:105:12
    |
@@ -18,6 +13,11 @@ LL |       } else {
    |  ____________^
 LL | |     }
    | |_____^
+note: the lint level is defined here
+  --> $DIR/valid_if_blocks.rs:2:9
+   |
+LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `if` has identical blocks
   --> $DIR/valid_if_blocks.rs:115:15
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
index 5d9a043edb9..a28dd8bd5ad 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
@@ -4,8 +4,8 @@ error: case-sensitive file extension comparison
 LL |     filename.ends_with(".rs")
    |              ^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::case-sensitive-file-extension-comparisons` implied by `-D warnings`
    = help: consider using a case-insensitive comparison instead
+   = note: `-D clippy::case-sensitive-file-extension-comparisons` implied by `-D warnings`
 
 error: case-sensitive file extension comparison
   --> $DIR/case_sensitive_file_extension_comparisons.rs:17:27
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr
index b9836d2f255..39fc9d6dda6 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr
@@ -4,8 +4,8 @@ error: casting a character literal to `u8` truncates
 LL |     let _ = '❤' as u8; // no suggestion, since a byte literal won't work.
    |             ^^^^^^^^^
    |
-   = note: `-D clippy::char-lit-as-u8` implied by `-D warnings`
    = note: `char` is four bytes wide, but `u8` is a single byte
+   = note: `-D clippy::char-lit-as-u8` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr
index bf7cb1607b4..586174c5088 100644
--- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr
+++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr
@@ -4,8 +4,8 @@ error: casting a character literal to `u8` truncates
 LL |     let _ = 'a' as u8;
    |             ^^^^^^^^^ help: use a byte literal instead: `b'a'`
    |
-   = note: `-D clippy::char-lit-as-u8` implied by `-D warnings`
    = note: `char` is four bytes wide, but `u8` is a single byte
+   = note: `-D clippy::char-lit-as-u8` implied by `-D warnings`
 
 error: casting a character literal to `u8` truncates
   --> $DIR/char_lit_as_u8_suggestions.rs:7:13
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr
index 46c6f69708e..d44d5072e48 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr
@@ -6,12 +6,12 @@ LL |     if x.is_ok() && y.is_err() {
 LL |         x.unwrap(); // unnecessary
    |         ^^^^^^^^^^
    |
+   = help: try using `if let` or `match`
 note: the lint level is defined here
   --> $DIR/complex_conditionals.rs:1:35
    |
 LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: try using `if let` or `match`
 
 error: this call to `unwrap_err()` will always panic
   --> $DIR/complex_conditionals.rs:9:9
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity.stderr b/src/tools/clippy/tests/ui/cognitive_complexity.stderr
index a0ddc673abc..d7f2f24e52f 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity.stderr
+++ b/src/tools/clippy/tests/ui/cognitive_complexity.stderr
@@ -4,8 +4,8 @@ error: the function has a cognitive complexity of (28/25)
 LL | fn main() {
    |    ^^^^
    |
-   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
    = help: you could split it up into multiple smaller functions
+   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
 
 error: the function has a cognitive complexity of (7/1)
   --> $DIR/cognitive_complexity.rs:91:4
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr
index f5ff53dda60..bb48f329748 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr
+++ b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr
@@ -4,8 +4,8 @@ error: the function has a cognitive complexity of (3/0)
 LL | fn kaboom() {
    |    ^^^^^^
    |
-   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
    = help: you could split it up into multiple smaller functions
+   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr
index 5f18b693502..33562e8401c 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match.stderr
@@ -8,7 +8,6 @@ LL | |             _ => return,
 LL | |         },
    | |_________^
    |
-   = note: `-D clippy::collapsible-match` implied by `-D warnings`
 help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match.rs:12:12
    |
@@ -16,6 +15,7 @@ LL |         Ok(val) => match val {
    |            ^^^ replace this binding
 LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
+   = note: `-D clippy::collapsible-match` implied by `-D warnings`
 
 error: this `match` can be collapsed into the outer `match`
   --> $DIR/collapsible_match.rs:21:20
diff --git a/src/tools/clippy/tests/ui/collapsible_match2.stderr b/src/tools/clippy/tests/ui/collapsible_match2.stderr
index fe64e469379..144dbe40a7a 100644
--- a/src/tools/clippy/tests/ui/collapsible_match2.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match2.stderr
@@ -8,7 +8,6 @@ LL | |                 _ => return,
 LL | |             },
    | |_____________^
    |
-   = note: `-D clippy::collapsible-match` implied by `-D warnings`
 help: the outer pattern can be modified to include the inner pattern
   --> $DIR/collapsible_match2.rs:13:16
    |
@@ -16,6 +15,7 @@ LL |             Ok(val) if make() => match val {
    |                ^^^ replace this binding
 LL |                 Some(n) => foo(n),
    |                 ^^^^^^^ with this pattern
+   = note: `-D clippy::collapsible-match` implied by `-D warnings`
 
 error: this `match` can be collapsed into the outer `match`
   --> $DIR/collapsible_match2.rs:20:24
diff --git a/src/tools/clippy/tests/ui/comparison_chain.stderr b/src/tools/clippy/tests/ui/comparison_chain.stderr
index be25a80dde0..2eeb50202cd 100644
--- a/src/tools/clippy/tests/ui/comparison_chain.stderr
+++ b/src/tools/clippy/tests/ui/comparison_chain.stderr
@@ -8,8 +8,8 @@ LL | |         b()
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::comparison-chain` implied by `-D warnings`
    = help: consider rewriting the `if` chain to use `cmp` and `match`
+   = note: `-D clippy::comparison-chain` implied by `-D warnings`
 
 error: `if` chain can be rewritten with `match`
   --> $DIR/comparison_chain.rs:27:5
diff --git a/src/tools/clippy/tests/ui/copy_iterator.stderr b/src/tools/clippy/tests/ui/copy_iterator.stderr
index f8ce6af7961..6bc6fd6b6fa 100644
--- a/src/tools/clippy/tests/ui/copy_iterator.stderr
+++ b/src/tools/clippy/tests/ui/copy_iterator.stderr
@@ -10,8 +10,8 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = note: `-D clippy::copy-iterator` implied by `-D warnings`
    = note: consider implementing `IntoIterator` instead
+   = note: `-D clippy::copy-iterator` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-360.stderr b/src/tools/clippy/tests/ui/crashes/ice-360.stderr
index 0eb7bb12b35..a2e2ab8fd19 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-360.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-360.stderr
@@ -18,8 +18,8 @@ error: empty `loop {}` wastes CPU cycles
 LL |         loop {}
    |         ^^^^^^^
    |
-   = note: `-D clippy::empty-loop` implied by `-D warnings`
    = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body
+   = note: `-D clippy::empty-loop` implied by `-D warnings`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr
index f37ab2e9b0c..22d82a30c6a 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr
@@ -4,9 +4,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit
 LL |         FOO_REF_REF => {},
    |         ^^^^^^^^^^^
    |
-   = note: `-D indirect-structural-match` implied by `-D warnings`
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: `-D indirect-structural-match` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
index 1a33e647588..1d8314e889f 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
@@ -4,8 +4,8 @@ error: unsafe block missing a safety comment
 LL |     unsafe { 0 };
    |     ^^^^^^^^^^^^
    |
-   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
    = help: consider adding a safety comment on the preceding line
+   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
index 4fa9fb27e76..35d1e8fd295 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr
@@ -8,8 +8,8 @@ LL | |     TyöValmis,
 LL | | }
    | |_^
    |
-   = note: `-D clippy::enum-variant-names` implied by `-D warnings`
    = help: remove the prefixes and use full paths to the variants instead of glob imports
+   = note: `-D clippy::enum-variant-names` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr
index 7daa08aeb6c..b0ce306d683 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr
@@ -22,8 +22,8 @@ error: literal out of range for `u32`
 LL |     let _y = 1u32 >> 10000000000000u32;
    |                      ^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(overflowing_literals)]` on by default
    = note: the literal `10000000000000u32` does not fit into the type `u32` whose range is `0..=4294967295`
+   = note: `#[deny(overflowing_literals)]` on by default
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr
index 459cf12a1c2..3d79a115cb3 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr
+++ b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr
@@ -4,8 +4,8 @@ error: recursing into entrypoint `a`
 LL |     a();
    |     ^
    |
-   = note: `-D clippy::main-recursion` implied by `-D warnings`
    = help: consider using another function for this recursion
+   = note: `-D clippy::main-recursion` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
index 48152d8ad77..7d8ea3f76b0 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr
@@ -5,8 +5,8 @@ LL | /     a = b;
 LL | |     b = a;
    | |_________^ help: try: `core::mem::swap(&mut a, &mut b)`
    |
-   = note: `-D clippy::almost-swapped` implied by `-D warnings`
    = note: or maybe you should use `core::mem::replace`?
+   = note: `-D clippy::almost-swapped` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr
index 0a260f9d230..82c68bd1cfe 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr
+++ b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr
@@ -4,8 +4,8 @@ error: recursing into entrypoint `main`
 LL |     main();
    |     ^^^^
    |
-   = note: `-D clippy::main-recursion` implied by `-D warnings`
    = help: consider using another function for this recursion
+   = note: `-D clippy::main-recursion` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr
index 6210d7c6cfd..f8fc17e872b 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.stderr
+++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr
@@ -4,8 +4,8 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutab
 LL |     pub fn as_ref(self) -> &'static str {
    |                   ^^^^
    |
-   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
    = help: consider choosing a less ambiguous name
+   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/default_union_representation.stderr b/src/tools/clippy/tests/ui/default_union_representation.stderr
index 138884af868..8b7ed94cbc6 100644
--- a/src/tools/clippy/tests/ui/default_union_representation.stderr
+++ b/src/tools/clippy/tests/ui/default_union_representation.stderr
@@ -7,8 +7,8 @@ LL | |     b: u32,
 LL | | }
    | |_^
    |
-   = note: `-D clippy::default-union-representation` implied by `-D warnings`
    = help: consider annotating `NoAttribute` with `#[repr(C)]` to explicitly specify memory layout
+   = note: `-D clippy::default-union-representation` implied by `-D warnings`
 
 error: this union has the default representation
   --> $DIR/default_union_representation.rs:16:1
diff --git a/src/tools/clippy/tests/ui/derive.stderr b/src/tools/clippy/tests/ui/derive.stderr
index 82a70ceecc3..e1fbb8dcd1e 100644
--- a/src/tools/clippy/tests/ui/derive.stderr
+++ b/src/tools/clippy/tests/ui/derive.stderr
@@ -8,7 +8,6 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings`
 note: consider deriving `Clone` or removing `Copy`
   --> $DIR/derive.rs:8:1
    |
@@ -18,6 +17,7 @@ LL | |         Qux
 LL | |     }
 LL | | }
    | |_^
+   = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings`
 
 error: you are implementing `Clone` explicitly on a `Copy` type
   --> $DIR/derive.rs:32:1
diff --git a/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr b/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr
index 2a4abb0c519..16c92397804 100644
--- a/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr
+++ b/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr
@@ -4,12 +4,12 @@ error: you are deriving `Hash` but have implemented `PartialEq` explicitly
 LL | #[derive(Hash)]
    |          ^^^^
    |
-   = note: `#[deny(clippy::derive_hash_xor_eq)]` on by default
 note: `PartialEq` implemented here
   --> $DIR/derive_hash_xor_eq.rs:15:1
    |
 LL | impl PartialEq for Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(clippy::derive_hash_xor_eq)]` on by default
    = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: you are deriving `Hash` but have implemented `PartialEq` explicitly
diff --git a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr
index baf8341aba9..58efbb8541f 100644
--- a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr
+++ b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr
@@ -4,12 +4,12 @@ error: you are deriving `Ord` but have implemented `PartialOrd` explicitly
 LL | #[derive(Ord, PartialEq, Eq)]
    |          ^^^
    |
-   = note: `-D clippy::derive-ord-xor-partial-ord` implied by `-D warnings`
 note: `PartialOrd` implemented here
   --> $DIR/derive_ord_xor_partial_ord.rs:24:1
    |
 LL | impl PartialOrd for DeriveOrd {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::derive-ord-xor-partial-ord` implied by `-D warnings`
    = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: you are deriving `Ord` but have implemented `PartialOrd` explicitly
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
index a462b98871a..f2ac6bc3269 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
@@ -7,8 +7,8 @@ LL | | /// Because of the initial `unbalanced_tick` pair, the error message is
 LL | | /// very `confusing_and_misleading`.
    | |____________________________________^
    |
-   = note: `-D clippy::doc-markdown` implied by `-D warnings`
    = help: a backtick may be missing a pair
+   = note: `-D clippy::doc-markdown` implied by `-D warnings`
 
 error: backticks are unbalanced
   --> $DIR/unbalanced_ticks.rs:13:1
diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr
index 8290ece1cad..3d34557a881 100644
--- a/src/tools/clippy/tests/ui/double_must_use.stderr
+++ b/src/tools/clippy/tests/ui/double_must_use.stderr
@@ -4,8 +4,8 @@ error: this function has an empty `#[must_use]` attribute, but returns a type al
 LL | pub fn must_use_result() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::double-must-use` implied by `-D warnings`
    = help: either add some descriptive text or remove the attribute
+   = note: `-D clippy::double-must-use` implied by `-D warnings`
 
 error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
   --> $DIR/double_must_use.rs:10:1
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
index 88228afae89..21adb3b3a50 100644
--- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr
+++ b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
@@ -4,12 +4,12 @@ error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a
 LL |     drop(s1);
    |     ^^^^^^^^
    |
-   = note: `-D clippy::drop-copy` implied by `-D warnings`
 note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:33:10
    |
 LL |     drop(s1);
    |          ^^
+   = note: `-D clippy::drop-copy` implied by `-D warnings`
 
 error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
   --> $DIR/drop_forget_copy.rs:34:5
@@ -41,12 +41,12 @@ error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetti
 LL |     forget(s1);
    |     ^^^^^^^^^^
    |
-   = note: `-D clippy::forget-copy` implied by `-D warnings`
 note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:39:12
    |
 LL |     forget(s1);
    |            ^^
+   = note: `-D clippy::forget-copy` implied by `-D warnings`
 
 error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
   --> $DIR/drop_forget_copy.rs:40:5
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.stderr b/src/tools/clippy/tests/ui/drop_non_drop.stderr
index 30121033de7..b86057c0c32 100644
--- a/src/tools/clippy/tests/ui/drop_non_drop.stderr
+++ b/src/tools/clippy/tests/ui/drop_non_drop.stderr
@@ -4,12 +4,12 @@ error: call to `std::mem::drop` with a value that does not implement `Drop`. Dro
 LL |     drop(Foo);
    |     ^^^^^^^^^
    |
-   = note: `-D clippy::drop-non-drop` implied by `-D warnings`
 note: argument has type `main::Foo`
   --> $DIR/drop_non_drop.rs:22:10
    |
 LL |     drop(Foo);
    |          ^^^
+   = note: `-D clippy::drop-non-drop` implied by `-D warnings`
 
 error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes
   --> $DIR/drop_non_drop.rs:37:5
diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr
index 531849f0680..4743cf79b5d 100644
--- a/src/tools/clippy/tests/ui/drop_ref.stderr
+++ b/src/tools/clippy/tests/ui/drop_ref.stderr
@@ -4,12 +4,12 @@ error: calls to `std::mem::drop` with a reference instead of an owned value. Dro
 LL |     drop(&SomeStruct);
    |     ^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::drop-ref` implied by `-D warnings`
 note: argument has type `&SomeStruct`
   --> $DIR/drop_ref.rs:11:10
    |
 LL |     drop(&SomeStruct);
    |          ^^^^^^^^^^^
+   = note: `-D clippy::drop-ref` implied by `-D warnings`
 
 error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
   --> $DIR/drop_ref.rs:14:5
diff --git a/src/tools/clippy/tests/ui/else_if_without_else.stderr b/src/tools/clippy/tests/ui/else_if_without_else.stderr
index 6f47658cfb1..90ccfb4fad6 100644
--- a/src/tools/clippy/tests/ui/else_if_without_else.stderr
+++ b/src/tools/clippy/tests/ui/else_if_without_else.stderr
@@ -8,8 +8,8 @@ LL | |         println!("else if");
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::else-if-without-else` implied by `-D warnings`
    = help: add an `else` block here
+   = note: `-D clippy::else-if-without-else` implied by `-D warnings`
 
 error: `if` expression with an `else if`, but without a final `else`
   --> $DIR/else_if_without_else.rs:54:12
diff --git a/src/tools/clippy/tests/ui/empty_enum.stderr b/src/tools/clippy/tests/ui/empty_enum.stderr
index 7125e5f602b..0d9aa5818e2 100644
--- a/src/tools/clippy/tests/ui/empty_enum.stderr
+++ b/src/tools/clippy/tests/ui/empty_enum.stderr
@@ -4,8 +4,8 @@ error: enum with no variants
 LL | enum Empty {}
    | ^^^^^^^^^^^^^
    |
-   = note: `-D clippy::empty-enum` implied by `-D warnings`
    = help: consider using the uninhabited type `!` (never type) or a wrapper around it to introduce a type which can't be instantiated
+   = note: `-D clippy::empty-enum` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/empty_loop.stderr b/src/tools/clippy/tests/ui/empty_loop.stderr
index 555f3d3d884..7602412334b 100644
--- a/src/tools/clippy/tests/ui/empty_loop.stderr
+++ b/src/tools/clippy/tests/ui/empty_loop.stderr
@@ -4,8 +4,8 @@ error: empty `loop {}` wastes CPU cycles
 LL |     loop {}
    |     ^^^^^^^
    |
-   = note: `-D clippy::empty-loop` implied by `-D warnings`
    = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body
+   = note: `-D clippy::empty-loop` implied by `-D warnings`
 
 error: empty `loop {}` wastes CPU cycles
   --> $DIR/empty_loop.rs:11:9
diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
index 5ded35a6f0d..71af64f49d5 100644
--- a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
+++ b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr
@@ -4,8 +4,8 @@ error: empty `loop {}` wastes CPU cycles
 LL |     loop {}
    |     ^^^^^^^
    |
-   = note: `-D clippy::empty-loop` implied by `-D warnings`
    = help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body
+   = note: `-D clippy::empty-loop` implied by `-D warnings`
 
 error: empty `loop {}` wastes CPU cycles
   --> $DIR/empty_loop_no_std.rs:25:5
diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr
index 904c0904645..f6738865cac 100644
--- a/src/tools/clippy/tests/ui/expect.stderr
+++ b/src/tools/clippy/tests/ui/expect.stderr
@@ -4,8 +4,8 @@ error: used `expect()` on `an Option` value
 LL |     let _ = opt.expect("");
    |             ^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::expect-used` implied by `-D warnings`
    = help: if this value is `None`, it will panic
+   = note: `-D clippy::expect-used` implied by `-D warnings`
 
 error: used `expect()` on `a Result` value
   --> $DIR/expect.rs:10:13
diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.stderr b/src/tools/clippy/tests/ui/fallible_impl_from.stderr
index d637dbce5d7..28a061af664 100644
--- a/src/tools/clippy/tests/ui/fallible_impl_from.stderr
+++ b/src/tools/clippy/tests/ui/fallible_impl_from.stderr
@@ -8,17 +8,17 @@ LL | |     }
 LL | | }
    | |_^
    |
-note: the lint level is defined here
-  --> $DIR/fallible_impl_from.rs:1:9
-   |
-LL | #![deny(clippy::fallible_impl_from)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail
 note: potential failure(s)
   --> $DIR/fallible_impl_from.rs:7:13
    |
 LL |         Foo(s.parse().unwrap())
    |             ^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/fallible_impl_from.rs:1:9
+   |
+LL | #![deny(clippy::fallible_impl_from)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: consider implementing `TryFrom` instead
   --> $DIR/fallible_impl_from.rs:26:1
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
index 3ce4b91a548..710bb66a48a 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
@@ -4,12 +4,12 @@ error: field assignment outside of initializer for an instance created with Defa
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
-   = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
   --> $DIR/field_reassign_with_default.rs:62:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
 
 error: field assignment outside of initializer for an instance created with Default::default()
   --> $DIR/field_reassign_with_default.rs:103:5
diff --git a/src/tools/clippy/tests/ui/filetype_is_file.stderr b/src/tools/clippy/tests/ui/filetype_is_file.stderr
index cd1e3ac37fe..e51a90d6cfd 100644
--- a/src/tools/clippy/tests/ui/filetype_is_file.stderr
+++ b/src/tools/clippy/tests/ui/filetype_is_file.stderr
@@ -4,8 +4,8 @@ error: `FileType::is_file()` only covers regular files
 LL |     if fs::metadata("foo.txt")?.file_type().is_file() {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::filetype-is-file` implied by `-D warnings`
    = help: use `!FileType::is_dir()` instead
+   = note: `-D clippy::filetype-is-file` implied by `-D warnings`
 
 error: `!FileType::is_file()` only denies regular files
   --> $DIR/filetype_is_file.rs:13:8
diff --git a/src/tools/clippy/tests/ui/float_cmp.stderr b/src/tools/clippy/tests/ui/float_cmp.stderr
index 9cc1f1b75ed..e3e9f3949fd 100644
--- a/src/tools/clippy/tests/ui/float_cmp.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp.stderr
@@ -4,8 +4,8 @@ error: strict comparison of `f32` or `f64`
 LL |     ONE as f64 != 2.0;
    |     ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin`
    |
-   = note: `-D clippy::float-cmp` implied by `-D warnings`
    = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
+   = note: `-D clippy::float-cmp` implied by `-D warnings`
 
 error: strict comparison of `f32` or `f64`
   --> $DIR/float_cmp.rs:62:5
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.stderr b/src/tools/clippy/tests/ui/float_cmp_const.stderr
index d8182cf855b..65c45648ab3 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp_const.stderr
@@ -4,8 +4,8 @@ error: strict comparison of `f32` or `f64` constant
 LL |     1f32 == ONE;
    |     ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin`
    |
-   = note: `-D clippy::float-cmp-const` implied by `-D warnings`
    = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
+   = note: `-D clippy::float-cmp-const` implied by `-D warnings`
 
 error: strict comparison of `f32` or `f64` constant
   --> $DIR/float_cmp_const.rs:17:5
diff --git a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
index cd9d07fa115..11627105691 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
@@ -4,8 +4,8 @@ error: more than 3 bools in function parameters
 LL | fn g(_: bool, _: bool, _: bool, _: bool) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
    = help: consider refactoring bools into two-variant enums
+   = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
 
 error: more than 3 bools in function parameters
   --> $DIR/fn_params_excessive_bools.rs:21:1
diff --git a/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr b/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr
index 8c8c022243a..68d2735b040 100644
--- a/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr
+++ b/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr
@@ -4,8 +4,8 @@ error: for loop over `option`, which is an `Option`. This is more readably writt
 LL |     for x in option {
    |              ^^^^^^
    |
-   = note: `-D clippy::for-loops-over-fallibles` implied by `-D warnings`
    = help: consider replacing `for x in option` with `if let Some(x) = option`
+   = note: `-D clippy::for-loops-over-fallibles` implied by `-D warnings`
 
 error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement
   --> $DIR/for_loops_over_fallibles.rs:14:14
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.stderr b/src/tools/clippy/tests/ui/forget_non_drop.stderr
index 03fb00960a4..194e37c8b42 100644
--- a/src/tools/clippy/tests/ui/forget_non_drop.stderr
+++ b/src/tools/clippy/tests/ui/forget_non_drop.stderr
@@ -4,12 +4,12 @@ error: call to `std::mem::forget` with a value that does not implement `Drop`. F
 LL |     forget(Foo);
    |     ^^^^^^^^^^^
    |
-   = note: `-D clippy::forget-non-drop` implied by `-D warnings`
 note: argument has type `main::Foo`
   --> $DIR/forget_non_drop.rs:13:12
    |
 LL |     forget(Foo);
    |            ^^^
+   = note: `-D clippy::forget-non-drop` implied by `-D warnings`
 
 error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it
   --> $DIR/forget_non_drop.rs:24:5
diff --git a/src/tools/clippy/tests/ui/forget_ref.stderr b/src/tools/clippy/tests/ui/forget_ref.stderr
index df5cd8cacdb..011cdefc665 100644
--- a/src/tools/clippy/tests/ui/forget_ref.stderr
+++ b/src/tools/clippy/tests/ui/forget_ref.stderr
@@ -4,12 +4,12 @@ error: calls to `std::mem::forget` with a reference instead of an owned value. F
 LL |     forget(&SomeStruct);
    |     ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::forget-ref` implied by `-D warnings`
 note: argument has type `&SomeStruct`
   --> $DIR/forget_ref.rs:11:12
    |
 LL |     forget(&SomeStruct);
    |            ^^^^^^^^^^^
+   = note: `-D clippy::forget-ref` implied by `-D warnings`
 
 error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
   --> $DIR/forget_ref.rs:14:5
diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.stderr b/src/tools/clippy/tests/ui/format_args_unfixable.stderr
index 4476218ad58..37a6afb1ba7 100644
--- a/src/tools/clippy/tests/ui/format_args_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/format_args_unfixable.stderr
@@ -4,9 +4,9 @@ error: `format!` in `println!` args
 LL |     println!("error: {}", format!("something failed at {}", Location::caller()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::format-in-format-args` implied by `-D warnings`
    = help: combine the `format!(..)` arguments with the outer `println!(..)` call
    = help: or consider changing `format!` to `format_args!`
+   = note: `-D clippy::format-in-format-args` implied by `-D warnings`
 
 error: `format!` in `println!` args
   --> $DIR/format_args_unfixable.rs:28:5
diff --git a/src/tools/clippy/tests/ui/format_push_string.stderr b/src/tools/clippy/tests/ui/format_push_string.stderr
index 953784bcc06..d7be9a5f206 100644
--- a/src/tools/clippy/tests/ui/format_push_string.stderr
+++ b/src/tools/clippy/tests/ui/format_push_string.stderr
@@ -4,8 +4,8 @@ error: `format!(..)` appended to existing `String`
 LL |     string += &format!("{:?}", 1234);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::format-push-string` implied by `-D warnings`
    = help: consider using `write!` to avoid the extra allocation
+   = note: `-D clippy::format-push-string` implied by `-D warnings`
 
 error: `format!(..)` appended to existing `String`
   --> $DIR/format_push_string.rs:6:5
diff --git a/src/tools/clippy/tests/ui/formatting.stderr b/src/tools/clippy/tests/ui/formatting.stderr
index 9272cd60484..caccd5cba17 100644
--- a/src/tools/clippy/tests/ui/formatting.stderr
+++ b/src/tools/clippy/tests/ui/formatting.stderr
@@ -4,8 +4,8 @@ error: this looks like you are trying to use `.. -= ..`, but you really are doin
 LL |     a =- 35;
    |      ^^^^
    |
-   = note: `-D clippy::suspicious-assignment-formatting` implied by `-D warnings`
    = note: to remove this lint, use either `-=` or `= -`
+   = note: `-D clippy::suspicious-assignment-formatting` implied by `-D warnings`
 
 error: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)`
   --> $DIR/formatting.rs:17:6
@@ -29,8 +29,8 @@ error: possibly missing a comma here
 LL |         -1, -2, -3 // <= no comma here
    |                   ^
    |
-   = note: `-D clippy::possible-missing-comma` implied by `-D warnings`
    = note: to remove this lint, add a comma or write the expr in a single line
+   = note: `-D clippy::possible-missing-comma` implied by `-D warnings`
 
 error: possibly missing a comma here
   --> $DIR/formatting.rs:33:19
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index 2951e6bdac4..469adadd219 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -4,8 +4,8 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for
 LL | impl Into<StringWrapper> for String {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::from-over-into` implied by `-D warnings`
    = help: consider to implement `From<std::string::String>` instead
+   = note: `-D clippy::from-over-into` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr
index a9f2ad36d0a..5b6858e4568 100644
--- a/src/tools/clippy/tests/ui/future_not_send.stderr
+++ b/src/tools/clippy/tests/ui/future_not_send.stderr
@@ -4,7 +4,6 @@ error: future cannot be sent between threads safely
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                                              ^^^^ future returned by `private_future` is not `Send`
    |
-   = note: `-D clippy::future-not-send` implied by `-D warnings`
 note: future is not `Send` as this value is used across an await
   --> $DIR/future_not_send.rs:8:19
    |
@@ -25,6 +24,7 @@ LL |     async { true }.await
 LL | }
    | - `cell` is later dropped here
    = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
+   = note: `-D clippy::future-not-send` implied by `-D warnings`
 
 error: future cannot be sent between threads safely
   --> $DIR/future_not_send.rs:11:42
diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr
index ea8fec52735..937f8590408 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/get_unwrap.stderr
@@ -16,8 +16,8 @@ error: used `unwrap()` on `an Option` value
 LL |         let _ = boxed_slice.get(1).unwrap();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::unwrap-used` implied by `-D warnings`
    = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
+   = note: `-D clippy::unwrap-used` implied by `-D warnings`
 
 error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
   --> $DIR/get_unwrap.rs:36:17
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.stderr
index 8a4d5dbac59..da0cc25f0ab 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.stderr
+++ b/src/tools/clippy/tests/ui/if_let_mutex.stderr
@@ -13,8 +13,8 @@ LL | |         do_stuff(lock);
 LL | |     };
    | |_____^
    |
-   = note: `-D clippy::if-let-mutex` implied by `-D warnings`
    = help: move the lock call outside of the `if let ...` expression
+   = note: `-D clippy::if-let-mutex` implied by `-D warnings`
 
 error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
   --> $DIR/if_let_mutex.rs:22:5
diff --git a/src/tools/clippy/tests/ui/if_not_else.stderr b/src/tools/clippy/tests/ui/if_not_else.stderr
index 8c8cc44bb03..46671c15274 100644
--- a/src/tools/clippy/tests/ui/if_not_else.stderr
+++ b/src/tools/clippy/tests/ui/if_not_else.stderr
@@ -8,8 +8,8 @@ LL | |         println!("Bunny");
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::if-not-else` implied by `-D warnings`
    = help: remove the `!` and swap the blocks of the `if`/`else`
+   = note: `-D clippy::if-not-else` implied by `-D warnings`
 
 error: unnecessary `!=` operation
   --> $DIR/if_not_else.rs:17:5
diff --git a/src/tools/clippy/tests/ui/if_same_then_else.stderr b/src/tools/clippy/tests/ui/if_same_then_else.stderr
index 2cdf442486a..fb23b81d36d 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else.stderr
@@ -11,7 +11,6 @@ LL | |         foo();
 LL | |     } else {
    | |_____^
    |
-   = note: `-D clippy::if-same-then-else` implied by `-D warnings`
 note: same as this
   --> $DIR/if_same_then_else.rs:31:12
    |
@@ -24,6 +23,7 @@ LL | |         0..10;
 LL | |         foo();
 LL | |     }
    | |_____^
+   = note: `-D clippy::if-same-then-else` implied by `-D warnings`
 
 error: this `if` has identical blocks
   --> $DIR/if_same_then_else.rs:67:21
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
index cac788f859d..704cfd9669a 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
@@ -11,7 +11,6 @@ LL | |         }
 LL | |     } else {
    | |_____^
    |
-   = note: `-D clippy::if-same-then-else` implied by `-D warnings`
 note: same as this
   --> $DIR/if_same_then_else2.rs:23:12
    |
@@ -24,6 +23,7 @@ LL | |             let bar: &Option<_> = &Some::<u8>(42);
 LL | |         }
 LL | |     }
    | |_____^
+   = note: `-D clippy::if-same-then-else` implied by `-D warnings`
 
 error: this `if` has identical blocks
   --> $DIR/if_same_then_else2.rs:35:13
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
index c22ace30d2d..24e0b5947f1 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
@@ -10,8 +10,8 @@ LL | |         None
 LL | |     };
    | |_____^
    |
-   = note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
    = help: consider using `bool::then` like: `foo().then(|| { /* snippet */ "foo" })`
+   = note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
 
 error: this could be simplified with `bool::then`
   --> $DIR/if_then_some_else_none.rs:14:13
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.stderr b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
index 0c8f49b8687..4113087327a 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.stderr
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
@@ -4,12 +4,12 @@ error: this `if` has the same condition as a previous `if`
 LL |     } else if b {
    |               ^
    |
-   = note: `-D clippy::ifs-same-cond` implied by `-D warnings`
 note: same as this
   --> $DIR/ifs_same_cond.rs:8:8
    |
 LL |     if b {
    |        ^
+   = note: `-D clippy::ifs-same-cond` implied by `-D warnings`
 
 error: this `if` has the same condition as a previous `if`
   --> $DIR/ifs_same_cond.rs:14:15
diff --git a/src/tools/clippy/tests/ui/impl.stderr b/src/tools/clippy/tests/ui/impl.stderr
index 8703ecac93e..e28b1bf0cdd 100644
--- a/src/tools/clippy/tests/ui/impl.stderr
+++ b/src/tools/clippy/tests/ui/impl.stderr
@@ -6,7 +6,6 @@ LL | |     fn second() {}
 LL | | }
    | |_^
    |
-   = note: `-D clippy::multiple-inherent-impl` implied by `-D warnings`
 note: first implementation here
   --> $DIR/impl.rs:6:1
    |
@@ -14,6 +13,7 @@ LL | / impl MyStruct {
 LL | |     fn first() {}
 LL | | }
    | |_^
+   = note: `-D clippy::multiple-inherent-impl` implied by `-D warnings`
 
 error: multiple implementations of this structure
   --> $DIR/impl.rs:24:5
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 6ae700753f0..a8d8b38163d 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -16,8 +16,8 @@ error: indexing may panic
 LL |     x[index];
    |     ^^^^^^^^
    |
-   = note: `-D clippy::indexing-slicing` implied by `-D warnings`
    = help: consider using `.get(n)` or `.get_mut(n)` instead
+   = note: `-D clippy::indexing-slicing` implied by `-D warnings`
 
 error: indexing may panic
   --> $DIR/indexing_slicing_index.rs:38:5
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
index f70722b92a5..dc54bd41365 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
@@ -4,8 +4,8 @@ error: slicing may panic
 LL |     &x[index..];
    |      ^^^^^^^^^^
    |
-   = note: `-D clippy::indexing-slicing` implied by `-D warnings`
    = help: consider using `.get(n..)` or .get_mut(n..)` instead
+   = note: `-D clippy::indexing-slicing` implied by `-D warnings`
 
 error: slicing may panic
   --> $DIR/indexing_slicing_slice.rs:13:6
diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.stderr b/src/tools/clippy/tests/ui/inefficient_to_string.stderr
index 1c0490ffa44..914dc92bfb6 100644
--- a/src/tools/clippy/tests/ui/inefficient_to_string.stderr
+++ b/src/tools/clippy/tests/ui/inefficient_to_string.stderr
@@ -4,12 +4,12 @@ error: calling `to_string` on `&&str`
 LL |     let _: String = rrstr.to_string();
    |                     ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstr).to_string()`
    |
+   = help: `&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString`
 note: the lint level is defined here
   --> $DIR/inefficient_to_string.rs:2:9
    |
 LL | #![deny(clippy::inefficient_to_string)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: `&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString`
 
 error: calling `to_string` on `&&&str`
   --> $DIR/inefficient_to_string.rs:12:21
diff --git a/src/tools/clippy/tests/ui/infinite_loop.stderr b/src/tools/clippy/tests/ui/infinite_loop.stderr
index 4ec7d900ade..85258b9d64f 100644
--- a/src/tools/clippy/tests/ui/infinite_loop.stderr
+++ b/src/tools/clippy/tests/ui/infinite_loop.stderr
@@ -4,8 +4,8 @@ error: variables in the condition are not mutated in the loop body
 LL |     while y < 10 {
    |           ^^^^^^
    |
-   = note: `#[deny(clippy::while_immutable_condition)]` on by default
    = note: this may lead to an infinite or to a never running loop
+   = note: `#[deny(clippy::while_immutable_condition)]` on by default
 
 error: variables in the condition are not mutated in the loop body
   --> $DIR/infinite_loop.rs:25:11
diff --git a/src/tools/clippy/tests/ui/inherent_to_string.stderr b/src/tools/clippy/tests/ui/inherent_to_string.stderr
index 4f331f5bec9..443fecae1aa 100644
--- a/src/tools/clippy/tests/ui/inherent_to_string.stderr
+++ b/src/tools/clippy/tests/ui/inherent_to_string.stderr
@@ -6,8 +6,8 @@ LL | |         "A.to_string()".to_string()
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::inherent-to-string` implied by `-D warnings`
    = help: implement trait `Display` for type `A` instead
+   = note: `-D clippy::inherent-to-string` implied by `-D warnings`
 
 error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`
   --> $DIR/inherent_to_string.rs:44:5
@@ -17,12 +17,12 @@ LL | |         "C.to_string()".to_string()
 LL | |     }
    | |_____^
    |
+   = help: remove the inherent method from type `C`
 note: the lint level is defined here
   --> $DIR/inherent_to_string.rs:2:9
    |
 LL | #![deny(clippy::inherent_to_string_shadow_display)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: remove the inherent method from type `C`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/inspect_for_each.stderr b/src/tools/clippy/tests/ui/inspect_for_each.stderr
index 9f976bb7458..67c2d5e53c7 100644
--- a/src/tools/clippy/tests/ui/inspect_for_each.stderr
+++ b/src/tools/clippy/tests/ui/inspect_for_each.stderr
@@ -9,8 +9,8 @@ LL | |         b.push(z);
 LL | |     });
    | |______^
    |
-   = note: `-D clippy::inspect-for-each` implied by `-D warnings`
    = help: move the code from `inspect(..)` to `for_each(..)` and remove the `inspect(..)`
+   = note: `-D clippy::inspect-for-each` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/integer_division.stderr b/src/tools/clippy/tests/ui/integer_division.stderr
index cbb7f881424..ca800127920 100644
--- a/src/tools/clippy/tests/ui/integer_division.stderr
+++ b/src/tools/clippy/tests/ui/integer_division.stderr
@@ -4,8 +4,8 @@ error: integer division
 LL |     let n = 1 / 2;
    |             ^^^^^
    |
-   = note: `-D clippy::integer-division` implied by `-D warnings`
    = help: division of integers may cause loss of precision. consider using floats
+   = note: `-D clippy::integer-division` implied by `-D warnings`
 
 error: integer division
   --> $DIR/integer_division.rs:6:13
diff --git a/src/tools/clippy/tests/ui/issue_4266.stderr b/src/tools/clippy/tests/ui/issue_4266.stderr
index e5042aaa776..240f4bcc38f 100644
--- a/src/tools/clippy/tests/ui/issue_4266.stderr
+++ b/src/tools/clippy/tests/ui/issue_4266.stderr
@@ -18,8 +18,8 @@ error: methods called `new` usually take no `self`
 LL |     pub async fn new(&mut self) -> Self {
    |                      ^^^^^^^^^
    |
-   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
    = help: consider choosing a less ambiguous name
+   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/iter_nth.stderr b/src/tools/clippy/tests/ui/iter_nth.stderr
index d00b2fb672b..a0fe353bcf7 100644
--- a/src/tools/clippy/tests/ui/iter_nth.stderr
+++ b/src/tools/clippy/tests/ui/iter_nth.stderr
@@ -4,8 +4,8 @@ error: called `.iter().nth()` on a Vec
 LL |         let bad_vec = some_vec.iter().nth(3);
    |                       ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::iter-nth` implied by `-D warnings`
    = help: calling `.get()` is both faster and more readable
+   = note: `-D clippy::iter-nth` implied by `-D warnings`
 
 error: called `.iter().nth()` on a slice
   --> $DIR/iter_nth.rs:34:26
diff --git a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr
index 74c327c7483..4062706f942 100644
--- a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr
@@ -4,12 +4,12 @@ error: called `skip(..).next()` on an iterator
 LL |     let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect();
    |                          ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`
    |
-   = note: `-D clippy::iter-skip-next` implied by `-D warnings`
 help: for this change `sp` has to be mutable
   --> $DIR/iter_skip_next_unfixable.rs:8:9
    |
 LL |     let sp = test_string.split('|').map(|s| s.trim());
    |         ^^
+   = note: `-D clippy::iter-skip-next` implied by `-D warnings`
 
 error: called `skip(..).next()` on an iterator
   --> $DIR/iter_skip_next_unfixable.rs:11:29
diff --git a/src/tools/clippy/tests/ui/large_stack_arrays.stderr b/src/tools/clippy/tests/ui/large_stack_arrays.stderr
index 0d91b65b428..c7bf941ad00 100644
--- a/src/tools/clippy/tests/ui/large_stack_arrays.stderr
+++ b/src/tools/clippy/tests/ui/large_stack_arrays.stderr
@@ -4,8 +4,8 @@ error: allocating a local array larger than 512000 bytes
 LL |         [0u32; 20_000_000],
    |         ^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::large-stack-arrays` implied by `-D warnings`
    = help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()`
+   = note: `-D clippy::large-stack-arrays` implied by `-D warnings`
 
 error: allocating a local array larger than 512000 bytes
   --> $DIR/large_stack_arrays.rs:24:9
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.stderr b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
index a1f48f7610b..8e890e2e259 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.stderr
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
@@ -92,8 +92,8 @@ error: this returns a `Result<_, ()>`
 LL |     pub fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::result-unit-err` implied by `-D warnings`
    = help: use a custom `Error` type instead
+   = note: `-D clippy::result-unit-err` implied by `-D warnings`
 
 error: this returns a `Result<_, ()>`
   --> $DIR/len_without_is_empty.rs:240:5
diff --git a/src/tools/clippy/tests/ui/let_if_seq.stderr b/src/tools/clippy/tests/ui/let_if_seq.stderr
index 271ccce681c..f2e0edb6fbc 100644
--- a/src/tools/clippy/tests/ui/let_if_seq.stderr
+++ b/src/tools/clippy/tests/ui/let_if_seq.stderr
@@ -7,8 +7,8 @@ LL | |         foo = 42;
 LL | |     }
    | |_____^ help: it is more idiomatic to write: `let <mut> foo = if f() { 42 } else { 0 };`
    |
-   = note: `-D clippy::useless-let-if-seq` implied by `-D warnings`
    = note: you might not need `mut` at all
+   = note: `-D clippy::useless-let-if-seq` implied by `-D warnings`
 
 error: `if _ { .. } else { .. }` is an expression
   --> $DIR/let_if_seq.rs:71:5
diff --git a/src/tools/clippy/tests/ui/let_underscore_drop.stderr b/src/tools/clippy/tests/ui/let_underscore_drop.stderr
index ee7bbe995f1..324b7cd431d 100644
--- a/src/tools/clippy/tests/ui/let_underscore_drop.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_drop.stderr
@@ -4,8 +4,8 @@ error: non-binding `let` on a type that implements `Drop`
 LL |     let _ = Box::new(());
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::let-underscore-drop` implied by `-D warnings`
    = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
+   = note: `-D clippy::let-underscore-drop` implied by `-D warnings`
 
 error: non-binding `let` on a type that implements `Drop`
   --> $DIR/let_underscore_drop.rs:18:5
diff --git a/src/tools/clippy/tests/ui/let_underscore_lock.stderr b/src/tools/clippy/tests/ui/let_underscore_lock.stderr
index 4365b48fabb..d7779e7b6c4 100644
--- a/src/tools/clippy/tests/ui/let_underscore_lock.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_lock.stderr
@@ -4,8 +4,8 @@ error: non-binding let on a synchronization lock
 LL |     let _ = m.lock();
    |     ^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::let-underscore-lock` implied by `-D warnings`
    = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
+   = note: `-D clippy::let-underscore-lock` implied by `-D warnings`
 
 error: non-binding let on a synchronization lock
   --> $DIR/let_underscore_lock.rs:10:5
diff --git a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
index 5b751ea56de..bae60f2ff9b 100644
--- a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
@@ -4,8 +4,8 @@ error: non-binding let on a result of a `#[must_use]` function
 LL |     let _ = f();
    |     ^^^^^^^^^^^^
    |
-   = note: `-D clippy::let-underscore-must-use` implied by `-D warnings`
    = help: consider explicitly using function result
+   = note: `-D clippy::let-underscore-must-use` implied by `-D warnings`
 
 error: non-binding let on an expression with `#[must_use]` type
   --> $DIR/let_underscore_must_use.rs:68:5
diff --git a/src/tools/clippy/tests/ui/linkedlist.stderr b/src/tools/clippy/tests/ui/linkedlist.stderr
index 51327df1321..c76c9496131 100644
--- a/src/tools/clippy/tests/ui/linkedlist.stderr
+++ b/src/tools/clippy/tests/ui/linkedlist.stderr
@@ -4,8 +4,8 @@ error: you seem to be using a `LinkedList`! Perhaps you meant some other data st
 LL | const C: LinkedList<i32> = LinkedList::new();
    |          ^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::linkedlist` implied by `-D warnings`
    = help: a `VecDeque` might work
+   = note: `-D clippy::linkedlist` implied by `-D warnings`
 
 error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?
   --> $DIR/linkedlist.rs:9:11
diff --git a/src/tools/clippy/tests/ui/manual_find.stderr b/src/tools/clippy/tests/ui/manual_find.stderr
index da0fd4aaef7..ea04bb066e6 100644
--- a/src/tools/clippy/tests/ui/manual_find.stderr
+++ b/src/tools/clippy/tests/ui/manual_find.stderr
@@ -9,8 +9,8 @@ LL | |     }
 LL | |     None
    | |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())`
    |
-   = note: `-D clippy::manual-find` implied by `-D warnings`
    = note: you may need to dereference some variables
+   = note: `-D clippy::manual-find` implied by `-D warnings`
 
 error: manual implementation of `Iterator::find`
   --> $DIR/manual_find.rs:14:5
diff --git a/src/tools/clippy/tests/ui/manual_flatten.stderr b/src/tools/clippy/tests/ui/manual_flatten.stderr
index da053c05668..180a6ff4e9a 100644
--- a/src/tools/clippy/tests/ui/manual_flatten.stderr
+++ b/src/tools/clippy/tests/ui/manual_flatten.stderr
@@ -11,7 +11,6 @@ LL | |         }
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::manual-flatten` implied by `-D warnings`
 help: ...and remove the `if let` statement in the for loop
   --> $DIR/manual_flatten.rs:8:9
    |
@@ -19,6 +18,7 @@ LL | /         if let Some(y) = n {
 LL | |             println!("{}", y);
 LL | |         }
    | |_________^
+   = note: `-D clippy::manual-flatten` implied by `-D warnings`
 
 error: unnecessary `if let` since only the `Ok` variant of the iterator element is used
   --> $DIR/manual_flatten.rs:15:5
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
index 144fe86df55..087f766be70 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
@@ -13,12 +13,12 @@ LL | |     _C,
 LL | | }
    | |_^
    |
-   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
 help: remove this variant
   --> $DIR/manual_non_exhaustive_enum.rs:9:5
    |
 LL |     _C,
    |     ^^
+   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
 
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> $DIR/manual_non_exhaustive_enum.rs:14:1
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
index e0766c17b75..d0bed8e1121 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
@@ -12,12 +12,12 @@ LL | |         _c: (),
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
 help: remove this field
   --> $DIR/manual_non_exhaustive_struct.rs:8:9
    |
 LL |         _c: (),
    |         ^^^^^^
+   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
 
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> $DIR/manual_non_exhaustive_struct.rs:13:5
diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr
index 896edf2ae51..2191ccb85dd 100644
--- a/src/tools/clippy/tests/ui/manual_strip.stderr
+++ b/src/tools/clippy/tests/ui/manual_strip.stderr
@@ -4,12 +4,12 @@ error: stripping a prefix manually
 LL |         str::to_string(&s["ab".len()..]);
    |                        ^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::manual-strip` implied by `-D warnings`
 note: the prefix was tested here
   --> $DIR/manual_strip.rs:6:5
    |
 LL |     if s.starts_with("ab") {
    |     ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::manual-strip` implied by `-D warnings`
 help: try using the `strip_prefix` method
    |
 LL ~     if let Some(<stripped>) = s.strip_prefix("ab") {
diff --git a/src/tools/clippy/tests/ui/map_err.stderr b/src/tools/clippy/tests/ui/map_err.stderr
index c035840521e..d44403a84a5 100644
--- a/src/tools/clippy/tests/ui/map_err.stderr
+++ b/src/tools/clippy/tests/ui/map_err.stderr
@@ -4,8 +4,8 @@ error: `map_err(|_|...` wildcard pattern discards the original error
 LL |     println!("{:?}", x.map_err(|_| Errors::Ignored));
    |                                ^^^
    |
-   = note: `-D clippy::map-err-ignore` implied by `-D warnings`
    = help: consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)
+   = note: `-D clippy::map-err-ignore` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
index b81bb1ecfae..a72becbeb66 100644
--- a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
+++ b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
@@ -4,12 +4,12 @@ error: some ranges overlap
 LL |         0..=10 => println!("0..=10"),
    |         ^^^^^^
    |
-   = note: `-D clippy::match-overlapping-arm` implied by `-D warnings`
 note: overlaps with this
   --> $DIR/match_overlapping_arm.rs:14:9
    |
 LL |         0..=11 => println!("0..=11"),
    |         ^^^^^^
+   = note: `-D clippy::match-overlapping-arm` implied by `-D warnings`
 
 error: some ranges overlap
   --> $DIR/match_overlapping_arm.rs:19:9
diff --git a/src/tools/clippy/tests/ui/match_same_arms.stderr b/src/tools/clippy/tests/ui/match_same_arms.stderr
index b6d04263b37..db85b5964e8 100644
--- a/src/tools/clippy/tests/ui/match_same_arms.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms.stderr
@@ -4,13 +4,13 @@ error: this match arm has an identical body to the `_` wildcard arm
 LL |         Abc::A => 0,
    |         ^^^^^^^^^^^ help: try removing the arm
    |
-   = note: `-D clippy::match-same-arms` implied by `-D warnings`
    = help: or try changing either arm body
 note: `_` wildcard arm here
   --> $DIR/match_same_arms.rs:13:9
    |
 LL |         _ => 0, //~ ERROR match arms have same body
    |         ^^^^^^
+   = note: `-D clippy::match-same-arms` implied by `-D warnings`
 
 error: this match arm has an identical body to another arm
   --> $DIR/match_same_arms.rs:17:9
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.stderr b/src/tools/clippy/tests/ui/match_same_arms2.stderr
index 14a672ba2fe..b260155d218 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms2.stderr
@@ -10,7 +10,6 @@ LL | |             a
 LL | |         },
    | |_________^ help: try removing the arm
    |
-   = note: `-D clippy::match-same-arms` implied by `-D warnings`
    = help: or try changing either arm body
 note: `_` wildcard arm here
   --> $DIR/match_same_arms2.rs:20:9
@@ -23,6 +22,7 @@ LL | |             let mut a = 42 + [23].len() as i32;
 LL | |             a
 LL | |         },
    | |_________^
+   = note: `-D clippy::match-same-arms` implied by `-D warnings`
 
 error: this match arm has an identical body to another arm
   --> $DIR/match_same_arms2.rs:34:9
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
index 2d66daea804..525533bf07b 100644
--- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr
@@ -4,8 +4,8 @@ error: `Err(_)` matches all errors
 LL |         Err(_) => panic!("err"),
    |         ^^^^^^
    |
-   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
    = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
+   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
 
 error: `Err(_)` matches all errors
   --> $DIR/match_wild_err_arm.rs:20:9
diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
index 2d66daea804..525533bf07b 100644
--- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr
@@ -4,8 +4,8 @@ error: `Err(_)` matches all errors
 LL |         Err(_) => panic!("err"),
    |         ^^^^^^
    |
-   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
    = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable
+   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`
 
 error: `Err(_)` matches all errors
   --> $DIR/match_wild_err_arm.rs:20:9
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
index b1c23b539ff..6e749d2741c 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
@@ -4,12 +4,12 @@ error: stripping a prefix manually
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::manual-strip` implied by `-D warnings`
 note: the prefix was tested here
   --> $DIR/min_rust_version_attr.rs:203:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::manual-strip` implied by `-D warnings`
 help: try using the `strip_prefix` method
    |
 LL ~         if let Some(<stripped>) = s.strip_prefix("hello, ") {
diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr b/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr
index 3534b53282f..9822c77c9df 100644
--- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr
+++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr
@@ -6,8 +6,8 @@ LL | #[cfg(linux)]
    |       |
    |       help: try: `target_os = "linux"`
    |
-   = note: `-D clippy::mismatched-target-os` implied by `-D warnings`
    = help: did you mean `unix`?
+   = note: `-D clippy::mismatched-target-os` implied by `-D warnings`
 
 error: operating system used in target family position
   --> $DIR/mismatched_target_os_unix.rs:9:1
diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr b/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr
index cb720256c50..204d4990557 100644
--- a/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr
+++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr
@@ -4,8 +4,8 @@ error: `Foo` has a similarly named generic type parameter `B` in its declaration
 LL |     impl<B, A> Foo<B, A> {}
    |                    ^
    |
-   = note: `-D clippy::mismatching-type-param-order` implied by `-D warnings`
    = help: try `A`, or a name that does not conflict with `Foo`'s generic params
+   = note: `-D clippy::mismatching-type-param-order` implied by `-D warnings`
 
 error: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order
   --> $DIR/mismatching_type_param_order.rs:11:23
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.stderr b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
index 91ebd695238..c9ded7f1ad0 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
@@ -7,12 +7,12 @@ LL | |     result.unwrap()
 LL | | }
    | |_^
    |
-   = note: `-D clippy::missing-panics-doc` implied by `-D warnings`
 note: first possible panic found here
   --> $DIR/missing_panics_doc.rs:8:5
    |
 LL |     result.unwrap()
    |     ^^^^^^^^^^^^^^^
+   = note: `-D clippy::missing-panics-doc` implied by `-D warnings`
 
 error: docs for function which may panic missing `# Panics` section
   --> $DIR/missing_panics_doc.rs:12:1
diff --git a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr
index 2e951cdbcbf..8cc68b0ac7b 100644
--- a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr
+++ b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr
@@ -4,12 +4,12 @@ error: unsequenced read of `x`
 LL |     } + x;
    |         ^
    |
-   = note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings`
 note: whether read occurs before this write depends on evaluation order
   --> $DIR/mixed_read_write_in_expression.rs:12:9
    |
 LL |         x = 1;
    |         ^^^^^
+   = note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings`
 
 error: unsequenced read of `x`
   --> $DIR/mixed_read_write_in_expression.rs:17:5
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr
index 97844aaaa75..36106de31f0 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr
@@ -4,8 +4,8 @@ error: you are using modulo operator on constants with different signs: `-1.600
 LL |     -1.6 % 2.1;
    |     ^^^^^^^^^^
    |
-   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
    = note: double check for expected result especially when interoperating with different languages
+   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
 
 error: you are using modulo operator on constants with different signs: `1.600 % -2.100`
   --> $DIR/modulo_arithmetic_float.rs:7:5
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr
index f71adf5b0d0..9ff676ff6bc 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr
@@ -4,9 +4,9 @@ error: you are using modulo operator on types that might have different signs
 LL |     a % b;
    |     ^^^^^
    |
-   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
    = note: double check for expected result especially when interoperating with different languages
    = note: or consider using `rem_euclid` or similar function
+   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
 
 error: you are using modulo operator on types that might have different signs
   --> $DIR/modulo_arithmetic_integral.rs:9:5
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
index 11b5f77461b..1453d44f488 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
@@ -4,9 +4,9 @@ error: you are using modulo operator on constants with different signs: `-1 % 2`
 LL |     -1 % 2;
    |     ^^^^^^
    |
-   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
    = note: double check for expected result especially when interoperating with different languages
    = note: or consider using `rem_euclid` or similar function
+   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
   --> $DIR/modulo_arithmetic_integral_const.rs:12:5
diff --git a/src/tools/clippy/tests/ui/mut_from_ref.stderr b/src/tools/clippy/tests/ui/mut_from_ref.stderr
index b76d6a13ffb..c20ff54bf94 100644
--- a/src/tools/clippy/tests/ui/mut_from_ref.stderr
+++ b/src/tools/clippy/tests/ui/mut_from_ref.stderr
@@ -4,12 +4,12 @@ error: mutable borrow from immutable input(s)
 LL |     fn this_wont_hurt_a_bit(&self) -> &mut Foo {
    |                                       ^^^^^^^^
    |
-   = note: `-D clippy::mut-from-ref` implied by `-D warnings`
 note: immutable borrow here
   --> $DIR/mut_from_ref.rs:7:29
    |
 LL |     fn this_wont_hurt_a_bit(&self) -> &mut Foo {
    |                             ^^^^^
+   = note: `-D clippy::mut-from-ref` implied by `-D warnings`
 
 error: mutable borrow from immutable input(s)
   --> $DIR/mut_from_ref.rs:13:25
diff --git a/src/tools/clippy/tests/ui/mut_range_bound.stderr b/src/tools/clippy/tests/ui/mut_range_bound.stderr
index 4b5a3fc1e41..e0c8dced382 100644
--- a/src/tools/clippy/tests/ui/mut_range_bound.stderr
+++ b/src/tools/clippy/tests/ui/mut_range_bound.stderr
@@ -4,8 +4,8 @@ error: attempt to mutate range bound within loop
 LL |         m = 5;
    |         ^
    |
-   = note: `-D clippy::mut-range-bound` implied by `-D warnings`
    = note: the range of the loop is unchanged
+   = note: `-D clippy::mut-range-bound` implied by `-D warnings`
 
 error: attempt to mutate range bound within loop
   --> $DIR/mut_range_bound.rs:15:9
diff --git a/src/tools/clippy/tests/ui/needless_continue.stderr b/src/tools/clippy/tests/ui/needless_continue.stderr
index b8657c74caa..005ba010f34 100644
--- a/src/tools/clippy/tests/ui/needless_continue.stderr
+++ b/src/tools/clippy/tests/ui/needless_continue.stderr
@@ -7,7 +7,6 @@ LL | |             continue;
 LL | |         }
    | |_________^
    |
-   = note: `-D clippy::needless-continue` implied by `-D warnings`
    = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block
                    if i % 2 == 0 && i % 3 == 0 {
                        println!("{}", i);
@@ -33,6 +32,7 @@ LL | |         }
                        }
                        println!("bleh");
                    }
+   = note: `-D clippy::needless-continue` implied by `-D warnings`
 
 error: there is no need for an explicit `else` block for this `if` expression
   --> $DIR/needless_continue.rs:44:9
diff --git a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
index b6c904a147a..e912b59a6e7 100644
--- a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
+++ b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
@@ -4,13 +4,13 @@ error: some fields in `RingBuffer<T>` are not safe to be sent to another thread
 LL | unsafe impl<T> Send for RingBuffer<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
 note: it is not safe to send field `data` to another thread
   --> $DIR/non_send_fields_in_send_ty.rs:12:5
    |
 LL |     data: Vec<UnsafeCell<T>>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`
+   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
 
 error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
   --> $DIR/non_send_fields_in_send_ty.rs:25:1
diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr
index 54f5bbb0fc4..295dc1798e3 100644
--- a/src/tools/clippy/tests/ui/octal_escapes.stderr
+++ b/src/tools/clippy/tests/ui/octal_escapes.stderr
@@ -4,8 +4,8 @@ error: octal-looking escape in string literal
 LL |     let _bad1 = "/033[0m";
    |                 ^^^^^^^^^
    |
-   = note: `-D clippy::octal-escapes` implied by `-D warnings`
    = help: octal escapes are not supported, `/0` is always a null character
+   = note: `-D clippy::octal-escapes` implied by `-D warnings`
 help: if an octal escape was intended, use the hexadecimal representation instead
    |
 LL |     let _bad1 = "/x1b[0m";
diff --git a/src/tools/clippy/tests/ui/ok_expect.stderr b/src/tools/clippy/tests/ui/ok_expect.stderr
index b02b28e7f68..6c40adbb53d 100644
--- a/src/tools/clippy/tests/ui/ok_expect.stderr
+++ b/src/tools/clippy/tests/ui/ok_expect.stderr
@@ -4,8 +4,8 @@ error: called `ok().expect()` on a `Result` value
 LL |     res.ok().expect("disaster!");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::ok-expect` implied by `-D warnings`
    = help: you can call `expect()` directly on the `Result`
+   = note: `-D clippy::ok-expect` implied by `-D warnings`
 
 error: called `ok().expect()` on a `Result` value
   --> $DIR/ok_expect.rs:20:5
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
index 74057ddcfda..571e5c4b5fa 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr
@@ -4,12 +4,12 @@ error: parameter is only used in recursion
 LL | fn _one_unused(flag: u32, a: usize) -> usize {
    |                           ^ help: if this is intentional, prefix it with an underscore: `_a`
    |
-   = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
 note: parameter used here
   --> $DIR/only_used_in_recursion.rs:12:53
    |
 LL |     if flag == 0 { 0 } else { _one_unused(flag - 1, a) }
    |                                                     ^
+   = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
 
 error: parameter is only used in recursion
   --> $DIR/only_used_in_recursion.rs:15:27
diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
index 23f6ffd30c9..8dcbfdd612e 100644
--- a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
+++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr
@@ -4,12 +4,12 @@ error: parameter is only used in recursion
 LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
    |                                   ^ help: if this is intentional, prefix it with an underscore: `_b`
    |
-   = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
 note: parameter used here
   --> $DIR/only_used_in_recursion2.rs:9:52
    |
 LL |     if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }
    |                                                    ^
+   = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
 
 error: parameter is only used in recursion
   --> $DIR/only_used_in_recursion2.rs:4:25
diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.stderr b/src/tools/clippy/tests/ui/option_env_unwrap.stderr
index 885ac096cc8..bc188a07e9e 100644
--- a/src/tools/clippy/tests/ui/option_env_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/option_env_unwrap.stderr
@@ -4,8 +4,8 @@ error: this will panic at run-time if the environment variable doesn't exist at
 LL |     let _ = option_env!("PATH").unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::option-env-unwrap` implied by `-D warnings`
    = help: consider using the `env!` macro instead
+   = note: `-D clippy::option-env-unwrap` implied by `-D warnings`
 
 error: this will panic at run-time if the environment variable doesn't exist at compile-time
   --> $DIR/option_env_unwrap.rs:19:13
diff --git a/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
index 158cae8b8f3..e989f2ece30 100644
--- a/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
+++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr
@@ -4,12 +4,12 @@ error: this boolean expression contains a logic bug
 LL |     let _ = a && b || a;
    |             ^^^^^^^^^^^ help: it would look like the following: `a`
    |
-   = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings`
 help: this expression can be optimized out by applying boolean operations to the outer expression
   --> $DIR/overly_complex_bool_expr.rs:11:18
    |
 LL |     let _ = a && b || a;
    |                  ^
+   = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings`
 
 error: this boolean expression contains a logic bug
   --> $DIR/overly_complex_bool_expr.rs:13:13
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
index 561503ae54f..97787bc84e2 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
@@ -7,13 +7,13 @@ LL | |         panic!("error");
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:8:9
    |
 LL |         panic!("error");
    |         ^^^^^^^^^^^^^^^
+   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:11:5
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
index b6aa005e7b5..eb0aacbb6a4 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
@@ -8,13 +8,13 @@ LL | |         Ok(true)
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
    = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn_assertions.rs:9:9
    |
 LL |         assert!(x == 5, "wrong argument");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
 
 error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn_assertions.rs:13:5
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr
index 3421d568365..87fb243b65e 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr
@@ -4,8 +4,8 @@ error: type of pattern does not match the expression type
 LL |         Some(_) => (),
    |         ^^^^^^^
    |
-   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
+   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
 
 error: type of pattern does not match the expression type
   --> $DIR/mutability.rs:15:9
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr
index d285c93782c..a91b5ac6cf7 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr
@@ -4,8 +4,8 @@ error: type of pattern does not match the expression type
 LL |     if let Value::B | Value::A(_) = ref_value {}
    |            ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
+   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
 
 error: type of pattern does not match the expression type
   --> $DIR/pattern_alternatives.rs:16:34
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr
index d428e85b0c9..8bc5c63baab 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr
@@ -4,8 +4,8 @@ error: type of pattern does not match the expression type
 LL |     let Struct { .. } = ref_value;
    |         ^^^^^^^^^^^^^
    |
-   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
+   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
 
 error: type of pattern does not match the expression type
   --> $DIR/pattern_structs.rs:14:33
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr
index edd0074d00d..a1ef540d283 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr
@@ -4,8 +4,8 @@ error: type of pattern does not match the expression type
 LL |     let TupleStruct(_) = ref_value;
    |         ^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
+   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
 
 error: type of pattern does not match the expression type
   --> $DIR/pattern_tuples.rs:12:25
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
index 12b3d3a8bd0..f56a3a89380 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
@@ -4,8 +4,8 @@ error: type of pattern does not match the expression type
 LL |         Some(_) => (),
    |         ^^^^^^^
    |
-   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
+   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`
 
 error: type of pattern does not match the expression type
   --> $DIR/syntax.rs:30:12
diff --git a/src/tools/clippy/tests/ui/proc_macro.stderr b/src/tools/clippy/tests/ui/proc_macro.stderr
index 48fd58c9a49..c795f6ad0d2 100644
--- a/src/tools/clippy/tests/ui/proc_macro.stderr
+++ b/src/tools/clippy/tests/ui/proc_macro.stderr
@@ -4,8 +4,8 @@ error: approximate value of `f{32, 64}::consts::PI` found
 LL |     let _x = 3.14;
    |              ^^^^
    |
-   = note: `#[deny(clippy::approx_constant)]` on by default
    = help: consider using the constant directly
+   = note: `#[deny(clippy::approx_constant)]` on by default
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/pub_use.stderr b/src/tools/clippy/tests/ui/pub_use.stderr
index 9ab710df818..ba4ee732c05 100644
--- a/src/tools/clippy/tests/ui/pub_use.stderr
+++ b/src/tools/clippy/tests/ui/pub_use.stderr
@@ -4,8 +4,8 @@ error: using `pub use`
 LL |     pub use inner::Test;
    |     ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::pub-use` implied by `-D warnings`
    = help: move the exported item to a public module instead
+   = note: `-D clippy::pub-use` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr
index cd7d91e1206..7814f5b5403 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr
@@ -4,8 +4,8 @@ error: initializing a reference-counted pointer in `vec![elem; len]`
 LL |     let v = vec![Arc::new("x".to_string()); 2];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
    = note: each element will point to the same `Arc` instance
+   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
 help: consider initializing each `Arc` element individually
    |
 LL ~     let v = {
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr
index fe861afe054..80deb7cb9f2 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr
@@ -4,8 +4,8 @@ error: initializing a reference-counted pointer in `vec![elem; len]`
 LL |     let v = vec![Rc::new("x".to_string()); 2];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
    = note: each element will point to the same `Rc` instance
+   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
 help: consider initializing each `Rc` element individually
    |
 LL ~     let v = {
diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr
index 4a21946ccdf..789e14a302f 100644
--- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr
+++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr
@@ -4,8 +4,8 @@ error: initializing a reference-counted pointer in `vec![elem; len]`
 LL |     let v = vec![SyncWeak::<u32>::new(); 2];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
    = note: each element will point to the same `Weak` instance
+   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`
 help: consider initializing each `Weak` element individually
    |
 LL ~     let v = {
diff --git a/src/tools/clippy/tests/ui/rc_mutex.stderr b/src/tools/clippy/tests/ui/rc_mutex.stderr
index fe84361d781..cee3bd8b224 100644
--- a/src/tools/clippy/tests/ui/rc_mutex.stderr
+++ b/src/tools/clippy/tests/ui/rc_mutex.stderr
@@ -4,8 +4,8 @@ error: usage of `Rc<Mutex<_>>`
 LL |     foo: Rc<Mutex<i32>>,
    |          ^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::rc-mutex` implied by `-D warnings`
    = help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead
+   = note: `-D clippy::rc-mutex` implied by `-D warnings`
 
 error: usage of `Rc<Mutex<_>>`
   --> $DIR/rc_mutex.rs:26:18
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.stderr b/src/tools/clippy/tests/ui/redundant_allocation.stderr
index 54d4d88dba8..e0826fefa6c 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.stderr
+++ b/src/tools/clippy/tests/ui/redundant_allocation.stderr
@@ -4,9 +4,9 @@ error: usage of `Box<Rc<T>>`
 LL |     pub fn box_test6<T>(foo: Box<Rc<T>>) {}
    |                              ^^^^^^^^^^
    |
-   = note: `-D clippy::redundant-allocation` implied by `-D warnings`
    = note: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation
    = help: consider using just `Box<T>` or `Rc<T>`
+   = note: `-D clippy::redundant-allocation` implied by `-D warnings`
 
 error: usage of `Box<Arc<T>>`
   --> $DIR/redundant_allocation.rs:19:30
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr b/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr
index fdd76ef17a5..8dd4a6a2687 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr
@@ -4,8 +4,8 @@ error: usage of `Box<&T>`
 LL |     pub fn box_test1<T>(foo: Box<&T>) {}
    |                              ^^^^^^^ help: try: `&T`
    |
-   = note: `-D clippy::redundant-allocation` implied by `-D warnings`
    = note: `&T` is already a pointer, `Box<&T>` allocates a pointer on the heap
+   = note: `-D clippy::redundant-allocation` implied by `-D warnings`
 
 error: usage of `Box<&MyStruct>`
   --> $DIR/redundant_allocation_fixable.rs:28:27
diff --git a/src/tools/clippy/tests/ui/redundant_clone.stderr b/src/tools/clippy/tests/ui/redundant_clone.stderr
index aa1dd7cbb45..782590034d0 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.stderr
+++ b/src/tools/clippy/tests/ui/redundant_clone.stderr
@@ -4,12 +4,12 @@ error: redundant clone
 LL |     let _s = ["lorem", "ipsum"].join(" ").to_string();
    |                                          ^^^^^^^^^^^^ help: remove this
    |
-   = note: `-D clippy::redundant-clone` implied by `-D warnings`
 note: this value is dropped without further use
   --> $DIR/redundant_clone.rs:10:14
    |
 LL |     let _s = ["lorem", "ipsum"].join(" ").to_string();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::redundant-clone` implied by `-D warnings`
 
 error: redundant clone
   --> $DIR/redundant_clone.rs:13:15
diff --git a/src/tools/clippy/tests/ui/redundant_else.stderr b/src/tools/clippy/tests/ui/redundant_else.stderr
index 9000cdc814b..de9d00a6024 100644
--- a/src/tools/clippy/tests/ui/redundant_else.stderr
+++ b/src/tools/clippy/tests/ui/redundant_else.stderr
@@ -7,8 +7,8 @@ LL | |             println!("yet don't pull down your hedge.");
 LL | |         }
    | |_________^
    |
-   = note: `-D clippy::redundant-else` implied by `-D warnings`
    = help: remove the `else` block and move the contents out
+   = note: `-D clippy::redundant-else` implied by `-D warnings`
 
 error: redundant else block
   --> $DIR/redundant_else.rs:17:16
diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr
index eb7aa70ee27..23f08103f35 100644
--- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr
@@ -4,9 +4,9 @@ error: redundant pattern matching, consider using `is_ok()`
 LL |     if let Ok(_) = m.lock() {}
    |     -------^^^^^----------- help: try this: `if m.lock().is_ok()`
    |
-   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
    = note: this will change drop order of the result, as well as all temporaries
    = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important
+   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: redundant pattern matching, consider using `is_err()`
   --> $DIR/redundant_pattern_matching_drop_order.rs:13:12
diff --git a/src/tools/clippy/tests/ui/regex.stderr b/src/tools/clippy/tests/ui/regex.stderr
index 1394a9b63bc..2424644c6f6 100644
--- a/src/tools/clippy/tests/ui/regex.stderr
+++ b/src/tools/clippy/tests/ui/regex.stderr
@@ -4,8 +4,8 @@ error: trivial regex
 LL |     let pipe_in_wrong_position = Regex::new("|");
    |                                             ^^^
    |
-   = note: `-D clippy::trivial-regex` implied by `-D warnings`
    = help: the regex is unlikely to be useful as it is
+   = note: `-D clippy::trivial-regex` implied by `-D warnings`
 
 error: trivial regex
   --> $DIR/regex.rs:14:60
diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr
index 57ebd47f8c7..e15633fb1a1 100644
--- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr
+++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr
@@ -4,8 +4,8 @@ error: unnecessary use of `..` pattern in struct binding. All fields were alread
 LL |         A { a: 5, b: 42, c: "", .. } => {}, // Lint
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::rest-pat-in-fully-bound-structs` implied by `-D warnings`
    = help: consider removing `..` from this binding
+   = note: `-D clippy::rest-pat-in-fully-bound-structs` implied by `-D warnings`
 
 error: unnecessary use of `..` pattern in struct binding. All fields were already bound
   --> $DIR/rest_pat_in_fully_bound_structs.rs:23:9
diff --git a/src/tools/clippy/tests/ui/result_large_err.stderr b/src/tools/clippy/tests/ui/result_large_err.stderr
index ef19f2854ab..bea101fe20b 100644
--- a/src/tools/clippy/tests/ui/result_large_err.stderr
+++ b/src/tools/clippy/tests/ui/result_large_err.stderr
@@ -4,8 +4,8 @@ error: the `Err`-variant returned from this function is very large
 LL | pub fn large_err() -> Result<(), [u8; 512]> {
    |                       ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
    |
-   = note: `-D clippy::result-large-err` implied by `-D warnings`
    = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
+   = note: `-D clippy::result-large-err` implied by `-D warnings`
 
 error: the `Err`-variant returned from this function is very large
   --> $DIR/result_large_err.rs:19:21
diff --git a/src/tools/clippy/tests/ui/result_unit_error.stderr b/src/tools/clippy/tests/ui/result_unit_error.stderr
index 8c7573eabda..8393a4bf03b 100644
--- a/src/tools/clippy/tests/ui/result_unit_error.stderr
+++ b/src/tools/clippy/tests/ui/result_unit_error.stderr
@@ -4,8 +4,8 @@ error: this returns a `Result<_, ()>`
 LL | pub fn returns_unit_error() -> Result<u32, ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::result-unit-err` implied by `-D warnings`
    = help: use a custom `Error` type instead
+   = note: `-D clippy::result-unit-err` implied by `-D warnings`
 
 error: this returns a `Result<_, ()>`
   --> $DIR/result_unit_error.rs:12:5
diff --git a/src/tools/clippy/tests/ui/return_self_not_must_use.stderr b/src/tools/clippy/tests/ui/return_self_not_must_use.stderr
index 94be87dfa31..34932fe1c2c 100644
--- a/src/tools/clippy/tests/ui/return_self_not_must_use.stderr
+++ b/src/tools/clippy/tests/ui/return_self_not_must_use.stderr
@@ -4,8 +4,8 @@ error: missing `#[must_use]` attribute on a method returning `Self`
 LL |     fn what(&self) -> Self;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::return-self-not-must-use` implied by `-D warnings`
    = help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type
+   = note: `-D clippy::return-self-not-must-use` implied by `-D warnings`
 
 error: missing `#[must_use]` attribute on a method returning `Self`
   --> $DIR/return_self_not_must_use.rs:18:5
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
index cd438b83040..3901546cbd6 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
@@ -4,12 +4,12 @@ error: this `if` has the same function call as a previous `if`
 LL |     } else if function() {
    |               ^^^^^^^^^^
    |
-   = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings`
 note: same as this
   --> $DIR/same_functions_in_if_condition.rs:30:8
    |
 LL |     if function() {
    |        ^^^^^^^^^^
+   = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings`
 
 error: this `if` has the same function call as a previous `if`
   --> $DIR/same_functions_in_if_condition.rs:36:15
diff --git a/src/tools/clippy/tests/ui/same_item_push.stderr b/src/tools/clippy/tests/ui/same_item_push.stderr
index d9ffa15780a..1d1254d9fcc 100644
--- a/src/tools/clippy/tests/ui/same_item_push.stderr
+++ b/src/tools/clippy/tests/ui/same_item_push.stderr
@@ -4,8 +4,8 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = note: `-D clippy::same-item-push` implied by `-D warnings`
    = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = note: `-D clippy::same-item-push` implied by `-D warnings`
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:29:9
diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr
index f55ec9f3cc6..0c6908c0959 100644
--- a/src/tools/clippy/tests/ui/same_name_method.stderr
+++ b/src/tools/clippy/tests/ui/same_name_method.stderr
@@ -4,12 +4,12 @@ error: method's name is the same as an existing method in a trait
 LL |             fn foo() {}
    |             ^^^^^^^^^^^
    |
-   = note: `-D clippy::same-name-method` implied by `-D warnings`
 note: existing `foo` defined here
   --> $DIR/same_name_method.rs:25:13
    |
 LL |             fn foo() {}
    |             ^^^^^^^^^^^
+   = note: `-D clippy::same-name-method` implied by `-D warnings`
 
 error: method's name is the same as an existing method in a trait
   --> $DIR/same_name_method.rs:35:13
diff --git a/src/tools/clippy/tests/ui/search_is_some.stderr b/src/tools/clippy/tests/ui/search_is_some.stderr
index 54760545bce..6bea8c67477 100644
--- a/src/tools/clippy/tests/ui/search_is_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some.stderr
@@ -8,8 +8,8 @@ LL | |                           }
 LL | |                    ).is_some();
    | |______________________________^
    |
-   = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: this is more succinctly expressed by calling `any()`
+   = note: `-D clippy::search-is-some` implied by `-D warnings`
 
 error: called `is_some()` after searching an `Iterator` with `position`
   --> $DIR/search_is_some.rs:20:13
diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr
index 43d76094d0e..c3d7bc2a536 100644
--- a/src/tools/clippy/tests/ui/shadow.stderr
+++ b/src/tools/clippy/tests/ui/shadow.stderr
@@ -4,12 +4,12 @@ error: `x` is shadowed by itself in `x`
 LL |     let x = x;
    |         ^
    |
-   = note: `-D clippy::shadow-same` implied by `-D warnings`
 note: previous binding is here
   --> $DIR/shadow.rs:5:9
    |
 LL |     let x = 1;
    |         ^
+   = note: `-D clippy::shadow-same` implied by `-D warnings`
 
 error: `mut x` is shadowed by itself in `&x`
   --> $DIR/shadow.rs:7:13
@@ -53,12 +53,12 @@ error: `x` is shadowed
 LL |     let x = x.0;
    |         ^
    |
-   = note: `-D clippy::shadow-reuse` implied by `-D warnings`
 note: previous binding is here
   --> $DIR/shadow.rs:13:9
    |
 LL |     let x = ([[0]], ());
    |         ^
+   = note: `-D clippy::shadow-reuse` implied by `-D warnings`
 
 error: `x` is shadowed
   --> $DIR/shadow.rs:15:9
@@ -150,12 +150,12 @@ error: `x` shadows a previous, unrelated binding
 LL |     let x = 2;
    |         ^
    |
-   = note: `-D clippy::shadow-unrelated` implied by `-D warnings`
 note: previous binding is here
   --> $DIR/shadow.rs:30:9
    |
 LL |     let x = 1;
    |         ^
+   = note: `-D clippy::shadow-unrelated` implied by `-D warnings`
 
 error: `x` shadows a previous, unrelated binding
   --> $DIR/shadow.rs:36:13
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
index 2b7d4628c3f..d2f41e3f934 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr
@@ -6,8 +6,8 @@ LL | |         unimplemented!()
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::should-implement-trait` implied by `-D warnings`
    = help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name
+   = note: `-D clippy::should-implement-trait` implied by `-D warnings`
 
 error: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut`
   --> $DIR/method_list_1.rs:29:5
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
index b6fd4356956..10bfea68ff5 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
@@ -6,8 +6,8 @@ LL | |         unimplemented!()
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::should-implement-trait` implied by `-D warnings`
    = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name
+   = note: `-D clippy::should-implement-trait` implied by `-D warnings`
 
 error: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter`
   --> $DIR/method_list_2.rs:30:5
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
index 88ea6bce25b..f1ed808ba08 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
@@ -10,8 +10,8 @@ LL |             mutex.lock().unwrap().bar();
 LL |     };
    |      - temporary lives until here
    |
-   = note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings`
    = note: this might lead to deadlocks or other unexpected behavior
+   = note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings`
 help: try moving the temporary above the match
    |
 LL ~     let value = mutex.lock().unwrap().foo();
diff --git a/src/tools/clippy/tests/ui/similar_names.stderr b/src/tools/clippy/tests/ui/similar_names.stderr
index 6e772693897..43c5cee4b45 100644
--- a/src/tools/clippy/tests/ui/similar_names.stderr
+++ b/src/tools/clippy/tests/ui/similar_names.stderr
@@ -4,12 +4,12 @@ error: binding's name is too similar to existing binding
 LL |     let bpple: i32;
    |         ^^^^^
    |
-   = note: `-D clippy::similar-names` implied by `-D warnings`
 note: existing binding defined here
   --> $DIR/similar_names.rs:19:9
    |
 LL |     let apple: i32;
    |         ^^^^^
+   = note: `-D clippy::similar-names` implied by `-D warnings`
 
 error: binding's name is too similar to existing binding
   --> $DIR/similar_names.rs:23:9
diff --git a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
index 1438b3999db..bfe6d44b589 100644
--- a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
+++ b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
@@ -4,8 +4,8 @@ error: single-character lifetime names are likely uninformative
 LL | struct DiagnosticCtx<'a, 'b>
    |                      ^^
    |
-   = note: `-D clippy::single-char-lifetime-names` implied by `-D warnings`
    = help: use a more informative name
+   = note: `-D clippy::single-char-lifetime-names` implied by `-D warnings`
 
 error: single-character lifetime names are likely uninformative
   --> $DIR/single_char_lifetime_names.rs:5:26
diff --git a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
index cf990be1b9f..633546f6419 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
+++ b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr
@@ -4,8 +4,8 @@ error: this import is redundant
 LL |     use {regex, serde};
    |          ^^^^^
    |
-   = note: `-D clippy::single-component-path-imports` implied by `-D warnings`
    = help: remove this import
+   = note: `-D clippy::single-component-path-imports` implied by `-D warnings`
 
 error: this import is redundant
   --> $DIR/single_component_path_imports_nested_first.rs:13:17
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
index 0f0dff57f51..037f695f3ee 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
@@ -4,8 +4,8 @@ error: found a count of bytes instead of a count of elements of `T`
 LL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
    |                                                              ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
+   = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
 
 error: found a count of bytes instead of a count of elements of `T`
   --> $DIR/expressions.rs:18:62
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
index c1e824167b7..4351e6a14fe 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
@@ -4,8 +4,8 @@ error: found a count of bytes instead of a count of elements of `T`
 LL |     unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
    |                                                                    ^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
+   = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
 
 error: found a count of bytes instead of a count of elements of `T`
   --> $DIR/functions.rs:19:62
diff --git a/src/tools/clippy/tests/ui/skip_while_next.stderr b/src/tools/clippy/tests/ui/skip_while_next.stderr
index 269cc13468b..7308ab4e55c 100644
--- a/src/tools/clippy/tests/ui/skip_while_next.stderr
+++ b/src/tools/clippy/tests/ui/skip_while_next.stderr
@@ -4,8 +4,8 @@ error: called `skip_while(<p>).next()` on an `Iterator`
 LL |     let _ = v.iter().skip_while(|&x| *x < 0).next();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::skip-while-next` implied by `-D warnings`
    = help: this is more succinctly expressed by calling `.find(!<p>)` instead
+   = note: `-D clippy::skip-while-next` implied by `-D warnings`
 
 error: called `skip_while(<p>).next()` on an `Iterator`
   --> $DIR/skip_while_next.rs:17:13
diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
index c35e0c22ae8..1432fdcff77 100644
--- a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
+++ b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
@@ -4,8 +4,8 @@ error: used `sort` on primitive type `i32`
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
-   = note: `-D clippy::stable-sort-primitive` implied by `-D warnings`
    = note: an unstable sort typically performs faster without any observable difference for this data type
+   = note: `-D clippy::stable-sort-primitive` implied by `-D warnings`
 
 error: used `sort` on primitive type `bool`
   --> $DIR/stable_sort_primitive.rs:9:5
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
index bc49dabf586..8138ccb82a0 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
@@ -4,8 +4,8 @@ error: used import from `std` instead of `core`
 LL |     use std::hash::Hasher;
    |         ^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::std-instead-of-core` implied by `-D warnings`
    = help: consider importing the item from `core`
+   = note: `-D clippy::std-instead-of-core` implied by `-D warnings`
 
 error: used import from `std` instead of `core`
   --> $DIR/std_instead_of_core.rs:11:9
@@ -69,8 +69,8 @@ error: used import from `std` instead of `alloc`
 LL |     use std::vec;
    |         ^^^^^^^^
    |
-   = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`
    = help: consider importing the item from `alloc`
+   = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`
 
 error: used import from `std` instead of `alloc`
   --> $DIR/std_instead_of_core.rs:33:9
@@ -86,8 +86,8 @@ error: used import from `alloc` instead of `core`
 LL |     use alloc::slice::from_ref;
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
    = help: consider importing the item from `core`
+   = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/str_to_string.stderr b/src/tools/clippy/tests/ui/str_to_string.stderr
index b1f73eda5d2..1d47da571fa 100644
--- a/src/tools/clippy/tests/ui/str_to_string.stderr
+++ b/src/tools/clippy/tests/ui/str_to_string.stderr
@@ -4,8 +4,8 @@ error: `to_string()` called on a `&str`
 LL |     let hello = "hello world".to_string();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::str-to-string` implied by `-D warnings`
    = help: consider using `.to_owned()`
+   = note: `-D clippy::str-to-string` implied by `-D warnings`
 
 error: `to_string()` called on a `&str`
   --> $DIR/str_to_string.rs:6:5
diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr
index 1ebd17999bd..e304c3e346d 100644
--- a/src/tools/clippy/tests/ui/string_to_string.stderr
+++ b/src/tools/clippy/tests/ui/string_to_string.stderr
@@ -4,8 +4,8 @@ error: `to_string()` called on a `String`
 LL |     let mut v = message.to_string();
    |                 ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::string-to-string` implied by `-D warnings`
    = help: consider using `.clone()`
+   = note: `-D clippy::string-to-string` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/struct_excessive_bools.stderr b/src/tools/clippy/tests/ui/struct_excessive_bools.stderr
index 2941bf2983a..e4d50043acb 100644
--- a/src/tools/clippy/tests/ui/struct_excessive_bools.stderr
+++ b/src/tools/clippy/tests/ui/struct_excessive_bools.stderr
@@ -9,8 +9,8 @@ LL | |     d: bool,
 LL | | }
    | |_^
    |
-   = note: `-D clippy::struct-excessive-bools` implied by `-D warnings`
    = help: consider using a state machine or refactoring bools into two-variant enums
+   = note: `-D clippy::struct-excessive-bools` implied by `-D warnings`
 
 error: more than 3 bools in a struct
   --> $DIR/struct_excessive_bools.rs:38:5
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
index ee68eb5a791..2e512b47f12 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
@@ -4,8 +4,8 @@ error: this looks like an `else {..}` but the `else` is missing
 LL |     } {
    |      ^
    |
-   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
    = note: to remove this lint, add the missing `else` or add a new line before the next block
+   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
 
 error: this looks like an `else if` but the `else` is missing
   --> $DIR/suspicious_else_formatting.rs:21:6
diff --git a/src/tools/clippy/tests/ui/suspicious_map.stderr b/src/tools/clippy/tests/ui/suspicious_map.stderr
index 3ffcd1a9031..e251674819e 100644
--- a/src/tools/clippy/tests/ui/suspicious_map.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_map.stderr
@@ -4,8 +4,8 @@ error: this call to `map()` won't have an effect on the call to `count()`
 LL |     let _ = (0..3).map(|x| x + 2).count();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::suspicious-map` implied by `-D warnings`
    = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`
+   = note: `-D clippy::suspicious-map` implied by `-D warnings`
 
 error: this call to `map()` won't have an effect on the call to `count()`
   --> $DIR/suspicious_map.rs:7:13
diff --git a/src/tools/clippy/tests/ui/suspicious_splitn.stderr b/src/tools/clippy/tests/ui/suspicious_splitn.stderr
index 3bcd681fa49..55ce63d4faa 100644
--- a/src/tools/clippy/tests/ui/suspicious_splitn.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_splitn.stderr
@@ -4,8 +4,8 @@ error: `splitn` called with `0` splits
 LL |     let _ = "a,b".splitn(0, ',');
    |             ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::suspicious-splitn` implied by `-D warnings`
    = note: the resulting iterator will always return `None`
+   = note: `-D clippy::suspicious-splitn` implied by `-D warnings`
 
 error: `rsplitn` called with `0` splits
   --> $DIR/suspicious_splitn.rs:11:13
diff --git a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr
index 581527dcff8..9f1289ccba0 100644
--- a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr
@@ -4,8 +4,8 @@ error: by not having a space between `>` and `-` it looks like `>-` is a single
 LL |     if a >- 30 {}
    |         ^^^^
    |
-   = note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings`
    = help: put a space between `>` and `-` and remove the space after `-`
+   = note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings`
 
 error: by not having a space between `>=` and `-` it looks like `>=-` is a single operator
   --> $DIR/suspicious_unary_op_formatting.rs:9:9
diff --git a/src/tools/clippy/tests/ui/swap.stderr b/src/tools/clippy/tests/ui/swap.stderr
index 2b556b475ce..ee4b7a508a5 100644
--- a/src/tools/clippy/tests/ui/swap.stderr
+++ b/src/tools/clippy/tests/ui/swap.stderr
@@ -6,8 +6,8 @@ LL | |     bar.a = bar.b;
 LL | |     bar.b = temp;
    | |________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b)`
    |
-   = note: `-D clippy::manual-swap` implied by `-D warnings`
    = note: or maybe you should use `std::mem::replace`?
+   = note: `-D clippy::manual-swap` implied by `-D warnings`
 
 error: this looks like you are swapping elements of `foo` manually
   --> $DIR/swap.rs:36:5
@@ -96,8 +96,8 @@ LL | /     a = b;
 LL | |     b = a;
    | |_________^ help: try: `std::mem::swap(&mut a, &mut b)`
    |
-   = note: `-D clippy::almost-swapped` implied by `-D warnings`
    = note: or maybe you should use `std::mem::replace`?
+   = note: `-D clippy::almost-swapped` implied by `-D warnings`
 
 error: this looks like you are trying to swap `c.0` and `a`
   --> $DIR/swap.rs:140:5
diff --git a/src/tools/clippy/tests/ui/trailing_empty_array.stderr b/src/tools/clippy/tests/ui/trailing_empty_array.stderr
index 9e2bd31d9fa..2e148440035 100644
--- a/src/tools/clippy/tests/ui/trailing_empty_array.stderr
+++ b/src/tools/clippy/tests/ui/trailing_empty_array.stderr
@@ -7,8 +7,8 @@ LL | |     last: [usize; 0],
 LL | | }
    | |_^
    |
-   = note: `-D clippy::trailing-empty-array` implied by `-D warnings`
    = help: consider annotating `RarelyUseful` with `#[repr(C)]` or another `repr` attribute
+   = note: `-D clippy::trailing-empty-array` implied by `-D warnings`
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
   --> $DIR/trailing_empty_array.rs:10:1
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
index fbd9abb005f..4d56a94646c 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr
@@ -4,12 +4,12 @@ error: this trait bound is already specified in the where clause
 LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
    |               ^^^^^
    |
+   = help: consider removing this trait bound
 note: the lint level is defined here
   --> $DIR/trait_duplication_in_bounds_unfixable.rs:1:9
    |
 LL | #![deny(clippy::trait_duplication_in_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: consider removing this trait bound
 
 error: this trait bound is already specified in the where clause
   --> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23
diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
index 1d88714814d..70d700c1cc4 100644
--- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
@@ -4,12 +4,12 @@ error: this type has already been used as a bound predicate
 LL |     T: Clone,
    |     ^^^^^^^^
    |
+   = help: consider combining the bounds: `T: Copy + Clone`
 note: the lint level is defined here
   --> $DIR/type_repetition_in_bounds.rs:1:9
    |
 LL | #![deny(clippy::type_repetition_in_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: consider combining the bounds: `T: Copy + Clone`
 
 error: this type has already been used as a bound predicate
   --> $DIR/type_repetition_in_bounds.rs:25:5
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
index c6a2127443b..2c466ff5c73 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
@@ -4,8 +4,8 @@ error: unsafe block missing a safety comment
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
    |
-   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
    = help: consider adding a safety comment on the preceding line
+   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
 
 error: unsafe block missing a safety comment
   --> $DIR/undocumented_unsafe_blocks.rs:266:5
diff --git a/src/tools/clippy/tests/ui/undropped_manually_drops.stderr b/src/tools/clippy/tests/ui/undropped_manually_drops.stderr
index 2ac0fe98697..92611a9b7df 100644
--- a/src/tools/clippy/tests/ui/undropped_manually_drops.stderr
+++ b/src/tools/clippy/tests/ui/undropped_manually_drops.stderr
@@ -4,8 +4,8 @@ error: the inner value of this ManuallyDrop will not be dropped
 LL |     drop(std::mem::ManuallyDrop::new(S));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::undropped-manually-drops` implied by `-D warnings`
    = help: to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop
+   = note: `-D clippy::undropped-manually-drops` implied by `-D warnings`
 
 error: the inner value of this ManuallyDrop will not be dropped
   --> $DIR/undropped_manually_drops.rs:15:5
diff --git a/src/tools/clippy/tests/ui/uninit_vec.stderr b/src/tools/clippy/tests/ui/uninit_vec.stderr
index 520bfb26b62..77fc689f076 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.stderr
+++ b/src/tools/clippy/tests/ui/uninit_vec.stderr
@@ -7,8 +7,8 @@ LL |     unsafe {
 LL |         vec.set_len(200);
    |         ^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::uninit-vec` implied by `-D warnings`
    = help: initialize the buffer or wrap the content in `MaybeUninit`
+   = note: `-D clippy::uninit-vec` implied by `-D warnings`
 
 error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
   --> $DIR/uninit_vec.rs:18:5
diff --git a/src/tools/clippy/tests/ui/unit_hash.stderr b/src/tools/clippy/tests/ui/unit_hash.stderr
index 050fa55a12b..089d1212dd1 100644
--- a/src/tools/clippy/tests/ui/unit_hash.stderr
+++ b/src/tools/clippy/tests/ui/unit_hash.stderr
@@ -4,8 +4,8 @@ error: this call to `hash` on the unit type will do nothing
 LL |         Foo::Empty => ().hash(&mut state),
    |                       ^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
    |
-   = note: `-D clippy::unit-hash` implied by `-D warnings`
    = note: the implementation of `Hash` for `()` is a no-op
+   = note: `-D clippy::unit-hash` implied by `-D warnings`
 
 error: this call to `hash` on the unit type will do nothing
   --> $DIR/unit_hash.rs:24:5
diff --git a/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr b/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
index e63d5874609..1d9564ce225 100644
--- a/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
+++ b/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr
@@ -4,12 +4,12 @@ error: this closure returns the unit type which also implements Ord
 LL |     structs.sort_by_key(|s| {
    |                         ^^^
    |
-   = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings`
 help: probably caused by this trailing semicolon
   --> $DIR/unit_return_expecting_ord.rs:19:24
    |
 LL |         double(s.field);
    |                        ^
+   = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings`
 
 error: this closure returns the unit type which also implements PartialOrd
   --> $DIR/unit_return_expecting_ord.rs:22:30
diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr b/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr
index 83a5618c983..db805eb3680 100644
--- a/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr
@@ -6,8 +6,8 @@ LL | use std::fs::{self as alias};
    |          |
    |          help: consider omitting `::{self}`: `fs as alias;`
    |
-   = note: `-D clippy::unnecessary-self-imports` implied by `-D warnings`
    = note: this will slightly change semantics; any non-module items at the same path will also be imported
+   = note: `-D clippy::unnecessary-self-imports` implied by `-D warnings`
 
 error: import ending with `::{self}`
   --> $DIR/unnecessary_self_imports.rs:8:1
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index 7deb90b06f3..02bf45a33fb 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -4,12 +4,12 @@ error: redundant clone
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                                                                ^^^^^^^^^^^ help: remove this
    |
-   = note: `-D clippy::redundant-clone` implied by `-D warnings`
 note: this value is dropped without further use
   --> $DIR/unnecessary_to_owned.rs:151:20
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::redundant-clone` implied by `-D warnings`
 
 error: redundant clone
   --> $DIR/unnecessary_to_owned.rs:152:40
diff --git a/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr b/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr
index b8d3c294532..6f7c3154569 100644
--- a/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr
+++ b/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr
@@ -4,8 +4,8 @@ error: you matched a field with a wildcard pattern, consider using `..` instead
 LL |         Foo { a: _, b: 0, .. } => {},
    |               ^^^^
    |
-   = note: `-D clippy::unneeded-field-pattern` implied by `-D warnings`
    = help: try with `Foo { b: 0, .. }`
+   = note: `-D clippy::unneeded-field-pattern` implied by `-D warnings`
 
 error: all the struct fields are matched to a wildcard pattern, consider using `..`
   --> $DIR/unneeded_field_pattern.rs:16:9
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
index 18c4276c6dd..8aaae2d7fff 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
@@ -4,8 +4,8 @@ error: you are deriving `serde::Deserialize` on a type that has methods using `u
 LL | #[derive(Deserialize)]
    |          ^^^^^^^^^^^
    |
-   = note: `-D clippy::unsafe-derive-deserialize` implied by `-D warnings`
    = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html
+   = note: `-D clippy::unsafe-derive-deserialize` implied by `-D warnings`
    = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr
index 8b8ad065a4c..cff3eccbd32 100644
--- a/src/tools/clippy/tests/ui/unused_async.stderr
+++ b/src/tools/clippy/tests/ui/unused_async.stderr
@@ -6,8 +6,8 @@ LL | |     4
 LL | | }
    | |_^
    |
-   = note: `-D clippy::unused-async` implied by `-D warnings`
    = help: consider removing the `async` from this function
+   = note: `-D clippy::unused-async` implied by `-D warnings`
 
 error: unused `async` for function with no await statements
   --> $DIR/unused_async.rs:17:5
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.stderr b/src/tools/clippy/tests/ui/unused_io_amount.stderr
index e5bdd993aa1..7ba7e09c0f0 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.stderr
+++ b/src/tools/clippy/tests/ui/unused_io_amount.stderr
@@ -4,8 +4,8 @@ error: written amount is not handled
 LL |     s.write(b"test")?;
    |     ^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::unused-io-amount` implied by `-D warnings`
    = help: use `Write::write_all` instead, or handle partial writes
+   = note: `-D clippy::unused-io-amount` implied by `-D warnings`
 
 error: read amount is not handled
   --> $DIR/unused_io_amount.rs:11:5
diff --git a/src/tools/clippy/tests/ui/unused_peekable.stderr b/src/tools/clippy/tests/ui/unused_peekable.stderr
index d557f54179d..54788f2fa2f 100644
--- a/src/tools/clippy/tests/ui/unused_peekable.stderr
+++ b/src/tools/clippy/tests/ui/unused_peekable.stderr
@@ -4,8 +4,8 @@ error: `peek` never called on `Peekable` iterator
 LL |     let peekable = std::iter::empty::<u32>().peekable();
    |         ^^^^^^^^
    |
-   = note: `-D clippy::unused-peekable` implied by `-D warnings`
    = help: consider removing the call to `peekable`
+   = note: `-D clippy::unused-peekable` implied by `-D warnings`
 
 error: `peek` never called on `Peekable` iterator
   --> $DIR/unused_peekable.rs:18:9
diff --git a/src/tools/clippy/tests/ui/unused_self.stderr b/src/tools/clippy/tests/ui/unused_self.stderr
index 0534b40eabb..23186122a9a 100644
--- a/src/tools/clippy/tests/ui/unused_self.stderr
+++ b/src/tools/clippy/tests/ui/unused_self.stderr
@@ -4,8 +4,8 @@ error: unused `self` argument
 LL |         fn unused_self_move(self) {}
    |                             ^^^^
    |
-   = note: `-D clippy::unused-self` implied by `-D warnings`
    = help: consider refactoring to a associated function
+   = note: `-D clippy::unused-self` implied by `-D warnings`
 
 error: unused `self` argument
   --> $DIR/unused_self.rs:12:28
diff --git a/src/tools/clippy/tests/ui/unwrap.stderr b/src/tools/clippy/tests/ui/unwrap.stderr
index 78422757819..e88d580f7bd 100644
--- a/src/tools/clippy/tests/ui/unwrap.stderr
+++ b/src/tools/clippy/tests/ui/unwrap.stderr
@@ -4,8 +4,8 @@ error: used `unwrap()` on `an Option` value
 LL |     let _ = opt.unwrap();
    |             ^^^^^^^^^^^^
    |
-   = note: `-D clippy::unwrap-used` implied by `-D warnings`
    = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
+   = note: `-D clippy::unwrap-used` implied by `-D warnings`
 
 error: used `unwrap()` on `a Result` value
   --> $DIR/unwrap.rs:10:13
diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
index 1a19459b2c1..211d2be1834 100644
--- a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
@@ -4,8 +4,8 @@ error: used `unwrap()` on `an Option` value
 LL |     Some(3).unwrap();
    |     ^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::unwrap-used` implied by `-D warnings`
    = help: if this value is `None`, it will panic
+   = note: `-D clippy::unwrap-used` implied by `-D warnings`
 
 error: used `expect()` on `an Option` value
   --> $DIR/unwrap_expect_used.rs:24:5
@@ -13,8 +13,8 @@ error: used `expect()` on `an Option` value
 LL |     Some(3).expect("Hello world!");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::expect-used` implied by `-D warnings`
    = help: if this value is `None`, it will panic
+   = note: `-D clippy::expect-used` implied by `-D warnings`
 
 error: used `unwrap()` on `a Result` value
   --> $DIR/unwrap_expect_used.rs:31:5
diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.stderr b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
index 56bc2f2d1c0..40e6bfe087e 100644
--- a/src/tools/clippy/tests/ui/unwrap_in_result.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
@@ -10,13 +10,13 @@ LL | |         }
 LL | |     }
    | |_____^
    |
-   = note: `-D clippy::unwrap-in-result` implied by `-D warnings`
    = help: unwrap and expect should not be used in a function that returns result or option
 note: potential non-recoverable error(s)
   --> $DIR/unwrap_in_result.rs:24:17
    |
 LL |         let i = i_str.parse::<i32>().unwrap();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::unwrap-in-result` implied by `-D warnings`
 
 error: used unwrap or expect in a function that returns result or option
   --> $DIR/unwrap_in_result.rs:32:5
diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.stderr b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
index 12e74d61471..9aef9dda6f6 100644
--- a/src/tools/clippy/tests/ui/useless_conversion_try.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion_try.stderr
@@ -4,12 +4,12 @@ error: useless conversion to the same type: `T`
 LL |     let _ = T::try_from(val).unwrap();
    |             ^^^^^^^^^^^^^^^^
    |
+   = help: consider removing `T::try_from()`
 note: the lint level is defined here
   --> $DIR/useless_conversion_try.rs:1:9
    |
 LL | #![deny(clippy::useless_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: consider removing `T::try_from()`
 
 error: useless conversion to the same type: `T`
   --> $DIR/useless_conversion_try.rs:5:5
diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
index 7428cf62d6c..8851e9f38be 100644
--- a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
+++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr
@@ -6,8 +6,8 @@ LL |     v.resize(0, 5);
    |       |
    |       help: ...or you can empty the vector with: `clear()`
    |
-   = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
    = help: the arguments may be inverted...
+   = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/verbose_file_reads.stderr b/src/tools/clippy/tests/ui/verbose_file_reads.stderr
index 550b6ab679f..44266c7c01f 100644
--- a/src/tools/clippy/tests/ui/verbose_file_reads.stderr
+++ b/src/tools/clippy/tests/ui/verbose_file_reads.stderr
@@ -4,8 +4,8 @@ error: use of `File::read_to_end`
 LL |     f.read_to_end(&mut buffer)?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::verbose-file-reads` implied by `-D warnings`
    = help: consider using `fs::read` instead
+   = note: `-D clippy::verbose-file-reads` implied by `-D warnings`
 
 error: use of `File::read_to_string`
   --> $DIR/verbose_file_reads.rs:26:5
diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr
index 2f1be61e5df..14748f583f0 100644
--- a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr
@@ -4,8 +4,8 @@ error: comparing trait object pointers compares a non-unique vtable address
 LL |     let _ = a == b;
    |             ^^^^^^
    |
-   = note: `-D clippy::vtable-address-comparisons` implied by `-D warnings`
    = help: consider extracting and comparing data pointers only
+   = note: `-D clippy::vtable-address-comparisons` implied by `-D warnings`
 
 error: comparing trait object pointers compares a non-unique vtable address
   --> $DIR/vtable_address_comparisons.rs:15:13
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
index 45b87aa0f20..bd5860f45ca 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
@@ -4,8 +4,8 @@ error: wildcard pattern covers any other pattern as it will match anyway
 LL |         "bar" | _ => {
    |         ^^^^^^^^^
    |
-   = note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings`
    = help: consider handling `_` separately
+   = note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings`
 
 error: wildcard pattern covers any other pattern as it will match anyway
   --> $DIR/wild_in_or_pats.rs:16:9
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.stderr b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
index 2e7ee51d7e1..d002e55c570 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
@@ -4,8 +4,8 @@ error: methods called `from_*` usually take no `self`
 LL |     fn from_i32(self) {}
    |                 ^^^^
    |
-   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
    = help: consider choosing a less ambiguous name
+   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
 
 error: methods called `from_*` usually take no `self`
   --> $DIR/wrong_self_convention.rs:22:21
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention2.stderr b/src/tools/clippy/tests/ui/wrong_self_convention2.stderr
index 5bdc47f91f6..8de10e7be69 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention2.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_convention2.stderr
@@ -4,8 +4,8 @@ error: methods called `from_*` usually take no `self`
 LL |         pub fn from_be_self(self) -> Self {
    |                             ^^^^
    |
-   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
    = help: consider choosing a less ambiguous name
+   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
 
 error: methods called `from_*` usually take no `self`
   --> $DIR/wrong_self_convention2.rs:63:25
diff --git a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
index 8665d8dc9a9..3d009083cee 100644
--- a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr
@@ -4,8 +4,8 @@ error: methods with the following characteristics: (`to_*` and `self` type is no
 LL |         pub fn to_many(&mut self) -> Option<&mut [T]> {
    |                        ^^^^^^^^^
    |
-   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
    = help: consider choosing a less ambiguous name
+   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`
 
 error: methods with the following characteristics: (`to_*` and `*_mut`) usually take `self` by mutable reference
   --> $DIR/wrong_self_conventions_mut.rs:22:28
diff --git a/src/tools/clippy/tests/ui/zero_div_zero.stderr b/src/tools/clippy/tests/ui/zero_div_zero.stderr
index 86563542e06..2793d160644 100644
--- a/src/tools/clippy/tests/ui/zero_div_zero.stderr
+++ b/src/tools/clippy/tests/ui/zero_div_zero.stderr
@@ -4,8 +4,8 @@ error: constant division of `0.0` with `0.0` will always result in NaN
 LL |     let nan = 0.0 / 0.0;
    |               ^^^^^^^^^
    |
-   = note: `-D clippy::zero-divided-by-zero` implied by `-D warnings`
    = help: consider using `f64::NAN` if you would like a constant representing NaN
+   = note: `-D clippy::zero-divided-by-zero` implied by `-D warnings`
 
 error: constant division of `0.0` with `0.0` will always result in NaN
   --> $DIR/zero_div_zero.rs:5:19
diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
index d924f33797d..c6ba6fa76f0 100644
--- a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
+++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
@@ -4,8 +4,8 @@ error: map with zero-sized value type
 LL | const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;
    |                            ^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
    = help: consider using a set instead
+   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
 
 error: map with zero-sized value type
   --> $DIR/zero_sized_btreemap_values.rs:8:30
diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
index 79770bf90d7..75bdeb42ec0 100644
--- a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
+++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
@@ -4,8 +4,8 @@ error: map with zero-sized value type
 LL | const CONST_NOT_OK: Option<HashMap<String, ()>> = None;
    |                            ^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
    = help: consider using a set instead
+   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
 
 error: map with zero-sized value type
   --> $DIR/zero_sized_hashmap_values.rs:8:30
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index dccfd4e0d98..b48395035d4 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -797,7 +797,10 @@ fn make_test_closure(
     let config = config.clone();
     let testpaths = testpaths.clone();
     let revision = revision.cloned();
-    test::DynTestFn(Box::new(move || runtest::run(config, &testpaths, revision.as_deref())))
+    test::DynTestFn(Box::new(move || {
+        runtest::run(config, &testpaths, revision.as_deref());
+        Ok(())
+    }))
 }
 
 /// Returns `true` if the given target is an Android target for the
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index cda27beab30..d07610b19d7 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -7,7 +7,7 @@
 #![feature(int_log)]
 #![feature(variant_count)]
 #![feature(yeet_expr)]
-#![feature(is_some_with)]
+#![feature(is_some_and)]
 #![feature(nonzero_ops)]
 #![feature(local_key_cell_methods)]
 #![cfg_attr(bootstrap, feature(let_else))]
diff --git a/src/tools/miri/src/stacked_borrows/stack.rs b/src/tools/miri/src/stacked_borrows/stack.rs
index 494ea08b56e..97632af785d 100644
--- a/src/tools/miri/src/stacked_borrows/stack.rs
+++ b/src/tools/miri/src/stacked_borrows/stack.rs
@@ -211,7 +211,7 @@ impl<'tcx> Stack {
         }
 
         // Couldn't find it in the stack; but if there is an unknown bottom it might be there.
-        let found = self.unknown_bottom.is_some_and(|&unknown_limit| {
+        let found = self.unknown_bottom.is_some_and(|unknown_limit| {
             tag.0 < unknown_limit.0 // unknown_limit is an upper bound for what can be in the unknown bottom.
         });
         if found { Ok(None) } else { Err(()) }
diff --git a/src/tools/miri/tests/fail/erroneous_const2.stderr b/src/tools/miri/tests/fail/erroneous_const2.stderr
index 05ed8ea1c14..4d402257b8b 100644
--- a/src/tools/miri/tests/fail/erroneous_const2.stderr
+++ b/src/tools/miri/tests/fail/erroneous_const2.stderr
@@ -4,9 +4,9 @@ error: any use of this value will cause an error
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    | --------------    ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow
    |
-   = note: `#[deny(const_err)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: `#[deny(const_err)]` on by default
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/erroneous_const2.rs:LL:CC
diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs
index cd9d5300964..0c60d500a80 100644
--- a/src/tools/remote-test-server/src/main.rs
+++ b/src/tools/remote-test-server/src/main.rs
@@ -12,6 +12,7 @@
 
 #[cfg(not(windows))]
 use std::fs::Permissions;
+use std::net::SocketAddr;
 #[cfg(not(windows))]
 use std::os::unix::prelude::*;
 
@@ -41,30 +42,44 @@ static TEST: AtomicUsize = AtomicUsize::new(0);
 
 #[derive(Copy, Clone)]
 struct Config {
-    pub remote: bool,
-    pub verbose: bool,
+    verbose: bool,
+    sequential: bool,
+    bind: SocketAddr,
 }
 
 impl Config {
     pub fn default() -> Config {
-        Config { remote: false, verbose: false }
+        Config {
+            verbose: false,
+            sequential: false,
+            bind: if cfg!(target_os = "android") || cfg!(windows) {
+                ([0, 0, 0, 0], 12345).into()
+            } else {
+                ([10, 0, 2, 15], 12345).into()
+            },
+        }
     }
 
     pub fn parse_args() -> Config {
         let mut config = Config::default();
 
         let args = env::args().skip(1);
+        let mut next_is_bind = false;
         for argument in args {
             match &argument[..] {
-                "remote" => {
-                    config.remote = true;
-                }
-                "verbose" | "-v" => {
-                    config.verbose = true;
+                bind if next_is_bind => {
+                    config.bind = t!(bind.parse());
+                    next_is_bind = false;
                 }
+                "--bind" => next_is_bind = true,
+                "--sequential" => config.sequential = true,
+                "--verbose" | "-v" => config.verbose = true,
                 arg => panic!("unknown argument: {}", arg),
             }
         }
+        if next_is_bind {
+            panic!("missing value for --bind");
+        }
 
         config
     }
@@ -81,13 +96,7 @@ fn main() {
 
     let config = Config::parse_args();
 
-    let bind_addr = if cfg!(target_os = "android") || cfg!(windows) || config.remote {
-        "0.0.0.0:12345"
-    } else {
-        "10.0.2.15:12345"
-    };
-
-    let listener = t!(TcpListener::bind(bind_addr));
+    let listener = t!(TcpListener::bind(config.bind));
     let (work, tmp): (PathBuf, PathBuf) = if cfg!(target_os = "android") {
         ("/data/tmp/work".into(), "/data/tmp/work/tmp".into())
     } else {
@@ -97,7 +106,7 @@ fn main() {
         tmp_dir.push("tmp");
         (work_dir, tmp_dir)
     };
-    println!("listening on {}!", bind_addr);
+    println!("listening on {}!", config.bind);
 
     t!(fs::create_dir_all(&work));
     t!(fs::create_dir_all(&tmp));
@@ -119,7 +128,12 @@ fn main() {
             let lock = lock.clone();
             let work = work.clone();
             let tmp = tmp.clone();
-            thread::spawn(move || handle_run(socket, &work, &tmp, &lock, config));
+            let f = move || handle_run(socket, &work, &tmp, &lock, config);
+            if config.sequential {
+                f();
+            } else {
+                thread::spawn(f);
+            }
         } else {
             panic!("unknown command {:?}", buf);
         }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs
index 7fb4b90e6d9..371d642c15d 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs
@@ -225,7 +225,7 @@ fn path_cmp_short(a: &ast::Path, b: &ast::Path) -> Ordering {
 }
 
 /// Compares two paths, if one ends earlier than the other the has_tl parameters decide which is
-/// greater as a a path that has a tree list should be greater, while one that just ends without
+/// greater as a path that has a tree list should be greater, while one that just ends without
 /// a tree list should be considered less.
 pub(super) fn use_tree_path_cmp(
     a: &ast::Path,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs
index 298814af5a4..ac10721d955 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs
@@ -132,7 +132,7 @@ where
 
             let ext = span.extensions();
 
-            // `FormattedFields` is a a formatted representation of the span's
+            // `FormattedFields` is a formatted representation of the span's
             // fields, which is stored in its extensions by the `fmt` layer's
             // `new_span` method. The fields will have been formatted
             // by the same field formatter that's provided to the event
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 9aab66b1d21..d4733107e79 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -73,14 +73,11 @@ const EXCEPTIONS_BOOTSTRAP: &[(&str, &str)] = &[
 /// these and all their dependencies *must not* be in the exception list.
 const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"];
 
-/// Crates whose dependencies must be explicitly permitted.
-const RESTRICTED_DEPENDENCY_CRATES: &[&str] = &["rustc_driver", "rustc_codegen_llvm"];
-
 /// Crates rustc is allowed to depend on. Avoid adding to the list if possible.
 ///
 /// This list is here to provide a speed-bump to adding a new dependency to
 /// rustc. Please check with the compiler team before adding an entry.
-const PERMITTED_DEPENDENCIES: &[&str] = &[
+const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "addr2line",
     "adler",
     "ahash",
@@ -307,7 +304,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
 ];
 
 const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[
-    // These two crates take quite a long time to build, so don't allow two versions of them
+    // This crate takes quite a long time to build, so don't allow two versions of them
     // to accidentally sneak into our dependency graph, in order to ensure we keep our CI times
     // under control.
     "cargo",
@@ -324,12 +321,12 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
         .features(cargo_metadata::CargoOpt::AllFeatures);
     let metadata = t!(cmd.exec());
     let runtime_ids = compute_runtime_crates(&metadata);
-    check_exceptions(&metadata, EXCEPTIONS, runtime_ids, bad);
-    check_dependencies(
+    check_license_exceptions(&metadata, EXCEPTIONS, runtime_ids, bad);
+    check_permitted_dependencies(
         &metadata,
-        "main workspace",
-        PERMITTED_DEPENDENCIES,
-        RESTRICTED_DEPENDENCY_CRATES,
+        "rustc",
+        PERMITTED_RUSTC_DEPENDENCIES,
+        &["rustc_driver", "rustc_codegen_llvm"],
         bad,
     );
     check_crate_duplicate(&metadata, FORBIDDEN_TO_HAVE_DUPLICATES, bad);
@@ -342,8 +339,8 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
         .features(cargo_metadata::CargoOpt::AllFeatures);
     let metadata = t!(cmd.exec());
     let runtime_ids = HashSet::new();
-    check_exceptions(&metadata, EXCEPTIONS_CRANELIFT, runtime_ids, bad);
-    check_dependencies(
+    check_license_exceptions(&metadata, EXCEPTIONS_CRANELIFT, runtime_ids, bad);
+    check_permitted_dependencies(
         &metadata,
         "cranelift",
         PERMITTED_CRANELIFT_DEPENDENCIES,
@@ -358,13 +355,13 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
         .features(cargo_metadata::CargoOpt::AllFeatures);
     let metadata = t!(cmd.exec());
     let runtime_ids = HashSet::new();
-    check_exceptions(&metadata, EXCEPTIONS_BOOTSTRAP, runtime_ids, bad);
+    check_license_exceptions(&metadata, EXCEPTIONS_BOOTSTRAP, runtime_ids, bad);
 }
 
 /// Check that all licenses are in the valid list in `LICENSES`.
 ///
-/// Packages listed in `EXCEPTIONS` are allowed for tools.
-fn check_exceptions(
+/// Packages listed in `exceptions` are allowed for tools.
+fn check_license_exceptions(
     metadata: &Metadata,
     exceptions: &[(&str, &str)],
     runtime_ids: HashSet<&PackageId>,
@@ -434,11 +431,11 @@ fn check_exceptions(
     }
 }
 
-/// Checks the dependency of `RESTRICTED_DEPENDENCY_CRATES` at the given path. Changes `bad` to
+/// Checks the dependency of `restricted_dependency_crates` at the given path. Changes `bad` to
 /// `true` if a check failed.
 ///
-/// Specifically, this checks that the dependencies are on the `PERMITTED_DEPENDENCIES`.
-fn check_dependencies(
+/// Specifically, this checks that the dependencies are on the `permitted_dependencies`.
+fn check_permitted_dependencies(
     metadata: &Metadata,
     descr: &str,
     permitted_dependencies: &[&'static str],
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 28a0700a64b..d8b3903b98e 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -538,7 +538,9 @@ fn map_lib_features(
                 becoming_feature = None;
                 if line.contains("rustc_const_unstable(") {
                     // `const fn` features are handled specially.
-                    let feature_name = match find_attr_val(line, "feature") {
+                    let feature_name = match find_attr_val(line, "feature").or_else(|| {
+                        iter_lines.peek().and_then(|next| find_attr_val(next.1, "feature"))
+                    }) {
                         Some(name) => name,
                         None => err!("malformed stability attribute: missing `feature` key"),
                     };