about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Conjob Bot <miri@cron.bot>2024-01-31 05:01:22 +0000
committerThe Miri Conjob Bot <miri@cron.bot>2024-01-31 05:01:22 +0000
commit38b8bd3737d26885202811449f290a2a082a672c (patch)
tree2645f361836f23dc58276ac2f5345ea08f1a8223
parent63524ee2161dfe6a20f1a757b18e9872b50079bb (diff)
parent80deabd0987201e1b8d060400f50e03309a0105e (diff)
downloadrust-38b8bd3737d26885202811449f290a2a082a672c.tar.gz
rust-38b8bd3737d26885202811449f290a2a082a672c.zip
Merge from rustc
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--Cargo.lock81
-rw-r--r--compiler/rustc_ast/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/util/literal.rs96
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs20
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs7
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs38
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs51
-rw-r--r--compiler/rustc_attr/src/session_diagnostics.rs47
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs3
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs14
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs10
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs77
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml4
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/audit.yml2
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/main.yml18
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml8
-rw-r--r--compiler/rustc_codegen_cranelift/.vscode/settings.json3
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock140
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml12
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md23
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Enable-the-exposed_provenance-feature.patch22
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch2
-rw-r--r--compiler/rustc_codegen_cranelift/patches/rand-lock.toml23
-rw-r--r--compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml4
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs11
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs36
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs14
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs330
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs34
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs23
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/vtable.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs2
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl3
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs38
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/assert_module_sources.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs84
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs2
-rw-r--r--compiler/rustc_const_eval/src/errors.rs54
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs21
-rw-r--r--compiler/rustc_const_eval/src/lib.rs7
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs14
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs23
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml1
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs60
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs658
-rw-r--r--compiler/rustc_error_codes/src/lib.rs678
-rw-r--r--compiler/rustc_error_messages/src/lib.rs1
-rw-r--r--compiler/rustc_errors/Cargo.toml2
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs7
-rw-r--r--compiler/rustc_errors/src/codes.rs39
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs57
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs13
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs108
-rw-r--r--compiler/rustc_errors/src/emitter.rs12
-rw-r--r--compiler/rustc_errors/src/json.rs4
-rw-r--r--compiler/rustc_errors/src/lib.rs43
-rw-r--r--compiler/rustc_errors/src/registry.rs9
-rw-r--r--compiler/rustc_errors/src/translation.rs6
-rw-r--r--compiler/rustc_expand/src/base.rs8
-rw-r--r--compiler/rustc_expand/src/config.rs4
-rw-r--r--compiler/rustc_expand/src/errors.rs11
-rw-r--r--compiler/rustc_expand/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs39
-rw-r--r--compiler/rustc_feature/src/unstable.rs3
-rw-r--r--compiler/rustc_hir/src/hir.rs9
-rw-r--r--compiler/rustc_hir/src/intravisit.rs20
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/object_safety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs39
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs140
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs8
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl5
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs52
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs45
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs42
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs56
-rw-r--r--compiler/rustc_hir_typeck/src/gather_locals.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs21
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs104
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs30
-rw-r--r--compiler/rustc_incremental/src/lib.rs1
-rw-r--r--compiler/rustc_index/src/interval.rs6
-rw-r--r--compiler/rustc_index/src/lib.rs11
-rw-r--r--compiler/rustc_index/src/vec.rs7
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs68
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs21
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs14
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs4
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs3
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs18
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs41
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs29
-rw-r--r--compiler/rustc_infer/src/lib.rs3
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_interface/src/lib.rs3
-rw-r--r--compiler/rustc_lexer/src/unescape.rs170
-rw-r--r--compiler/rustc_lexer/src/unescape/tests.rs10
-rw-r--r--compiler/rustc_lint/src/context.rs14
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs1
-rw-r--r--compiler/rustc_lint/src/errors.rs14
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs6
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs13
-rw-r--r--compiler/rustc_macros/build.rs16
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs4
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_macros/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/errors.rs28
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/locator.rs2
-rw-r--r--compiler/rustc_middle/src/error.rs11
-rw-r--r--compiler/rustc_middle/src/lib.rs6
-rw-r--r--compiler/rustc_middle/src/middle/region.rs8
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs11
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs2
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs28
-rw-r--r--compiler/rustc_middle/src/thir.rs2
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs2
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs2
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs8
-rw-r--r--compiler/rustc_middle/src/values.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs37
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs33
-rw-r--r--compiler/rustc_mir_build/src/errors.rs100
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs13
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/cursor.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs7
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs10
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs1
-rw-r--r--compiler/rustc_parse/messages.ftl14
-rw-r--r--compiler/rustc_parse/src/errors.rs30
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs40
-rw-r--r--compiler/rustc_parse/src/lib.rs3
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs44
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs54
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs1
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs159
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs14
-rw-r--r--compiler/rustc_passes/src/dead.rs2
-rw-r--r--compiler/rustc_passes/src/entry.rs6
-rw-r--r--compiler/rustc_passes/src/errors.rs94
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs5
-rw-r--r--compiler/rustc_passes/src/lib.rs3
-rw-r--r--compiler/rustc_pattern_analysis/Cargo.toml1
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs98
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs21
-rw-r--r--compiler/rustc_pattern_analysis/src/pat.rs31
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs15
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs84
-rw-r--r--compiler/rustc_privacy/src/errors.rs6
-rw-r--r--compiler/rustc_privacy/src/lib.rs61
-rw-r--r--compiler/rustc_query_impl/src/lib.rs2
-rw-r--r--compiler/rustc_query_system/src/error.rs3
-rw-r--r--compiler/rustc_resolve/Cargo.toml2
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs18
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs4
-rw-r--r--compiler/rustc_resolve/src/errors.rs66
-rw-r--r--compiler/rustc_resolve/src/imports.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs85
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs14
-rw-r--r--compiler/rustc_resolve/src/lib.rs6
-rw-r--r--compiler/rustc_resolve/src/macros.rs32
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/config.rs17
-rw-r--r--compiler/rustc_session/src/errors.rs6
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/options.rs6
-rw-r--r--compiler/rustc_session/src/session.rs8
-rw-r--r--compiler/rustc_span/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs14
-rw-r--r--compiler/rustc_symbol_mangling/src/hashed.rs43
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs6
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs104
-rw-r--r--compiler/rustc_target/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs64
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs20
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs40
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs161
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs90
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs269
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs4
-rw-r--r--compiler/rustc_traits/src/lib.rs1
-rw-r--r--compiler/rustc_transmute/src/lib.rs3
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs3
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs1
-rw-r--r--compiler/stable_mir/src/lib.rs1
-rw-r--r--library/alloc/src/boxed.rs3
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/alloc/src/rc.rs7
-rw-r--r--library/alloc/src/slice.rs4
-rw-r--r--library/alloc/src/str.rs2
-rw-r--r--library/alloc/src/sync.rs54
-rw-r--r--library/alloc/src/sync/tests.rs65
-rw-r--r--library/alloc/src/vec/cow.rs13
-rw-r--r--library/alloc/src/vec/mod.rs8
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/slice.rs16
-rw-r--r--library/alloc/tests/vec.rs24
-rw-r--r--library/core/src/array/mod.rs9
-rw-r--r--library/core/src/ascii/ascii_char.rs16
-rw-r--r--library/core/src/ffi/mod.rs64
-rw-r--r--library/core/src/intrinsics.rs2
-rw-r--r--library/core/src/iter/adapters/intersperse.rs147
-rw-r--r--library/core/src/net/ip_addr.rs1
-rw-r--r--library/core/src/num/mod.rs10
-rw-r--r--library/core/src/num/nonzero.rs50
-rw-r--r--library/core/src/pin.rs46
-rw-r--r--library/core/src/primitive_docs.rs24
-rw-r--r--library/core/src/ptr/const_ptr.rs2
-rw-r--r--library/core/src/ptr/metadata.rs16
-rw-r--r--library/core/src/ptr/mut_ptr.rs2
-rw-r--r--library/core/src/ptr/non_null.rs8
-rw-r--r--library/core/src/slice/iter.rs64
-rw-r--r--library/core/src/slice/mod.rs44
-rw-r--r--library/core/src/str/converts.rs40
-rw-r--r--library/core/src/str/iter.rs25
-rw-r--r--library/core/src/str/mod.rs3
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/std/src/collections/hash/map.rs3
-rw-r--r--library/std/src/fs.rs10
-rw-r--r--library/std/src/io/buffered/bufreader.rs1
-rw-r--r--library/std/src/io/error.rs36
-rw-r--r--library/std/src/io/error/tests.rs4
-rw-r--r--library/std/src/io/impls.rs5
-rw-r--r--library/std/src/io/mod.rs38
-rw-r--r--library/std/src/io/stdio.rs11
-rw-r--r--library/std/src/io/util.rs10
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/num.rs10
-rw-r--r--library/std/src/os/mod.rs3
-rw-r--r--library/std/src/os/wasi/mod.rs3
-rw-r--r--library/std/src/os/wasi_preview2/mod.rs5
-rw-r--r--library/std/src/os/windows/fs.rs2
-rw-r--r--library/std/src/sys/pal/mod.rs3
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs7
-rw-r--r--library/std/src/sys/pal/unix/process/process_unsupported.rs5
-rw-r--r--library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs5
-rw-r--r--library/std/src/sys/pal/unix/process/process_vxworks.rs7
-rw-r--r--library/std/src/sys/pal/wasi/helpers.rs123
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs132
-rw-r--r--library/std/src/sys/pal/wasi/net.rs3
-rw-r--r--library/std/src/sys/pal/wasi_preview2/mod.rs78
-rw-r--r--library/std/src/sys/pal/windows/alloc.rs24
-rw-r--r--library/std/src/sys/pal/windows/c.rs4
-rw-r--r--library/std/src/sys/pal/windows/fs.rs34
-rw-r--r--src/bootstrap/bootstrap.py11
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs12
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/setup/tests.rs (renamed from src/bootstrap/src/tests/setup.rs)0
-rw-r--r--src/bootstrap/src/core/builder.rs1
-rw-r--r--src/bootstrap/src/core/builder/tests.rs (renamed from src/bootstrap/src/tests/builder.rs)0
-rw-r--r--src/bootstrap/src/core/config/config.rs6
-rw-r--r--src/bootstrap/src/core/config/mod.rs2
-rw-r--r--src/bootstrap/src/core/config/tests.rs (renamed from src/bootstrap/src/tests/config.rs)2
-rw-r--r--src/bootstrap/src/lib.rs2
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs3
-rw-r--r--src/bootstrap/src/utils/change_tracker/tests.rs10
-rw-r--r--src/bootstrap/src/utils/helpers.rs1
-rw-r--r--src/bootstrap/src/utils/helpers/tests.rs (renamed from src/bootstrap/src/tests/helpers.rs)48
-rwxr-xr-xsrc/ci/docker/run.sh116
-rw-r--r--src/ci/github-actions/ci.yml2
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md1
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasi-preview2.md30
-rw-r--r--src/etc/natvis/libcore.natvis39
-rw-r--r--src/librustdoc/clean/mod.rs7
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css6
-rw-r--r--src/librustdoc/html/static/js/storage.js10
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/tools/clippy/CHANGELOG.md2
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md21
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs80
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_config/src/types.rs2
-rw-r--r--src/tools/clippy/clippy_dev/Cargo.toml4
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs5
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_impl.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/open_options.rs230
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_or_err_ok.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/search_is_some.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/useless_asref.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs77
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs179
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs118
-rw-r--r--src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/single_call_fn.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs51
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/utils.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/unconditional_recursion.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs292
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs3
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr6
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml14
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs3
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml10
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs3
-rw-r--r--src/tools/clippy/tests/ui-internal/check_formulation.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr6
-rw-r--r--src/tools/clippy/tests/ui-toml/pub_underscore_fields/exported/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr81
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs34
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.fixed14
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.rs14
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs8
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr6
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs12
-rw-r--r--src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr18
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9041.stderr2
-rw-r--r--src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.fixed28
-rw-r--r--src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.rs28
-rw-r--r--src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.stderr17
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed40
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs40
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed32
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs32
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed8
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs8
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr16
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else.rs28
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else.stderr69
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.rs18
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.stderr37
-rw-r--r--src/tools/clippy/tests/ui/ineffective_open_options.fixed9
-rw-r--r--src/tools/clippy/tests/ui/ineffective_open_options.rs9
-rw-r--r--src/tools/clippy/tests/ui/join_absolute_paths.stderr8
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_or.stderr2
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr48
-rw-r--r--src/tools/clippy/tests/ui/map_clone.fixed33
-rw-r--r--src/tools/clippy/tests/ui/map_clone.rs35
-rw-r--r--src/tools/clippy/tests/ui/map_clone.stderr36
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.rs4
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.stderr5
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_no_std.fixed82
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_no_std.rs82
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_no_std.stderr50
-rw-r--r--src/tools/clippy/tests/ui/no_effect.rs2
-rw-r--r--src/tools/clippy/tests/ui/no_effect.stderr16
-rw-r--r--src/tools/clippy/tests/ui/open_options.rs38
-rw-r--r--src/tools/clippy/tests/ui/open_options.stderr34
-rw-r--r--src/tools/clippy/tests/ui/open_options_fixable.fixed7
-rw-r--r--src/tools/clippy/tests/ui/open_options_fixable.rs7
-rw-r--r--src/tools/clippy/tests/ui/open_options_fixable.stderr14
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.stderr36
-rw-r--r--src/tools/clippy/tests/ui/option_map_or_err_ok.stderr2
-rw-r--r--src/tools/clippy/tests/ui/option_map_or_none.stderr10
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.fixed49
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.rs49
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.stderr17
-rw-r--r--src/tools/clippy/tests/ui/read_zero_byte_vec.rs29
-rw-r--r--src/tools/clippy/tests/ui/read_zero_byte_vec.stderr34
-rw-r--r--src/tools/clippy/tests/ui/result_map_or_into_option.stderr6
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.stderr10
-rw-r--r--src/tools/clippy/tests/ui/search_is_some.stderr4
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr86
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr94
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed3
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs3
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr2
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed34
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs34
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr10
-rw-r--r--src/tools/clippy/tests/ui/single_call_fn.rs11
-rw-r--r--src/tools/clippy/tests/ui/single_char_pattern.stderr80
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed31
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs31
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs13
-rw-r--r--src/tools/clippy/tests/ui/transmute.stderr61
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char.fixed15
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char.rs15
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char.stderr17
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed27
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs27
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr17
-rw-r--r--src/tools/clippy/tests/ui/transmute_ref_to_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr4
-rw-r--r--src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs30
-rw-r--r--src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.stderr26
-rw-r--r--src/tools/clippy/tests/ui/unconditional_recursion.rs26
-rw-r--r--src/tools/clippy/tests/ui/unconditional_recursion.stderr19
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_join.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.stderr24
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.rs87
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.stderr141
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.fixed36
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.rs36
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.stderr26
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/error_index_generator/Cargo.toml1
-rw-r--r--src/tools/error_index_generator/main.rs8
-rw-r--r--src/tools/miri/src/diagnostics.rs2
-rw-r--r--src/tools/miri/tests/pass/issues/issue-120337-irrefutable-let-ice.rs16
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lexed_str.rs4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs19
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/validation.rs12
-rw-r--r--src/tools/tidy/src/deps.rs2
-rw-r--r--src/tools/tidy/src/error_codes.rs34
-rw-r--r--src/tools/tidy/src/ui_tests.rs14
-rw-r--r--tests/assembly/targets/targets-elf.rs68
-rw-r--r--tests/assembly/targets/targets-macho.rs81
-rw-r--r--tests/codegen/infallible-unwrap-in-opt-z.rs2
-rw-r--r--tests/codegen/pow_of_two.rs4
-rw-r--r--tests/debuginfo/msvc-pretty-enums.rs8
-rw-r--r--tests/debuginfo/numeric-types.rs46
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff34
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff34
-rw-r--r--tests/mir-opt/gvn_uninhabited.rs24
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff4
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/pretty/delimited-token-groups.rs2
-rw-r--r--tests/pretty/macro_rules.rs10
-rw-r--r--tests/pretty/stmt_expr_attributes.rs2
-rw-r--r--tests/run-make/symbol-mangling-hashed/Makefile48
-rw-r--r--tests/run-make/symbol-mangling-hashed/a_dylib.rs4
-rw-r--r--tests/run-make/symbol-mangling-hashed/a_rlib.rs5
-rw-r--r--tests/run-make/symbol-mangling-hashed/b_bin.rs9
-rw-r--r--tests/run-make/symbol-mangling-hashed/b_dylib.rs9
-rw-r--r--tests/run-make/target-specs/Makefile2
-rw-r--r--tests/rustdoc/footnote-definition-without-blank-line-100638.rs15
-rw-r--r--tests/ui-fulldeps/internal-lints/query_stability.rs13
-rw-r--r--tests/ui-fulldeps/internal-lints/query_stability.stderr26
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs166
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr268
-rw-r--r--tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs2
-rw-r--r--tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr2
-rw-r--r--tests/ui/anonymous-higher-ranked-lifetime.stderr55
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr5
-rw-r--r--tests/ui/associated-types/associated-types-path-2.rs2
-rw-r--r--tests/ui/associated-types/associated-types-path-2.stderr24
-rw-r--r--tests/ui/associated-types/associated-types-unconstrained.stderr2
-rw-r--r--tests/ui/async-await/async-closures/def-path.rs14
-rw-r--r--tests/ui/async-await/async-closures/def-path.stderr17
-rw-r--r--tests/ui/async-await/async-closures/higher-ranked.rs12
-rw-r--r--tests/ui/async-await/async-closures/higher-ranked.stderr17
-rw-r--r--tests/ui/async-await/async-is-unwindsafe.stderr24
-rw-r--r--tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs18
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.stderr8
-rw-r--r--tests/ui/async-await/issue-68112.stderr6
-rw-r--r--tests/ui/box/unit/unique-object-noncopyable.stderr15
-rw-r--r--tests/ui/box/unit/unique-pinned-nocopy.stderr12
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr4
-rw-r--r--tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr11
-rw-r--r--tests/ui/closures/closure-return-type-must-be-sized.stderr12
-rw-r--r--tests/ui/closures/multiple-fn-bounds.stderr5
-rw-r--r--tests/ui/codegen/mismatched-data-layout.json13
-rw-r--r--tests/ui/codegen/mismatched-data-layouts.rs14
-rw-r--r--tests/ui/codegen/mismatched-data-layouts.stderr4
-rw-r--r--tests/ui/const-generics/ensure_is_evaluatable.stderr2
-rw-r--r--tests/ui/const-generics/fn_with_two_const_inputs.stderr2
-rw-r--r--tests/ui/const-generics/generic_arg_infer/issue-91614.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-85848.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-79674.stderr2
-rw-r--r--tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr2
-rw-r--r--tests/ui/consts/issue-54954.stderr2
-rw-r--r--tests/ui/consts/let-irrefutable-pattern-ice-120337.rs10
-rw-r--r--tests/ui/coroutine/clone-impl.stderr12
-rw-r--r--tests/ui/coroutine/drop-tracking-parent-expression.stderr6
-rw-r--r--tests/ui/coroutine/drop-yield-twice.stderr9
-rw-r--r--tests/ui/coroutine/issue-105084.stderr2
-rw-r--r--tests/ui/coroutine/issue-68112.stderr4
-rw-r--r--tests/ui/coroutine/not-send-sync.stderr18
-rw-r--r--tests/ui/coroutine/parent-expression.stderr6
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-1.stderr4
-rw-r--r--tests/ui/coroutine/print/coroutine-print-verbose-2.stderr18
-rw-r--r--tests/ui/derives/derive-assoc-type-not-impl.stderr5
-rw-r--r--tests/ui/derives/deriving-with-repr-packed-2.stderr10
-rw-r--r--tests/ui/derives/issue-36617.rs10
-rw-r--r--tests/ui/derives/issue-36617.stderr42
-rw-r--r--tests/ui/derives/issue-91550.stderr25
-rw-r--r--tests/ui/did_you_mean/recursion_limit.stderr2
-rw-r--r--tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr2
-rw-r--r--tests/ui/error-codes/E0283.stderr2
-rw-r--r--tests/ui/error-codes/E0790.stderr6
-rw-r--r--tests/ui/extenv/issue-55897.rs1
-rw-r--r--tests/ui/extenv/issue-55897.stderr14
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs2
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-bench.rs3
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-bench.stderr12
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-test.rs3
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-test.stderr12
-rw-r--r--tests/ui/for/issue-20605.next.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr8
-rw-r--r--tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs4
-rw-r--r--tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr8
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.rs8
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.stderr73
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.rs8
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.stderr75
-rw-r--r--tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-30786.stderr10
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr4
-rw-r--r--tests/ui/impl-trait/cross-return-site-inference.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.stderr10
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.stderr10
-rw-r--r--tests/ui/imports/issue-28134.rs2
-rw-r--r--tests/ui/imports/issue-28134.stderr10
-rw-r--r--tests/ui/imports/issue-55457.rs7
-rw-r--r--tests/ui/imports/issue-55457.stderr36
-rw-r--r--tests/ui/imports/issue-59764.rs1
-rw-r--r--tests/ui/imports/issue-59764.stderr12
-rw-r--r--tests/ui/inference/erase-type-params-in-label.stderr4
-rw-r--r--tests/ui/inference/need_type_info/infer-var-for-self-param.stderr2
-rw-r--r--tests/ui/inference/need_type_info/type-alias.stderr4
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime-err.rs25
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime-err.stderr28
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.rs2
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.stderr19
-rw-r--r--tests/ui/inline-const/pat-unsafe.rs1
-rw-r--r--tests/ui/inline-const/pat-unsafe.stderr20
-rw-r--r--tests/ui/internal/internal-unstable.rs10
-rw-r--r--tests/ui/internal/internal-unstable.stderr8
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/auxiliary/issue-1920.rs (renamed from tests/ui/issues/auxiliary/issue-1920.rs)0
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/issue-1920-1.rs (renamed from tests/ui/issues/issue-1920-1.rs)0
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/issue-1920-1.stderr (renamed from tests/ui/issues/issue-1920-1.stderr)0
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/issue-1920-2.rs (renamed from tests/ui/issues/issue-1920-2.rs)0
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/issue-1920-2.stderr (renamed from tests/ui/issues/issue-1920-2.stderr)0
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/issue-1920-3.rs (renamed from tests/ui/issues/issue-1920-3.rs)0
-rw-r--r--tests/ui/issues/issue-1920-absolute-paths/issue-1920-3.stderr (renamed from tests/ui/issues/issue-1920-3.stderr)0
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.rs (renamed from tests/ui/issues/issue-23302-1.rs)0
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr (renamed from tests/ui/issues/issue-23302-1.stderr)0
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.rs (renamed from tests/ui/issues/issue-23302-2.rs)0
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr (renamed from tests/ui/issues/issue-23302-2.stderr)0
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-3.rs (renamed from tests/ui/issues/issue-23302-3.rs)0
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-3.stderr (renamed from tests/ui/issues/issue-23302-3.stderr)0
-rw-r--r--tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.fixed (renamed from tests/ui/issues/issue-32122-1.fixed)0
-rw-r--r--tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs (renamed from tests/ui/issues/issue-32122-1.rs)0
-rw-r--r--tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.stderr (renamed from tests/ui/issues/issue-32122-1.stderr)0
-rw-r--r--tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.fixed (renamed from tests/ui/issues/issue-32122-2.fixed)0
-rw-r--r--tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs (renamed from tests/ui/issues/issue-32122-2.rs)0
-rw-r--r--tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.stderr (renamed from tests/ui/issues/issue-32122-2.stderr)0
-rw-r--r--tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.fixed (renamed from tests/ui/issues/issue-3668-2.fixed)0
-rw-r--r--tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs (renamed from tests/ui/issues/issue-3668-2.rs)0
-rw-r--r--tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.stderr (renamed from tests/ui/issues/issue-3668-2.stderr)0
-rw-r--r--tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs (renamed from tests/ui/issues/issue-3668.rs)0
-rw-r--r--tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.stderr (renamed from tests/ui/issues/issue-3668.stderr)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr (renamed from tests/ui/issues/issue-40510-1.migrate.stderr)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.rs (renamed from tests/ui/issues/issue-40510-1.rs)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.stderr (renamed from tests/ui/issues/issue-40510-1.stderr)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-2.rs (renamed from tests/ui/issues/issue-40510-2.rs)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr (renamed from tests/ui/issues/issue-40510-3.migrate.stderr)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.rs (renamed from tests/ui/issues/issue-40510-3.rs)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.stderr (renamed from tests/ui/issues/issue-40510-3.stderr)0
-rw-r--r--tests/ui/issues/issue-40510-captured-variable-return/issue-40510-4.rs (renamed from tests/ui/issues/issue-40510-4.rs)0
-rw-r--r--tests/ui/issues/issue-56199.stderr4
-rw-r--r--tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs (renamed from tests/ui/issues/issue-57741-1.rs)0
-rw-r--r--tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr (renamed from tests/ui/issues/issue-57741-1.stderr)0
-rw-r--r--tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed (renamed from tests/ui/issues/issue-57741.fixed)0
-rw-r--r--tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs (renamed from tests/ui/issues/issue-57741.rs)0
-rw-r--r--tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr (renamed from tests/ui/issues/issue-57741.stderr)0
-rw-r--r--tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.rs (renamed from tests/ui/issues/issue-5997-enum.rs)0
-rw-r--r--tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.stderr (renamed from tests/ui/issues/issue-5997-enum.stderr)0
-rw-r--r--tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.rs (renamed from tests/ui/issues/issue-5997-struct.rs)0
-rw-r--r--tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.stderr (renamed from tests/ui/issues/issue-5997-struct.stderr)0
-rw-r--r--tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs (renamed from tests/ui/issues/issue-5997.rs)0
-rw-r--r--tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.fixed (renamed from tests/ui/issues/issue-71676-1.fixed)0
-rw-r--r--tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.rs (renamed from tests/ui/issues/issue-71676-1.rs)0
-rw-r--r--tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.stderr (renamed from tests/ui/issues/issue-71676-1.stderr)0
-rw-r--r--tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.rs (renamed from tests/ui/issues/issue-71676-2.rs)0
-rw-r--r--tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.stderr (renamed from tests/ui/issues/issue-71676-2.stderr)0
-rw-r--r--tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.fixed (renamed from tests/ui/issues/issue-76077-1.fixed)0
-rw-r--r--tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs (renamed from tests/ui/issues/issue-76077-1.rs)0
-rw-r--r--tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr (renamed from tests/ui/issues/issue-76077-1.stderr)0
-rw-r--r--tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs (renamed from tests/ui/issues/issue-76077.rs)0
-rw-r--r--tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.stderr (renamed from tests/ui/issues/issue-76077.stderr)0
-rw-r--r--tests/ui/iterators/issue-28098.rs4
-rw-r--r--tests/ui/iterators/issue-28098.stderr50
-rw-r--r--tests/ui/iterators/vec-on-unimplemented.stderr3
-rw-r--r--tests/ui/lang-items/bad-add-impl.rs18
-rw-r--r--tests/ui/lang-items/bad-add-impl.stderr11
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr18
-rw-r--r--tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs49
-rw-r--r--tests/ui/lang-items/issue-31076.rs17
-rw-r--r--tests/ui/lang-items/issue-31076.stderr19
-rw-r--r--tests/ui/lang-items/issue-86238.rs16
-rw-r--r--tests/ui/lang-items/issue-86238.stderr10
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.stderr2
-rw-r--r--tests/ui/lint/clashing-extern-fn.rs2
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr6
-rw-r--r--tests/ui/lint/invalid_value.stderr16
-rw-r--r--tests/ui/lint/lint-ctypes-enum.stderr6
-rw-r--r--tests/ui/macros/stringify.rs33
-rw-r--r--tests/ui/macros/trace_faulty_macros.stderr2
-rw-r--r--tests/ui/methods/method-call-err-msg.stderr5
-rw-r--r--tests/ui/mismatched_types/E0631.stderr10
-rw-r--r--tests/ui/mismatched_types/closure-arg-count.stderr10
-rw-r--r--tests/ui/mismatched_types/issue-36053-2.stderr6
-rw-r--r--tests/ui/mismatched_types/non_zero_assigned_something.stderr8
-rw-r--r--tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr2
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr12
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr (renamed from tests/ui/object-safety/avoid-ice-on-warning-2.stderr)28
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-2.rs13
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr47
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr (renamed from tests/ui/object-safety/avoid-ice-on-warning-3.stderr)84
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-3.rs31
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning.new.stderr15
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning.old.stderr (renamed from tests/ui/object-safety/avoid-ice-on-warning.stderr)12
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning.rs7
-rw-r--r--tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed9
-rw-r--r--tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed16
-rw-r--r--tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.stderr (renamed from tests/ui/object-safety/bare-trait-dont-suggest-dyn.stderr)2
-rw-r--r--tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr39
-rw-r--r--tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs9
-rw-r--r--tests/ui/on-unimplemented/multiple-impls.rs3
-rw-r--r--tests/ui/on-unimplemented/multiple-impls.stderr49
-rw-r--r--tests/ui/on-unimplemented/on-impl.rs1
-rw-r--r--tests/ui/on-unimplemented/on-impl.stderr12
-rw-r--r--tests/ui/on-unimplemented/on-trait.stderr4
-rw-r--r--tests/ui/panic-handler/panic-handler-requires-panic-info.rs2
-rw-r--r--tests/ui/panic-handler/panic-handler-requires-panic-info.stderr6
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs9
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr27
-rw-r--r--tests/ui/parser/issues/issue-24197.rs2
-rw-r--r--tests/ui/parser/issues/issue-24197.stderr6
-rw-r--r--tests/ui/parser/issues/issue-24375.rs2
-rw-r--r--tests/ui/parser/issues/issue-24375.stderr6
-rw-r--r--tests/ui/parser/label-is-actually-char.rs41
-rw-r--r--tests/ui/parser/label-is-actually-char.stderr73
-rw-r--r--tests/ui/parser/pat-lt-bracket-5.rs4
-rw-r--r--tests/ui/parser/pat-lt-bracket-5.stderr15
-rw-r--r--tests/ui/parser/pat-lt-bracket-6.rs3
-rw-r--r--tests/ui/parser/pat-lt-bracket-6.stderr30
-rw-r--r--tests/ui/parser/pat-ranges-3.rs6
-rw-r--r--tests/ui/parser/pat-ranges-3.stderr14
-rw-r--r--tests/ui/parser/pat-ranges-4.rs6
-rw-r--r--tests/ui/parser/pat-ranges-4.stderr8
-rw-r--r--tests/ui/parser/pat-recover-exprs.rs28
-rw-r--r--tests/ui/parser/pat-recover-exprs.stderr76
-rw-r--r--tests/ui/parser/pat-recover-methodcalls.rs37
-rw-r--r--tests/ui/parser/pat-recover-methodcalls.stderr35
-rw-r--r--tests/ui/parser/pat-recover-ranges.rs16
-rw-r--r--tests/ui/parser/pat-recover-ranges.stderr84
-rw-r--r--tests/ui/parser/pat-recover-wildcards.rs61
-rw-r--r--tests/ui/parser/pat-recover-wildcards.stderr77
-rw-r--r--tests/ui/parser/range-exclusive-dotdotlt.rs43
-rw-r--r--tests/ui/parser/range-exclusive-dotdotlt.stderr46
-rw-r--r--tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr5
-rw-r--r--tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr100
-rw-r--r--tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr630
-rw-r--r--tests/ui/pattern/usefulness/empty-types.normal.stderr98
-rw-r--r--tests/ui/pattern/usefulness/empty-types.rs84
-rw-r--r--tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs2
-rw-r--r--tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr2
-rw-r--r--tests/ui/pin-macro/cant_access_internals.rs2
-rw-r--r--tests/ui/pin-macro/cant_access_internals.stderr4
-rw-r--r--tests/ui/print_type_sizes/niche-filling.stdout16
-rw-r--r--tests/ui/proc-macro/allowed-attr-stmt-expr.stdout7
-rw-r--r--tests/ui/proc-macro/attr-stmt-expr.stdout5
-rw-r--r--tests/ui/proc-macro/attribute-spans-preserved.stdout2
-rw-r--r--tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs4
-rw-r--r--tests/ui/proc-macro/cfg-eval-inner.stdout4
-rw-r--r--tests/ui/proc-macro/derive-helper-legacy-spurious.rs2
-rw-r--r--tests/ui/proc-macro/derive-helper-legacy-spurious.stderr10
-rw-r--r--tests/ui/proc-macro/doc-comment-preserved.stdout2
-rw-r--r--tests/ui/proc-macro/dollar-crate-issue-57089.stdout2
-rw-r--r--tests/ui/proc-macro/dollar-crate-issue-62325.stdout2
-rw-r--r--tests/ui/proc-macro/dollar-crate.stdout6
-rw-r--r--tests/ui/proc-macro/expand-to-derive.stdout4
-rw-r--r--tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout13
-rw-r--r--tests/ui/proc-macro/inert-attribute-order.stdout8
-rw-r--r--tests/ui/proc-macro/inner-attrs.stdout11
-rw-r--r--tests/ui/proc-macro/input-interpolated.stdout2
-rw-r--r--tests/ui/proc-macro/issue-118455-skip-err-builtin.rs6
-rw-r--r--tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr8
-rw-r--r--tests/ui/proc-macro/issue-75734-pp-paren.stdout2
-rw-r--r--tests/ui/proc-macro/issue-75930-derive-cfg.stdout22
-rw-r--r--tests/ui/proc-macro/issue-76182-leading-vert-pat.stdout2
-rw-r--r--tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.fixed6
-rw-r--r--tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs6
-rw-r--r--tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr16
-rw-r--r--tests/ui/proc-macro/keep-expr-tokens.stdout2
-rw-r--r--tests/ui/proc-macro/macro-rules-derive-cfg.stdout6
-rw-r--r--tests/ui/proc-macro/nested-derive-cfg.stdout2
-rw-r--r--tests/ui/proc-macro/nonterminal-token-hygiene.stdout1
-rw-r--r--tests/ui/proc-macro/pretty-print-tts.stdout2
-rw-r--r--tests/ui/reserved/reserved-attr-on-macro.rs2
-rw-r--r--tests/ui/reserved/reserved-attr-on-macro.stderr10
-rw-r--r--tests/ui/rust-2018/issue-54006.rs1
-rw-r--r--tests/ui/rust-2018/issue-54006.stderr10
-rw-r--r--tests/ui/span/issue-43927-non-ADT-derive.rs3
-rw-r--r--tests/ui/span/issue-43927-non-ADT-derive.stderr12
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr5
-rw-r--r--tests/ui/str/str-escape.rs9
-rw-r--r--tests/ui/str/str-escape.stderr14
-rw-r--r--tests/ui/str/str-mut-idx.stderr2
-rw-r--r--tests/ui/suggestions/derive-trait-for-method-call.stderr16
-rw-r--r--tests/ui/suggestions/issue-104327.stderr2
-rw-r--r--tests/ui/suggestions/issue-104328.stderr2
-rw-r--r--tests/ui/suggestions/issue-89333.stderr2
-rw-r--r--tests/ui/suggestions/mut-borrow-needed-by-trait.stderr3
-rw-r--r--tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr4
-rw-r--r--tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed29
-rw-r--r--tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs29
-rw-r--r--tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr60
-rw-r--r--tests/ui/suggestions/suggest-change-mut.stderr3
-rw-r--r--tests/ui/symbol-mangling-version/bad-value.bad.stderr2
-rw-r--r--tests/ui/symbol-mangling-version/bad-value.blank.stderr2
-rw-r--r--tests/ui/symbol-mangling-version/bad-value.no-value.stderr2
-rw-r--r--tests/ui/symbol-mangling-version/unstable.hashed.stderr2
-rw-r--r--tests/ui/symbol-mangling-version/unstable.rs5
-rw-r--r--tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr5
-rw-r--r--tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr5
-rw-r--r--tests/ui/traits/bad-sized.stderr2
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait.stderr14
-rw-r--r--tests/ui/traits/inductive-overflow/lifetime.stderr2
-rw-r--r--tests/ui/traits/inductive-overflow/simultaneous.stderr2
-rw-r--r--tests/ui/traits/inductive-overflow/supertrait.stderr2
-rw-r--r--tests/ui/traits/inductive-overflow/two-traits.stderr2
-rw-r--r--tests/ui/traits/invalid_operator_trait.rs23
-rw-r--r--tests/ui/traits/invalid_operator_trait.stderr8
-rw-r--r--tests/ui/traits/issue-77982.stderr3
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.rs5
-rw-r--r--tests/ui/traits/next-solver/alias-bound-unsound.stderr25
-rw-r--r--tests/ui/traits/next-solver/alias-relate/alias_eq_cant_be_furthur_normalized.rs (renamed from tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs)0
-rw-r--r--tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs (renamed from tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs)0
-rw-r--r--tests/ui/traits/next-solver/alias-relate/alias_eq_simple.rs (renamed from tests/ui/traits/next-solver/alias_eq_simple.rs)0
-rw-r--r--tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.rs (renamed from tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs)0
-rw-r--r--tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.stderr (renamed from tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr)0
-rw-r--r--tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs (renamed from tests/ui/traits/next-solver/tait-eq-proj-2.rs)2
-rw-r--r--tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs (renamed from tests/ui/traits/next-solver/tait-eq-proj.rs)0
-rw-r--r--tests/ui/traits/next-solver/alias-relate/tait-eq-tait.rs (renamed from tests/ui/traits/next-solver/tait-eq-tait.rs)0
-rw-r--r--tests/ui/traits/next-solver/assembly/ambig-projection-self-is-ambig.rs19
-rw-r--r--tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr16
-rw-r--r--tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr4
-rw-r--r--tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs3
-rw-r--r--tests/ui/traits/next-solver/more-object-bound.stderr2
-rw-r--r--tests/ui/traits/next-solver/normalize-path-for-method.rs18
-rw-r--r--tests/ui/traits/next-solver/normalize-region-obligations.rs22
-rw-r--r--tests/ui/traits/next-solver/object-unsafety.stderr5
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs2
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr28
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs2
-rw-r--r--tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr28
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.rs1
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.stderr8
-rw-r--r--tests/ui/traits/next-solver/specialization-unconstrained.stderr2
-rw-r--r--tests/ui/traits/next-solver/temporary-ambiguity.rs22
-rw-r--r--tests/ui/traits/next-solver/unsound-region-obligation.rs13
-rw-r--r--tests/ui/traits/next-solver/unsound-region-obligation.stderr7
-rw-r--r--tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr2
-rw-r--r--tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr6
-rw-r--r--tests/ui/traits/non_lifetime_binders/fail.stderr4
-rw-r--r--tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr2
-rw-r--r--tests/ui/traits/static-method-generic-inference.stderr2
-rw-r--r--tests/ui/traits/track-obligations.stderr5
-rw-r--r--tests/ui/transmutability/region-infer.stderr2
-rw-r--r--tests/ui/treat-err-as-bug/eagerly-emit.rs1
-rw-r--r--tests/ui/treat-err-as-bug/eagerly-emit.stderr12
-rw-r--r--tests/ui/try-trait/bad-interconversion.stderr3
-rw-r--r--tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/struct-assignment-validity.rs31
-rw-r--r--tests/ui/type/issue-101866.stderr2
-rw-r--r--tests/ui/typeck/derive-sugg-arg-arity.stderr6
-rw-r--r--tests/ui/typeck/issue-31173.stderr6
-rw-r--r--tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr2
-rw-r--r--tests/ui/union/issue-81199.rs2
-rw-r--r--tests/ui/union/union-derive-clone.stderr5
-rw-r--r--tests/ui/unsized-locals/unsized-exprs.stderr2
-rw-r--r--tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr2
-rw-r--r--tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr2
-rw-r--r--triagebot.toml17
914 files changed, 11063 insertions, 6912 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index caf97abf78d..853f43e15e3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,6 +28,7 @@ name: CI
       - "**"
 permissions:
   contents: read
+  packages: write
 defaults:
   run:
     shell: bash
@@ -42,6 +43,7 @@ jobs:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
+      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
       CACHE_DOMAIN: ci-caches.rust-lang.org
@@ -172,6 +174,7 @@ jobs:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
+      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       DEPLOY_BUCKET: rust-lang-ci2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
@@ -554,6 +557,7 @@ jobs:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
+      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       DEPLOY_BUCKET: rust-lang-ci2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
diff --git a/Cargo.lock b/Cargo.lock
index 74f96983b31..25f4959bf14 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -382,9 +382,9 @@ dependencies = [
 
 [[package]]
 name = "byteorder"
-version = "1.4.3"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
@@ -596,11 +596,11 @@ dependencies = [
 name = "clippy_dev"
 version = "0.0.1"
 dependencies = [
- "aho-corasick 0.7.20",
+ "aho-corasick 1.0.2",
  "clap",
  "indoc",
  "itertools",
- "opener 0.5.2",
+ "opener",
  "shell-escape",
  "walkdir",
 ]
@@ -610,7 +610,7 @@ name = "clippy_lints"
 version = "0.1.77"
 dependencies = [
  "arrayvec",
- "cargo_metadata 0.15.4",
+ "cargo_metadata 0.18.0",
  "clippy_config",
  "clippy_utils",
  "declare_clippy_lint",
@@ -1268,7 +1268,6 @@ name = "error_index_generator"
 version = "0.0.0"
 dependencies = [
  "mdbook",
- "rustc_error_codes",
 ]
 
 [[package]]
@@ -2351,7 +2350,7 @@ dependencies = [
  "log",
  "memchr",
  "once_cell",
- "opener 0.6.1",
+ "opener",
  "pathdiff",
  "pulldown-cmark",
  "regex",
@@ -2596,9 +2595,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
 
 [[package]]
 name = "object"
-version = "0.32.1"
+version = "0.32.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
 dependencies = [
  "compiler_builtins",
  "crc32fast",
@@ -2628,16 +2627,6 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
 [[package]]
 name = "opener"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005"
-dependencies = [
- "bstr",
- "winapi",
-]
-
-[[package]]
-name = "opener"
 version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788"
@@ -3014,11 +3003,11 @@ dependencies = [
 
 [[package]]
 name = "pulldown-cmark"
-version = "0.9.3"
+version = "0.9.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
+checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
 dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.1",
  "memchr",
  "unicase",
 ]
@@ -3711,7 +3700,6 @@ dependencies = [
  "rustc_codegen_ssa",
  "rustc_const_eval",
  "rustc_data_structures",
- "rustc_error_codes",
  "rustc_errors",
  "rustc_expand",
  "rustc_feature",
@@ -3784,9 +3772,11 @@ dependencies = [
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
+ "rustc_error_codes",
  "rustc_error_messages",
  "rustc_fluent_macro",
  "rustc_hir",
+ "rustc_index",
  "rustc_lint_defs",
  "rustc_macros",
  "rustc_serialize",
@@ -4352,7 +4342,6 @@ dependencies = [
 name = "rustc_pattern_analysis"
 version = "0.0.0"
 dependencies = [
- "derivative",
  "rustc-hash",
  "rustc_apfloat",
  "rustc_arena",
@@ -4797,12 +4786,12 @@ checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
 
 [[package]]
 name = "ruzstd"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc"
+checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d"
 dependencies = [
  "byteorder",
- "thiserror-core",
+ "derive_more",
  "twox-hash",
 ]
 
@@ -5366,26 +5355,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "thiserror-core"
-version = "1.0.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d97345f6437bb2004cd58819d8a9ef8e36cdd7661c2abc4bbde0a7c40d9f497"
-dependencies = [
- "thiserror-core-impl",
-]
-
-[[package]]
-name = "thiserror-core-impl"
-version = "1.0.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10ac1c5050e43014d16b2f94d0d2ce79e65ffdd8b38d8048f9c8f6a8a6da62ac"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
 name = "thiserror-impl"
 version = "1.0.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5757,9 +5726,9 @@ dependencies = [
 
 [[package]]
 name = "unic-langid"
-version = "0.9.1"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f"
+checksum = "238722e6d794ed130f91f4ea33e01fcff4f188d92337a21297892521c72df516"
 dependencies = [
  "unic-langid-impl",
  "unic-langid-macros",
@@ -5767,18 +5736,18 @@ dependencies = [
 
 [[package]]
 name = "unic-langid-impl"
-version = "0.9.1"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff"
+checksum = "4bd55a2063fdea4ef1f8633243a7b0524cbeef1905ae04c31a1c9b9775c55bc6"
 dependencies = [
  "tinystr",
 ]
 
 [[package]]
 name = "unic-langid-macros"
-version = "0.9.1"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "055e618bf694161ffff0466d95cef3e1a5edc59f6ba1888e97801f2b4ebdc4fe"
+checksum = "5c854cefb82ff2816410ce606acbad1b3af065140907b29be9229040752b83ec"
 dependencies = [
  "proc-macro-hack",
  "tinystr",
@@ -5788,13 +5757,13 @@ dependencies = [
 
 [[package]]
 name = "unic-langid-macros-impl"
-version = "0.9.1"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8"
+checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.32",
  "unic-langid-impl",
 ]
 
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 7e713a49a8c..76d838308b4 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -13,13 +13,11 @@
 #![feature(rustdoc_internals)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
-#![feature(const_trait_impl)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(stmt_expr_attributes)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 7b781ba1e11..aaeb1bb9bff 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -3,8 +3,7 @@
 use crate::ast::{self, LitKind, MetaItemLit, StrStyle};
 use crate::token::{self, Token};
 use rustc_lexer::unescape::{
-    byte_from_char, unescape_byte, unescape_c_string, unescape_char, unescape_literal, CStrUnit,
-    Mode,
+    byte_from_char, unescape_byte, unescape_char, unescape_mixed, unescape_unicode, MixedUnit, Mode,
 };
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
@@ -48,6 +47,9 @@ impl LitKind {
             return Err(LitError::InvalidSuffix);
         }
 
+        // For byte/char/string literals, chars and escapes have already been
+        // checked in the lexer (in `cook_lexer_literal`). So we can assume all
+        // chars and escapes are valid here.
         Ok(match kind {
             token::Bool => {
                 assert!(symbol.is_bool_lit());
@@ -56,12 +58,12 @@ impl LitKind {
             token::Byte => {
                 return unescape_byte(symbol.as_str())
                     .map(LitKind::Byte)
-                    .map_err(|_| LitError::LexerError);
+                    .map_err(|_| panic!("failed to unescape byte literal"));
             }
             token::Char => {
                 return unescape_char(symbol.as_str())
                     .map(LitKind::Char)
-                    .map_err(|_| LitError::LexerError);
+                    .map_err(|_| panic!("failed to unescape char literal"));
             }
 
             // There are some valid suffixes for integer and float literals,
@@ -77,26 +79,22 @@ impl LitKind {
                 let s = symbol.as_str();
                 // Vanilla strings are so common we optimize for the common case where no chars
                 // requiring special behaviour are present.
-                let symbol = if s.contains(['\\', '\r']) {
+                let symbol = if s.contains('\\') {
                     let mut buf = String::with_capacity(s.len());
-                    let mut error = Ok(());
                     // Force-inlining here is aggressive but the closure is
-                    // called on every char in the string, so it can be
-                    // hot in programs with many long strings.
-                    unescape_literal(
+                    // called on every char in the string, so it can be hot in
+                    // programs with many long strings containing escapes.
+                    unescape_unicode(
                         s,
                         Mode::Str,
                         &mut #[inline(always)]
-                        |_, unescaped_char| match unescaped_char {
+                        |_, c| match c {
                             Ok(c) => buf.push(c),
                             Err(err) => {
-                                if err.is_fatal() {
-                                    error = Err(LitError::LexerError);
-                                }
+                                assert!(!err.is_fatal(), "failed to unescape string literal")
                             }
                         },
                     );
-                    error?;
                     Symbol::intern(&buf)
                 } else {
                     symbol
@@ -104,86 +102,46 @@ impl LitKind {
                 LitKind::Str(symbol, ast::StrStyle::Cooked)
             }
             token::StrRaw(n) => {
-                // Raw strings have no escapes, so we only need to check for invalid chars, and we
-                // can reuse the symbol on success.
-                let mut error = Ok(());
-                unescape_literal(symbol.as_str(), Mode::RawStr, &mut |_, unescaped_char| {
-                    match unescaped_char {
-                        Ok(_) => {}
-                        Err(err) => {
-                            if err.is_fatal() {
-                                error = Err(LitError::LexerError);
-                            }
-                        }
-                    }
-                });
-                error?;
+                // Raw strings have no escapes so no work is needed here.
                 LitKind::Str(symbol, ast::StrStyle::Raw(n))
             }
             token::ByteStr => {
                 let s = symbol.as_str();
                 let mut buf = Vec::with_capacity(s.len());
-                let mut error = Ok(());
-                unescape_literal(s, Mode::ByteStr, &mut |_, c| match c {
+                unescape_unicode(s, Mode::ByteStr, &mut |_, c| match c {
                     Ok(c) => buf.push(byte_from_char(c)),
                     Err(err) => {
-                        if err.is_fatal() {
-                            error = Err(LitError::LexerError);
-                        }
+                        assert!(!err.is_fatal(), "failed to unescape string literal")
                     }
                 });
-                error?;
                 LitKind::ByteStr(buf.into(), StrStyle::Cooked)
             }
             token::ByteStrRaw(n) => {
-                // Raw strings have no escapes, so we only need to check for invalid chars, and we
-                // can convert the symbol directly to a `Lrc<u8>` on success.
-                let s = symbol.as_str();
-                let mut error = Ok(());
-                unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
-                    Ok(_) => {}
-                    Err(err) => {
-                        if err.is_fatal() {
-                            error = Err(LitError::LexerError);
-                        }
-                    }
-                });
-                LitKind::ByteStr(s.to_owned().into_bytes().into(), StrStyle::Raw(n))
+                // Raw strings have no escapes so we can convert the symbol
+                // directly to a `Lrc<u8>`.
+                let buf = symbol.as_str().to_owned().into_bytes();
+                LitKind::ByteStr(buf.into(), StrStyle::Raw(n))
             }
             token::CStr => {
                 let s = symbol.as_str();
                 let mut buf = Vec::with_capacity(s.len());
-                let mut error = Ok(());
-                unescape_c_string(s, Mode::CStr, &mut |_span, c| match c {
-                    Ok(CStrUnit::Byte(b)) => buf.push(b),
-                    Ok(CStrUnit::Char(c)) => {
+                unescape_mixed(s, Mode::CStr, &mut |_span, c| match c {
+                    Ok(MixedUnit::Char(c)) => {
                         buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
                     }
+                    Ok(MixedUnit::HighByte(b)) => buf.push(b),
                     Err(err) => {
-                        if err.is_fatal() {
-                            error = Err(LitError::LexerError);
-                        }
+                        assert!(!err.is_fatal(), "failed to unescape C string literal")
                     }
                 });
-                error?;
                 buf.push(0);
                 LitKind::CStr(buf.into(), StrStyle::Cooked)
             }
             token::CStrRaw(n) => {
-                // Raw strings have no escapes, so we only need to check for invalid chars, and we
-                // can convert the symbol directly to a `Lrc<u8>` on success.
-                let s = symbol.as_str();
-                let mut error = Ok(());
-                unescape_c_string(s, Mode::RawCStr, &mut |_, c| match c {
-                    Ok(_) => {}
-                    Err(err) => {
-                        if err.is_fatal() {
-                            error = Err(LitError::LexerError);
-                        }
-                    }
-                });
-                error?;
-                let mut buf = s.to_owned().into_bytes();
+                // Raw strings have no escapes so we can convert the symbol
+                // directly to a `Lrc<u8>` after appending the terminating NUL
+                // char.
+                let mut buf = symbol.as_str().to_owned().into_bytes();
                 buf.push(0);
                 LitKind::CStr(buf.into(), StrStyle::Raw(n))
             }
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 4843d36372d..51bb8a96fad 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -1,9 +1,9 @@
-use rustc_errors::DiagnosticArgFromDisplay;
+use rustc_errors::{codes::*, DiagnosticArgFromDisplay};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_generic_type_with_parentheses, code = "E0214")]
+#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
 pub struct GenericTypeWithParentheses {
     #[primary_span]
     #[label]
@@ -22,7 +22,7 @@ pub struct UseAngleBrackets {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_abi, code = "E0703")]
+#[diag(ast_lowering_invalid_abi, code = E0703)]
 #[note]
 pub struct InvalidAbi {
     #[primary_span]
@@ -89,7 +89,7 @@ pub enum AssocTyParenthesesSub {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_lowering_misplaced_impl_trait, code = "E0562")]
+#[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
 #[note]
 pub struct MisplacedImplTrait<'a> {
     #[primary_span]
@@ -114,7 +114,7 @@ pub struct UnderscoreExprLhsAssign {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_base_expression_double_dot, code = "E0797")]
+#[diag(ast_lowering_base_expression_double_dot, code = E0797)]
 pub struct BaseExpressionDoubleDot {
     #[primary_span]
     #[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")]
@@ -122,7 +122,7 @@ pub struct BaseExpressionDoubleDot {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = "E0728")]
+#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
 pub struct AwaitOnlyInAsyncFnAndBlocks {
     #[primary_span]
     #[label]
@@ -132,14 +132,14 @@ pub struct AwaitOnlyInAsyncFnAndBlocks {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_coroutine_too_many_parameters, code = "E0628")]
+#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
 pub struct CoroutineTooManyParameters {
     #[primary_span]
     pub fn_decl_span: Span,
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_closure_cannot_be_static, code = "E0697")]
+#[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
 pub struct ClosureCannotBeStatic {
     #[primary_span]
     pub fn_decl_span: Span,
@@ -154,14 +154,14 @@ pub struct FunctionalRecordUpdateDestructuringAssignment {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_async_coroutines_not_supported, code = "E0727")]
+#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
 pub struct AsyncCoroutinesNotSupported {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_inline_asm_unsupported_target, code = "E0472")]
+#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
 pub struct InlineAsmUnsupportedTarget {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index cc172b37657..0ad4a59c17e 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -153,7 +153,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Let(pat, scrutinee, span, is_recovered) => {
                     hir::ExprKind::Let(self.arena.alloc(hir::Let {
-                        hir_id: self.next_id(),
                         span: self.lower_span(*span),
                         pat: self.lower_pat(pat),
                         ty: None,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 057fe65d0af..3621844efc8 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -33,10 +33,8 @@
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
-#![feature(if_let_guard)]
 #![feature(box_patterns)]
 #![feature(let_chains)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
@@ -2307,7 +2305,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         match c.value.kind {
             ExprKind::Underscore => {
                 if self.tcx.features().generic_arg_infer {
-                    hir::ArrayLen::Infer(self.lower_node_id(c.id), self.lower_span(c.value.span))
+                    hir::ArrayLen::Infer(hir::InferArg {
+                        hir_id: self.lower_node_id(c.id),
+                        span: self.lower_span(c.value.span),
+                    })
                 } else {
                     feature_err(
                         &self.tcx.sess,
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index e2b8e64b115..5f54a0ddf8c 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1,7 +1,7 @@
 //! Errors emitted by ast_passes.
 
 use rustc_ast::ParamKindOrd;
-use rustc_errors::{AddToDiagnostic, Applicability};
+use rustc_errors::{codes::*, AddToDiagnostic, Applicability};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
@@ -23,7 +23,7 @@ pub struct InvalidLabel {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_visibility_not_permitted, code = "E0449")]
+#[diag(ast_passes_visibility_not_permitted, code = E0449)]
 pub struct VisibilityNotPermitted {
     #[primary_span]
     pub span: Span,
@@ -44,7 +44,7 @@ pub enum VisibilityNotPermittedNote {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_trait_fn_const, code = "E0379")]
+#[diag(ast_passes_trait_fn_const, code = E0379)]
 pub struct TraitFnConst {
     #[primary_span]
     #[label]
@@ -302,14 +302,14 @@ pub struct ItemUnderscore<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_nomangle_ascii, code = "E0754")]
+#[diag(ast_passes_nomangle_ascii, code = E0754)]
 pub struct NoMangleAscii {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_module_nonascii, code = "E0754")]
+#[diag(ast_passes_module_nonascii, code = E0754)]
 #[help]
 pub struct ModuleNonAscii {
     #[primary_span]
@@ -318,7 +318,7 @@ pub struct ModuleNonAscii {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_auto_generic, code = "E0567")]
+#[diag(ast_passes_auto_generic, code = E0567)]
 pub struct AutoTraitGeneric {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
@@ -328,7 +328,7 @@ pub struct AutoTraitGeneric {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_auto_super_lifetime, code = "E0568")]
+#[diag(ast_passes_auto_super_lifetime, code = E0568)]
 pub struct AutoTraitBounds {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
@@ -338,7 +338,7 @@ pub struct AutoTraitBounds {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_auto_items, code = "E0380")]
+#[diag(ast_passes_auto_items, code = E0380)]
 pub struct AutoTraitItems {
     #[primary_span]
     pub spans: Vec<Span>,
@@ -384,28 +384,28 @@ impl AddToDiagnostic for EmptyLabelManySpans {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_fn_pointer, code = "E0561")]
+#[diag(ast_passes_pattern_in_fn_pointer, code = E0561)]
 pub struct PatternFnPointer {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_trait_object_single_bound, code = "E0226")]
+#[diag(ast_passes_trait_object_single_bound, code = E0226)]
 pub struct TraitObjectBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_impl_trait_path, code = "E0667")]
+#[diag(ast_passes_impl_trait_path, code = E0667)]
 pub struct ImplTraitPath {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_nested_impl_trait, code = "E0666")]
+#[diag(ast_passes_nested_impl_trait, code = E0666)]
 pub struct NestedImplTrait {
     #[primary_span]
     pub span: Span,
@@ -443,7 +443,7 @@ pub struct ObsoleteAuto {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_unsafe_negative_impl, code = "E0198")]
+#[diag(ast_passes_unsafe_negative_impl, code = E0198)]
 pub struct UnsafeNegativeImpl {
     #[primary_span]
     pub span: Span,
@@ -468,7 +468,7 @@ pub struct InherentImplCannot<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_inherent_cannot_be, code = "E0197")]
+#[diag(ast_passes_inherent_cannot_be, code = E0197)]
 pub struct InherentImplCannotUnsafe<'a> {
     #[primary_span]
     pub span: Span,
@@ -536,7 +536,7 @@ pub struct GenericDefaultTrailing {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_nested_lifetimes, code = "E0316")]
+#[diag(ast_passes_nested_lifetimes, code = E0316)]
 pub struct NestedLifetimes {
     #[primary_span]
     pub span: Span,
@@ -655,7 +655,7 @@ pub struct ConstAndCVariadic {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_foreign, code = "E0130")]
+#[diag(ast_passes_pattern_in_foreign, code = E0130)]
 pub struct PatternInForeign {
     #[primary_span]
     #[label]
@@ -663,7 +663,7 @@ pub struct PatternInForeign {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_bodiless, code = "E0642")]
+#[diag(ast_passes_pattern_in_bodiless, code = E0642)]
 pub struct PatternInBodiless {
     #[primary_span]
     #[label]
@@ -711,14 +711,14 @@ pub struct AssociatedSuggestion2 {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_stability_outside_std, code = "E0734")]
+#[diag(ast_passes_stability_outside_std, code = E0734)]
 pub struct StabilityOutsideStd {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_feature_on_non_nightly, code = "E0554")]
+#[diag(ast_passes_feature_on_non_nightly, code = E0554)]
 pub struct FeatureOnNonNightly {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index ba09183374e..fa6cdd55c3d 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -11,7 +11,6 @@
 #![feature(if_let_guard)]
 #![feature(iter_is_partitioned)]
 #![feature(let_chains)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 100b2988982..61617beb86b 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -4,8 +4,6 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(box_patterns)]
-#![feature(let_chains)]
-#![recursion_limit = "256"]
 
 mod helpers;
 pub mod pp;
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index c2fd4558fd7..a6f6f0b29a0 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -160,6 +160,10 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
     use TokenTree::Delimited as Del;
     use TokenTree::Token as Tok;
 
+    fn is_punct(tt: &TokenTree) -> bool {
+        matches!(tt, TokenTree::Token(tok, _) if tok.is_punct())
+    }
+
     // Each match arm has one or more examples in comments. The default is to
     // insert space between adjacent tokens, except for the cases listed in
     // this match.
@@ -167,24 +171,35 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
         // No space after line doc comments.
         (Tok(Token { kind: DocComment(CommentKind::Line, ..), .. }, _), _) => false,
 
-        // `.` + ANYTHING: `x.y`, `tup.0`
-        // `$` + ANYTHING: `$e`
-        (Tok(Token { kind: Dot | Dollar, .. }, _), _) => false,
-
-        // ANYTHING + `,`: `foo,`
-        // ANYTHING + `.`: `x.y`, `tup.0`
-        // ANYTHING + `!`: `foo! { ... }`
-        //
-        // FIXME: Incorrect cases:
-        // - Logical not: `x =! y`, `if! x { f(); }`
-        // - Never type: `Fn() ->!`
-        (_, Tok(Token { kind: Comma | Dot | Not, .. }, _)) => false,
-
-        // IDENT + `(`: `f(3)`
-        //
-        // FIXME: Incorrect cases:
-        // - Let: `let(a, b) = (1, 2)`
-        (Tok(Token { kind: Ident(..), .. }, _), Del(_, _, Parenthesis, _)) => false,
+        // `.` + NON-PUNCT: `x.y`, `tup.0`
+        (Tok(Token { kind: Dot, .. }, _), tt2) if !is_punct(tt2) => false,
+
+        // `$` + IDENT: `$e`
+        (Tok(Token { kind: Dollar, .. }, _), Tok(Token { kind: Ident(..), .. }, _)) => false,
+
+        // NON-PUNCT + `,`: `foo,`
+        // NON-PUNCT + `;`: `x = 3;`, `[T; 3]`
+        // NON-PUNCT + `.`: `x.y`, `tup.0`
+        (tt1, Tok(Token { kind: Comma | Semi | Dot, .. }, _)) if !is_punct(tt1) => false,
+
+        // IDENT + `!`: `println!()`, but `if !x { ... }` needs a space after the `if`
+        (Tok(Token { kind: Ident(sym, is_raw), span }, _), Tok(Token { kind: Not, .. }, _))
+            if !Ident::new(*sym, *span).is_reserved() || *is_raw =>
+        {
+            false
+        }
+
+        // IDENT|`fn`|`Self`|`pub` + `(`: `f(3)`, `fn(x: u8)`, `Self()`, `pub(crate)`,
+        //      but `let (a, b) = (1, 2)` needs a space after the `let`
+        (Tok(Token { kind: Ident(sym, is_raw), span }, _), Del(_, _, Parenthesis, _))
+            if !Ident::new(*sym, *span).is_reserved()
+                || *sym == kw::Fn
+                || *sym == kw::SelfUpper
+                || *sym == kw::Pub
+                || *is_raw =>
+        {
+            false
+        }
 
         // `#` + `[`: `#[attr]`
         (Tok(Token { kind: Pound, .. }, _), Del(_, _, Bracket, _)) => false,
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index 315a00c8d2f..79370602842 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -2,8 +2,7 @@ use std::num::IntErrorKind;
 
 use rustc_ast as ast;
 use rustc_errors::{
-    error_code, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
-    Level,
+    codes::*, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
@@ -12,14 +11,14 @@ use crate::fluent_generated as fluent;
 use crate::UnsupportedLiteralReason;
 
 #[derive(Diagnostic)]
-#[diag(attr_expected_one_cfg_pattern, code = "E0536")]
+#[diag(attr_expected_one_cfg_pattern, code = E0536)]
 pub(crate) struct ExpectedOneCfgPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_predicate, code = "E0537")]
+#[diag(attr_invalid_predicate, code = E0537)]
 pub(crate) struct InvalidPredicate {
     #[primary_span]
     pub span: Span,
@@ -28,7 +27,7 @@ pub(crate) struct InvalidPredicate {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_multiple_item, code = "E0538")]
+#[diag(attr_multiple_item, code = E0538)]
 pub(crate) struct MultipleItem {
     #[primary_span]
     pub span: Span,
@@ -37,7 +36,7 @@ pub(crate) struct MultipleItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_meta_item, code = "E0539")]
+#[diag(attr_incorrect_meta_item, code = E0539)]
 pub(crate) struct IncorrectMetaItem {
     #[primary_span]
     pub span: Span,
@@ -56,7 +55,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> {
         let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
         DiagnosticBuilder::new(dcx, level, fluent::attr_unknown_meta_item)
             .with_span(self.span)
-            .with_code(error_code!(E0541))
+            .with_code(E0541)
             .with_arg("item", self.item)
             .with_arg("expected", expected.join(", "))
             .with_span_label(self.span, fluent::attr_label)
@@ -64,28 +63,28 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_since, code = "E0542")]
+#[diag(attr_missing_since, code = E0542)]
 pub(crate) struct MissingSince {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_note, code = "E0543")]
+#[diag(attr_missing_note, code = E0543)]
 pub(crate) struct MissingNote {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_multiple_stability_levels, code = "E0544")]
+#[diag(attr_multiple_stability_levels, code = E0544)]
 pub(crate) struct MultipleStabilityLevels {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_issue_string, code = "E0545")]
+#[diag(attr_invalid_issue_string, code = E0545)]
 pub(crate) struct InvalidIssueString {
     #[primary_span]
     pub span: Span,
@@ -143,21 +142,21 @@ impl InvalidIssueStringCause {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_feature, code = "E0546")]
+#[diag(attr_missing_feature, code = E0546)]
 pub(crate) struct MissingFeature {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_non_ident_feature, code = "E0546")]
+#[diag(attr_non_ident_feature, code = E0546)]
 pub(crate) struct NonIdentFeature {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_issue, code = "E0547")]
+#[diag(attr_missing_issue, code = E0547)]
 pub(crate) struct MissingIssue {
     #[primary_span]
     pub span: Span,
@@ -166,14 +165,14 @@ pub(crate) struct MissingIssue {
 // FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
 // It is more similar to `IncorrectReprFormatGeneric`.
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")]
+#[diag(attr_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)]
 pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_hint_no_paren, code = "E0552")]
+#[diag(attr_invalid_repr_hint_no_paren, code = E0552)]
 pub(crate) struct InvalidReprHintNoParen {
     #[primary_span]
     pub span: Span,
@@ -182,7 +181,7 @@ pub(crate) struct InvalidReprHintNoParen {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_hint_no_value, code = "E0552")]
+#[diag(attr_invalid_repr_hint_no_value, code = E0552)]
 pub(crate) struct InvalidReprHintNoValue {
     #[primary_span]
     pub span: Span,
@@ -215,7 +214,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnsupportedLiteral {
             },
         );
         diag.span(self.span);
-        diag.code(error_code!(E0565));
+        diag.code(E0565);
         if self.is_bytestr {
             diag.span_suggestion(
                 self.start_point_span,
@@ -229,7 +228,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnsupportedLiteral {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_align_need_arg, code = "E0589")]
+#[diag(attr_invalid_repr_align_need_arg, code = E0589)]
 pub(crate) struct InvalidReprAlignNeedArg {
     #[primary_span]
     #[suggestion(code = "align(...)", applicability = "has-placeholders")]
@@ -237,7 +236,7 @@ pub(crate) struct InvalidReprAlignNeedArg {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_generic, code = "E0589")]
+#[diag(attr_invalid_repr_generic, code = E0589)]
 pub(crate) struct InvalidReprGeneric<'a> {
     #[primary_span]
     pub span: Span,
@@ -247,14 +246,14 @@ pub(crate) struct InvalidReprGeneric<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_repr_format_align_one_arg, code = "E0693")]
+#[diag(attr_incorrect_repr_format_align_one_arg, code = E0693)]
 pub(crate) struct IncorrectReprFormatAlignOneArg {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_repr_format_generic, code = "E0693")]
+#[diag(attr_incorrect_repr_format_generic, code = E0693)]
 pub(crate) struct IncorrectReprFormatGeneric<'a> {
     #[primary_span]
     pub span: Span,
@@ -305,14 +304,14 @@ impl<'a> IncorrectReprFormatGenericCause<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_rustc_promotable_pairing, code = "E0717")]
+#[diag(attr_rustc_promotable_pairing, code = E0717)]
 pub(crate) struct RustcPromotablePairing {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_rustc_allowed_unstable_pairing, code = "E0789")]
+#[diag(attr_rustc_allowed_unstable_pairing, code = E0789)]
 pub(crate) struct RustcAllowedUnstablePairing {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 351976cdaea..8a275a83630 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{struct_span_code_err, DiagCtxt, DiagnosticBuilder};
+use rustc_errors::{codes::*, struct_span_code_err, DiagCtxt, DiagnosticBuilder};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index da67862a48d..2e83072b8d1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -3,7 +3,9 @@
 use either::Either;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 4cb49362863..15e1066e983 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -188,7 +188,7 @@ impl Display for RegionName {
 }
 
 impl rustc_errors::IntoDiagnosticArg for RegionName {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 177fc1deca1..ea48e78509b 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -8,12 +8,9 @@
 #![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(never_type)]
-#![feature(lazy_cell)]
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
-#![feature(trusted_step)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index e321b92603d..1685624f247 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -1,4 +1,4 @@
-use rustc_errors::MultiSpan;
+use rustc_errors::{codes::*, MultiSpan};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{GenericArg, Ty};
 use rustc_span::Span;
@@ -6,7 +6,7 @@ use rustc_span::Span;
 use crate::diagnostics::RegionName;
 
 #[derive(Diagnostic)]
-#[diag(borrowck_move_unsized, code = "E0161")]
+#[diag(borrowck_move_unsized, code = E0161)]
 pub(crate) struct MoveUnsized<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
@@ -281,7 +281,7 @@ pub(crate) enum CaptureVarCause {
 }
 
 #[derive(Diagnostic)]
-#[diag(borrowck_cannot_move_when_borrowed, code = "E0505")]
+#[diag(borrowck_cannot_move_when_borrowed, code = E0505)]
 pub(crate) struct MoveBorrow<'a> {
     pub place: &'a str,
     pub borrow_place: &'a str,
@@ -294,7 +294,7 @@ pub(crate) struct MoveBorrow<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(borrowck_opaque_type_non_generic_param, code = "E0792")]
+#[diag(borrowck_opaque_type_non_generic_param, code = E0792)]
 pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
     pub ty: GenericArg<'tcx>,
     pub kind: &'a str,
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 21d8026e170..52559f9039b 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -33,7 +33,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
     /// our special inference variable there, we would mess that up.
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
     implicit_region_bound: ty::Region<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
+    known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
     locations: Locations,
     span: Span,
     category: ConstraintCategory<'tcx>,
@@ -47,7 +47,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         universal_regions: &'a UniversalRegions<'tcx>,
         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
         implicit_region_bound: ty::Region<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
+        known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
         locations: Locations,
         span: Span,
         category: ConstraintCategory<'tcx>,
@@ -59,7 +59,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
             universal_regions,
             region_bound_pairs,
             implicit_region_bound,
-            param_env,
+            known_type_outlives_obligations,
             locations,
             span,
             category,
@@ -136,7 +136,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
 
         // Extract out various useful fields we'll need below.
         let ConstraintConversion {
-            tcx, region_bound_pairs, implicit_region_bound, param_env, ..
+            tcx,
+            region_bound_pairs,
+            implicit_region_bound,
+            known_type_outlives_obligations,
+            ..
         } = *self;
 
         let ty::OutlivesPredicate(k1, r2) = predicate;
@@ -157,7 +161,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
                     tcx,
                     region_bound_pairs,
                     Some(implicit_region_bound),
-                    param_env,
+                    known_type_outlives_obligations,
                 )
                 .type_must_outlive(origin, t1, r2, constraint_category);
             }
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 011b5b760c2..d518f54fd25 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -45,12 +45,14 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
 pub(crate) struct CreateResult<'tcx> {
     pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
     pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
+    pub(crate) known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
     pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
 }
 
 pub(crate) fn create<'tcx>(
     infcx: &InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
+    known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
     implicit_region_bound: ty::Region<'tcx>,
     universal_regions: &Rc<UniversalRegions<'tcx>>,
     constraints: &mut MirTypeckRegionConstraints<'tcx>,
@@ -58,6 +60,7 @@ pub(crate) fn create<'tcx>(
     UniversalRegionRelationsBuilder {
         infcx,
         param_env,
+        known_type_outlives_obligations,
         implicit_region_bound,
         constraints,
         universal_regions: universal_regions.clone(),
@@ -175,6 +178,7 @@ impl UniversalRegionRelations<'_> {
 struct UniversalRegionRelationsBuilder<'this, 'tcx> {
     infcx: &'this InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
+    known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
     universal_regions: Rc<UniversalRegions<'tcx>>,
     implicit_region_bound: ty::Region<'tcx>,
     constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
@@ -200,7 +204,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         let defining_ty_def_id = self.universal_regions.defining_ty.def_id().expect_local();
         let span = tcx.def_span(defining_ty_def_id);
 
-        // Insert the facts we know from the predicates. Why? Why not.
+        // Insert the `'a: 'b` we know from the predicates.
+        // This does not consider the type-outlives.
         let param_env = self.param_env;
         self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
 
@@ -308,6 +313,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 outlives: self.outlives.freeze(),
                 inverse_outlives: self.inverse_outlives.freeze(),
             }),
+            known_type_outlives_obligations: self.known_type_outlives_obligations,
             region_bound_pairs: self.region_bound_pairs,
             normalized_inputs_and_output,
         }
@@ -322,7 +328,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
             &self.universal_regions,
             &self.region_bound_pairs,
             self.implicit_region_bound,
-            self.param_env,
+            self.known_type_outlives_obligations,
             Locations::All(span),
             span,
             ConstraintCategory::Internal,
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index cf28e62177f..59c4d9a6c78 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -152,9 +152,14 @@ pub(crate) fn type_check<'mir, 'tcx>(
         universal_region_relations,
         region_bound_pairs,
         normalized_inputs_and_output,
+        known_type_outlives_obligations,
     } = free_region_relations::create(
         infcx,
         param_env,
+        // FIXME(-Znext-solver): These are unnormalized. Normalize them.
+        infcx.tcx.arena.alloc_from_iter(
+            param_env.caller_bounds().iter().filter_map(|clause| clause.as_type_outlives_clause()),
+        ),
         implicit_region_bound,
         universal_regions,
         &mut constraints,
@@ -176,6 +181,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
         body,
         param_env,
         &region_bound_pairs,
+        known_type_outlives_obligations,
         implicit_region_bound,
         &mut borrowck_context,
     );
@@ -850,6 +856,7 @@ struct TypeChecker<'a, 'tcx> {
     /// all of the promoted items.
     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
+    known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
     implicit_region_bound: ty::Region<'tcx>,
     reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
@@ -1000,6 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         body: &'a Body<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
+        known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
         implicit_region_bound: ty::Region<'tcx>,
         borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
     ) -> Self {
@@ -1010,6 +1018,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             user_type_annotations: &body.user_type_annotations,
             param_env,
             region_bound_pairs,
+            known_type_outlives_obligations,
             implicit_region_bound,
             borrowck_context,
             reported_errors: Default::default(),
@@ -1099,10 +1108,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn check_user_type_annotations(&mut self) {
         debug!(?self.user_type_annotations);
+        let tcx = self.tcx();
         for user_annotation in self.user_type_annotations {
             let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
             let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
-            self.ascribe_user_type(inferred_ty, annotation, span);
+            if let ty::UserType::TypeOf(def, args) = annotation
+                && let DefKind::InlineConst = tcx.def_kind(def)
+            {
+                self.check_inline_const(inferred_ty, def.expect_local(), args, span);
+            } else {
+                self.ascribe_user_type(inferred_ty, annotation, span);
+            }
         }
     }
 
@@ -1120,7 +1136,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             self.borrowck_context.universal_regions,
             self.region_bound_pairs,
             self.implicit_region_bound,
-            self.param_env,
+            self.known_type_outlives_obligations,
             locations,
             locations.span(self.body),
             category,
@@ -1195,6 +1211,36 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         Ok(())
     }
 
+    fn check_inline_const(
+        &mut self,
+        inferred_ty: Ty<'tcx>,
+        def_id: LocalDefId,
+        args: UserArgs<'tcx>,
+        span: Span,
+    ) {
+        assert!(args.user_self_ty.is_none());
+        let tcx = self.tcx();
+        let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args);
+        if let Err(terr) =
+            self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring)
+        {
+            span_bug!(
+                span,
+                "bad inline const pattern: ({:?} = {:?}) {:?}",
+                const_ty,
+                inferred_ty,
+                terr
+            );
+        }
+        let args = self.infcx.resolve_vars_if_possible(args.args);
+        let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span));
+        self.normalize_and_prove_instantiated_predicates(
+            def_id.to_def_id(),
+            predicates,
+            Locations::All(span),
+        );
+    }
+
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
@@ -1851,7 +1897,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     let def_id = uv.def;
                     if tcx.def_kind(def_id) == DefKind::InlineConst {
                         let def_id = def_id.expect_local();
-                        let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
+                        let predicates = self.prove_closure_bounds(
+                            tcx,
+                            def_id,
+                            uv.args,
+                            location.to_locations(),
+                        );
                         self.normalize_and_prove_instantiated_predicates(
                             def_id.to_def_id(),
                             predicates,
@@ -2654,9 +2705,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             // desugaring. A closure gets desugared to a struct, and
             // these extra requirements are basically like where
             // clauses on the struct.
-            AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => {
-                (def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
-            }
+            AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => (
+                def_id,
+                self.prove_closure_bounds(
+                    tcx,
+                    def_id.expect_local(),
+                    args,
+                    location.to_locations(),
+                ),
+            ),
 
             AggregateKind::Array(_) | AggregateKind::Tuple => {
                 (CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
@@ -2675,7 +2732,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         tcx: TyCtxt<'tcx>,
         def_id: LocalDefId,
         args: GenericArgsRef<'tcx>,
-        location: Location,
+        locations: Locations,
     ) -> ty::InstantiatedPredicates<'tcx> {
         if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
             constraint_conversion::ConstraintConversion::new(
@@ -2683,8 +2740,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.borrowck_context.universal_regions,
                 self.region_bound_pairs,
                 self.implicit_region_bound,
-                self.param_env,
-                location.to_locations(),
+                self.known_type_outlives_obligations,
+                locations,
                 DUMMY_SP,                   // irrelevant; will be overridden.
                 ConstraintCategory::Boring, // same as above.
                 self.borrowck_context.constraints,
@@ -2710,7 +2767,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         if let Err(_) = self.eq_args(
             typeck_root_args,
             parent_args,
-            location.to_locations(),
+            locations,
             ConstraintCategory::BoringNoLocation,
         ) {
             span_mirbug!(
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index d6dfd0efaf9..eadb48ddd36 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -1,6 +1,6 @@
 use rustc_errors::{
-    AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
-    MultiSpan, SingleLabelManySpans,
+    codes::*, AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
+    Level, MultiSpan, SingleLabelManySpans,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
@@ -269,7 +269,7 @@ pub(crate) struct ConcatIdentsIdentArgs {
 }
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_bad_derive_target, code = "E0774")]
+#[diag(builtin_macros_bad_derive_target, code = E0774)]
 pub(crate) struct BadDeriveTarget {
     #[primary_span]
     #[label]
@@ -283,7 +283,7 @@ pub(crate) struct BadDeriveTarget {
 pub(crate) struct TestsNotSupport {}
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_unexpected_lit, code = "E0777")]
+#[diag(builtin_macros_unexpected_lit, code = E0777)]
 pub(crate) struct BadDeriveLit {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index eb331ef5853..b66f7111ff0 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -139,7 +139,7 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<
             _ => {
                 let expr = p.parse_expr()?;
                 if !args.named_args().is_empty() {
-                    ecx.dcx().emit_err(errors::PositionalAfterNamed {
+                    return Err(ecx.dcx().create_err(errors::PositionalAfterNamed {
                         span: expr.span,
                         args: args
                             .named_args()
@@ -147,7 +147,7 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<
                             .filter_map(|a| a.kind.ident().map(|ident| (a, ident)))
                             .map(|(arg, n)| n.span.to(arg.expr.span))
                             .collect(),
-                    });
+                    }));
                 }
                 args.add(FormatArgument { kind: FormatArgumentKind::Normal, expr });
             }
@@ -313,6 +313,8 @@ fn make_format_args(
     }
     use ArgRef::*;
 
+    let mut unnamed_arg_after_named_arg = false;
+
     let mut lookup_arg = |arg: ArgRef<'_>,
                           span: Option<Span>,
                           used_as: PositionUsedAs,
@@ -352,6 +354,7 @@ fn make_format_args(
                         // For the moment capturing variables from format strings expanded from macros is
                         // disabled (see RFC #2795)
                         ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name });
+                        unnamed_arg_after_named_arg = true;
                         DummyResult::raw_expr(span, true)
                     };
                     Ok(args.add(FormatArgument { kind: FormatArgumentKind::Captured(ident), expr }))
@@ -510,7 +513,8 @@ fn make_format_args(
         })
         .collect::<Vec<_>>();
 
-    if !unused.is_empty() {
+    let has_unused = !unused.is_empty();
+    if has_unused {
         // If there's a lot of unused arguments,
         // let's check if this format arguments looks like another syntax (printf / shell).
         let detect_foreign_fmt = unused.len() > args.explicit_args().len() / 2;
@@ -529,7 +533,7 @@ fn make_format_args(
 
     // Only check for unused named argument names if there are no other errors to avoid causing
     // too much noise in output errors, such as when a named argument is entirely unused.
-    if invalid_refs.is_empty() && ecx.dcx().has_errors().is_none() {
+    if invalid_refs.is_empty() && !has_unused && !unnamed_arg_after_named_arg {
         for &(index, span, used_as) in &numeric_refences_to_named_arg {
             let (position_sp_to_replace, position_sp_for_msg) = match used_as {
                 Placeholder(pspan) => (span, pspan),
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 3e9b06a5b05..4d7957ef4dd 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -5,17 +5,14 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(array_windows)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
 #![feature(if_let_guard)]
-#![feature(is_sorted)]
 #![feature(let_chains)]
 #![feature(lint_reasons)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
-#![recursion_limit = "256"]
 
 extern crate proc_macro;
 
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
index bd3b051185b..e6bf944f552 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
@@ -33,14 +33,14 @@ jobs:
               TARGET_TRIPLE: x86_64-pc-windows-gnu
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: CPU features
       if: matrix.os == 'ubuntu-latest'
       run: cat /proc/cpuinfo
 
     - name: Cache cargo target dir
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: build/cg_clif
         key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml
index 3efdec41559..b4f8ce0f532 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml
@@ -10,7 +10,7 @@ jobs:
   audit:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - run: |
           sed -i 's/components.*/components = []/' rust-toolchain
           echo 'profile = "minimal"' >> rust-toolchain
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index 9bbb18fc37f..cf9a105538d 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -10,7 +10,7 @@ jobs:
     timeout-minutes: 10
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: Avoid installing rustc-dev
       run: |
@@ -64,14 +64,14 @@ jobs:
               TARGET_TRIPLE: x86_64-pc-windows-gnu
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: CPU features
       if: matrix.os == 'ubuntu-latest'
       run: cat /proc/cpuinfo
 
     - name: Cache cargo target dir
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: build/cg_clif
         key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
@@ -138,7 +138,7 @@ jobs:
         shell: bash
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: CPU features
       run: cat /proc/cpuinfo
@@ -164,13 +164,13 @@ jobs:
         shell: bash
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: CPU features
       run: cat /proc/cpuinfo
 
     - name: Cache cargo target dir
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: build/cg_clif
         key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
@@ -221,10 +221,10 @@ jobs:
               TARGET_TRIPLE: x86_64-pc-windows-gnu
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: Cache cargo target dir
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: build/cg_clif
         key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
@@ -276,7 +276,7 @@ jobs:
       cancel-in-progress: true
 
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: Download all built artifacts
         uses: actions/download-artifact@v4
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
index 8085dc58263..930d025b73e 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
@@ -9,13 +9,13 @@ jobs:
     timeout-minutes: 60
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: CPU features
       run: cat /proc/cpuinfo
 
     - name: Cache cargo target dir
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: build/cg_clif
         key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
@@ -32,13 +32,13 @@ jobs:
     timeout-minutes: 60
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: CPU features
       run: cat /proc/cpuinfo
 
     - name: Cache cargo target dir
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: build/cg_clif
         key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
diff --git a/compiler/rustc_codegen_cranelift/.vscode/settings.json b/compiler/rustc_codegen_cranelift/.vscode/settings.json
index 834a1362caf..491646ce59b 100644
--- a/compiler/rustc_codegen_cranelift/.vscode/settings.json
+++ b/compiler/rustc_codegen_cranelift/.vscode/settings.json
@@ -1,8 +1,9 @@
 {
     "editor.formatOnSave": true,
 
-    // source for rustc_* is not included in the rust-src component; disable the errors about this
+    // in case rustc.source is disabled for performance reasons; disable the errors about this
     "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
+    "rust-analyzer.rustc.source": "discover",
     "rust-analyzer.imports.granularity.enforce": true,
     "rust-analyzer.imports.granularity.group": "module",
     "rust-analyzer.imports.prefix": "crate",
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index 6d6a1200f50..86bc7d0f067 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -45,18 +45,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c22542c0b95bd3302f7ed6839869c561f2324bac2fd5e7e99f5cfa65fdc8b92"
+checksum = "d819feeda4c420a18f1e28236ca0ce1177b22bf7c8a44ddee92dfe40de15bcf0"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b3db903ef2e9c8a4de2ea6db5db052c7857282952f9df604aa55d169e6000d8"
+checksum = "e9b8d03d5bdbca7e5f72b0e0a0f69933ed1f09e24be6c075aa6fe3f802b0cc0c"
 dependencies = [
  "bumpalo",
  "cranelift-bforest",
@@ -75,39 +75,39 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6590feb5a1d6438f974bf6a5ac4dddf69fca14e1f07f3265d880f69e61a94463"
+checksum = "a3fd3664e38e51649b17dc30cfdd561273fe2f590dcd013fb75d9eabc6272dfb"
 dependencies = [
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7239038c56fafe77fddc8788fc8533dd6c474dc5bdc5637216404f41ba807330"
+checksum = "4b031ec5e605828975952622b5a77d49126f20ffe88d33719a0af66b23a0fc36"
 
 [[package]]
 name = "cranelift-control"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7dc9c595341404d381d27a3d950160856b35b402275f0c3990cd1ad683c8053"
+checksum = "fada054d017cf2ed8f7ed2336e0517fc1b19e6825be1790de9eb00c94788362b"
 dependencies = [
  "arbitrary",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44e3ee532fc4776c69bcedf7e62f9632cbb3f35776fa9a525cdade3195baa3f7"
+checksum = "177b6f94ae8de6348eb45bf977c79ab9e3c40fc3ac8cb7ed8109560ea39bee7d"
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a612c94d09e653662ec37681dc2d6fd2b9856e6df7147be0afc9aabb0abf19df"
+checksum = "ebebd23a69a23e3ddea78e98ff3a2de222e88c8e045d81ef4a72f042e0d79dbd"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -117,15 +117,15 @@ dependencies = [
 
 [[package]]
 name = "cranelift-isle"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85db9830abeb1170b7d29b536ffd55af1d4d26ac8a77570b5d1aca003bf225cc"
+checksum = "1571bfc14df8966d12c6121b5325026591a4b4009e22fea0fe3765ab7cd33b96"
 
 [[package]]
 name = "cranelift-jit"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4946271f1055e26544ef8c90fa24776f201566419dfac4b3962c39d5a804ff67"
+checksum = "2f61e236d7622c3c43016e8b0f3ba27136e21ac7de328c7fda902e61db1de851"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -138,14 +138,14 @@ dependencies = [
  "region",
  "target-lexicon",
  "wasmtime-jit-icache-coherence",
- "windows-sys",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
 name = "cranelift-module"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7e3bdae2597556e59edeb8ecb62eb32c7e054c4f042d393732902979db69c3"
+checksum = "f30c6820342015c5009070e3e48d1da7b13521399de904663f1c84f5ee839657"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -154,9 +154,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "301ef0edafeaeda5771a5d2db64ac53e1818ae3111220a185677025fe91db4a1"
+checksum = "35a69c37e0c10b46fe5527f2397ac821046efbf5f7ec112c8b84df25712f465b"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -165,9 +165,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.103.0"
+version = "0.104.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59e0ee3d013728903e0c513c31afa389b559bfd4fe8a44f80335c799e3132a41"
+checksum = "24425a329b4343177d5f1852243841dcec17f929d72c0e7f41262140155e55e7"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -251,7 +251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
 dependencies = [
  "cfg-if",
- "windows-sys",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]
@@ -374,13 +374,13 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "wasmtime-jit-icache-coherence"
-version = "16.0.0"
+version = "17.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b6d197fcc34ad32ed440e1f9552fd57d1f377d9699d31dee1b5b457322c1f8a"
+checksum = "bdc26415bb89e9ccd3bdc498fef63aabf665c4c0dd710c107691deb9694955da"
 dependencies = [
  "cfg-if",
  "libc",
- "windows-sys",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -411,7 +411,16 @@ version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.0",
 ]
 
 [[package]]
@@ -420,13 +429,28 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
 ]
 
 [[package]]
@@ -436,37 +460,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
 [[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
+[[package]]
 name = "windows_aarch64_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
 [[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
+[[package]]
 name = "windows_i686_gnu"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
 [[package]]
+name = "windows_i686_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
+[[package]]
 name = "windows_i686_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
 [[package]]
+name = "windows_i686_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
+[[package]]
 name = "windows_x86_64_gnu"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
 [[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
+[[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
 [[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
+[[package]]
 name = "windows_x86_64_msvc"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index c57e964168f..586ce2286f9 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.103", default-features = false, features = ["std", "unwind", "all-arch"] }
-cranelift-frontend = { version = "0.103" }
-cranelift-module = { version = "0.103" }
-cranelift-native = { version = "0.103" }
-cranelift-jit = { version = "0.103", optional = true }
-cranelift-object = { version = "0.103" }
+cranelift-codegen = { version = "0.104", default-features = false, features = ["std", "unwind", "all-arch"] }
+cranelift-frontend = { version = "0.104" }
+cranelift-module = { version = "0.104" }
+cranelift-native = { version = "0.104" }
+cranelift-jit = { version = "0.104", optional = true }
+cranelift-object = { version = "0.104" }
 target-lexicon = "0.12.0"
 gimli = { version = "0.28", default-features = false, features = ["write"]}
 object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index ca6ecdf1d0e..4f455261963 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -62,6 +62,27 @@ $ ./test.sh
 
 For more docs on how to build and test see [build_system/usage.txt](build_system/usage.txt) or the help message of `./y.sh`.
 
+## Platform support
+
+|OS \ architecture|x86\_64|AArch64|Riscv64|s390x (System-Z)|
+|---|---|---|---|---|
+|Linux|✅|✅|✅[^no-rustup]|✅[^no-rustup]|
+|FreeBSD|✅[^no-rustup]|❓|❓|❓|
+|AIX|❌[^xcoff]|N/A|N/A|❌[^xcoff]|
+|Other unixes|❓|❓|❓|❓|
+|macOS|✅|❌[^apple-silicon]|N/A|N/A|
+|Windows|✅[^no-rustup]|❌|N/A|N/A|
+
+✅: Fully supported and tested
+❓: Maybe supported, not tested
+❌: Not supported at all
+
+Not all targets are available as rustup component for nightly. See notes in the platform support matrix.
+
+[^xcoff]: XCOFF object file format is not supported.
+[^apple-silicon]: Tracked in [#1248](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1248).
+[^no-rustup]: Not available as rustup component for nightly. You can build it yourself.
+
 ## Usage
 
 rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
@@ -100,6 +121,8 @@ You need to do this steps to successfully compile and use the cranelift backend
   * (Optional) run tests: `rustup run stage2 ./y.sh test`
 8. Now you can use your cg_clif build to compile other Rust programs, e.g. you can open any Rust crate and run commands like `$RustCheckoutDir/compiler/rustc_codegen_cranelift/dist/cargo-clif build --release`.
 
+You can also set `rust-analyzer.rustc.source` to your rust workspace to get rust-analyzer to understand your changes.
+
 ## Configuration
 
 See the documentation on the `BackendConfig` struct in [config.rs](src/config.rs) for all
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index cb7b2454cd5..818f3d6f08d 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -113,8 +113,8 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
 pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
     "rust-random",
     "rand",
-    "9a02c819cc1e4ec6959ae25eafbb5cf6acb68234",
-    "4934f0afb1d1c2ca",
+    "1f4507a8e1cf8050e4ceef95eeda8f64645b6719",
+    "981f8bf489338978",
     "rand",
 );
 
@@ -133,8 +133,8 @@ pub(crate) static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir
 pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
     "rust-lang",
     "portable-simd",
-    "4825b2a64d765317066948867e8714674419359b",
-    "9e67d07c00f5fb0b",
+    "97007cc2e70df8c97326ce896a79e2f0ce4dd98b",
+    "e54a16035cedf205",
     "portable-simd",
 );
 
diff --git a/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Enable-the-exposed_provenance-feature.patch b/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Enable-the-exposed_provenance-feature.patch
deleted file mode 100644
index b8c0783f524..00000000000
--- a/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Enable-the-exposed_provenance-feature.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From a101a43b795431ce617e7782afb451f4853afc00 Mon Sep 17 00:00:00 2001
-From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
-Date: Thu, 7 Dec 2023 14:51:35 +0000
-Subject: [PATCH] Enable the exposed_provenance feature
-
----
- crates/core_simd/tests/pointers.rs | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/crates/core_simd/tests/pointers.rs b/crates/core_simd/tests/pointers.rs
-index 0ae8f83..06620d6 100644
---- a/crates/core_simd/tests/pointers.rs
-+++ b/crates/core_simd/tests/pointers.rs
-@@ -1,4 +1,4 @@
--#![feature(portable_simd, strict_provenance)]
-+#![feature(exposed_provenance, portable_simd, strict_provenance)]
- 
- use core_simd::simd::{Simd, SimdConstPtr, SimdMutPtr};
- 
--- 
-2.34.1
-
diff --git a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
index be29ae09bcf..271ca12eabb 100644
--- a/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0027-coretests-128bit-atomic-operations.patch
@@ -21,7 +21,7 @@ index 897a5e9..331f66f 100644
 -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
  #![cfg_attr(test, feature(cfg_match))]
  #![feature(int_roundings)]
- #![feature(slice_group_by)]
+ #![feature(split_array)]
 diff --git a/atomic.rs b/atomic.rs
 index b735957..ea728b6 100644
 --- a/atomic.rs
diff --git a/compiler/rustc_codegen_cranelift/patches/rand-lock.toml b/compiler/rustc_codegen_cranelift/patches/rand-lock.toml
index aacf3653c16..815b828a68b 100644
--- a/compiler/rustc_codegen_cranelift/patches/rand-lock.toml
+++ b/compiler/rustc_codegen_cranelift/patches/rand-lock.toml
@@ -487,6 +487,7 @@ dependencies = [
  "rand_pcg",
  "rayon",
  "serde",
+ "zerocopy",
 ]
 
 [[package]]
@@ -505,6 +506,7 @@ version = "0.7.0"
 dependencies = [
  "getrandom",
  "serde",
+ "zerocopy",
 ]
 
 [[package]]
@@ -525,6 +527,7 @@ name = "rand_pcg"
 version = "0.4.0"
 dependencies = [
  "bincode",
+ "rand",
  "rand_core",
  "serde",
 ]
@@ -823,3 +826,23 @@ name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "zerocopy"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.37",
+]
diff --git a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
index 8e213f71c3f..ad63b0768d3 100644
--- a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
+++ b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
@@ -61,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.104"
+version = "0.1.106"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99c3f9035afc33f4358773239573f7d121099856753e1bbd2a6a5207098fc741"
+checksum = "f4ab134a739bafec76aa91ccb15d519a54e569350644a1fea6528d5a0d407e22"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index a086c029360..ccd7edbc2a9 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-12-31"
+channel = "nightly-2024-01-26"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
index e6edc452cfb..2d9c2ecdbc2 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
@@ -13,17 +13,14 @@ use gimli::write::{
 };
 use gimli::{Encoding, Format, LineEncoding, RunTimeEndian};
 use indexmap::IndexSet;
+use rustc_session::Session;
 
 pub(crate) use self::emit::{DebugReloc, DebugRelocName};
 pub(crate) use self::unwind::UnwindContext;
 use crate::prelude::*;
 
-pub(crate) fn producer() -> String {
-    format!(
-        "rustc version {} with cranelift {}",
-        rustc_interface::util::rustc_version_str().unwrap_or("unknown version"),
-        cranelift_codegen::VERSION,
-    )
+pub(crate) fn producer(sess: &Session) -> String {
+    format!("rustc version {} with cranelift {}", sess.cfg_version, cranelift_codegen::VERSION)
 }
 
 pub(crate) struct DebugContext {
@@ -67,7 +64,7 @@ impl DebugContext {
 
         let should_remap_filepaths = tcx.sess.should_prefer_remapped_for_codegen();
 
-        let producer = producer();
+        let producer = producer(tcx.sess);
         let comp_dir = tcx
             .sess
             .opts
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index e77b0cd0721..757082a5fed 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -143,6 +143,7 @@ fn emit_cgu(
     debug: Option<DebugContext>,
     unwind_context: UnwindContext,
     global_asm_object_file: Option<PathBuf>,
+    producer: &str,
 ) -> Result<ModuleCodegenResult, String> {
     let mut product = module.finish();
 
@@ -152,8 +153,14 @@ fn emit_cgu(
 
     unwind_context.emit(&mut product);
 
-    let module_regular =
-        emit_module(output_filenames, prof, product.object, ModuleKind::Regular, name.clone())?;
+    let module_regular = emit_module(
+        output_filenames,
+        prof,
+        product.object,
+        ModuleKind::Regular,
+        name.clone(),
+        producer,
+    )?;
 
     Ok(ModuleCodegenResult {
         module_regular,
@@ -174,6 +181,7 @@ fn emit_module(
     mut object: cranelift_object::object::write::Object<'_>,
     kind: ModuleKind,
     name: String,
+    producer_str: &str,
 ) -> Result<CompiledModule, String> {
     if object.format() == cranelift_object::object::BinaryFormat::Elf {
         let comment_section = object.add_section(
@@ -182,7 +190,7 @@ fn emit_module(
             cranelift_object::object::SectionKind::OtherString,
         );
         let mut producer = vec![0];
-        producer.extend(crate::debuginfo::producer().as_bytes());
+        producer.extend(producer_str.as_bytes());
         producer.push(0);
         object.set_section_data(comment_section, producer, 1);
     }
@@ -321,6 +329,8 @@ fn module_codegen(
             (cgu_name, cx, module, codegened_functions)
         });
 
+    let producer = crate::debuginfo::producer(tcx.sess);
+
     OngoingModuleCodegen::Async(std::thread::spawn(move || {
         cx.profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| {
             cranelift_codegen::timing::set_thread_profiler(Box::new(super::MeasuremeProfiler(
@@ -348,6 +358,7 @@ fn module_codegen(
                     cx.debug_context,
                     cx.unwind_context,
                     global_asm_object_file,
+                    &producer,
                 )
             });
         std::mem::drop(token);
@@ -453,6 +464,7 @@ pub(crate) fn run_aot(
             product.object,
             ModuleKind::Allocator,
             "allocator_shim".to_owned(),
+            &crate::debuginfo::producer(tcx.sess),
         ) {
             Ok(allocator_module) => Some(allocator_module),
             Err(err) => tcx.dcx().fatal(err),
@@ -467,7 +479,7 @@ pub(crate) fn run_aot(
 
             let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
             let metadata_cgu_name = cgu_name_builder
-                .build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata"))
+                .build_cgu_name(LOCAL_CRATE, ["crate"], Some("metadata"))
                 .as_str()
                 .to_string();
 
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index 50d9f287e74..6b2b946db02 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -321,10 +321,9 @@ fn dep_symbol_lookup_fn(
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}
             Linkage::Static => {
                 let name = crate_info.crate_name[&cnum];
-                sess.dcx()
-                    .struct_err(format!("Can't load static lib {}", name))
-                    .note("rustc_codegen_cranelift can only load dylibs in JIT mode.")
-                    .emit();
+                let mut diag = sess.dcx().struct_err(format!("Can't load static lib {}", name));
+                diag.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
+                diag.emit();
             }
             Linkage::Dynamic => {
                 dylib_paths.push(src.dylib.as_ref().unwrap().0.clone());
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 6b9cec39d70..7793b1b7092 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -52,7 +52,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
     }
 
     let operands = operands
-        .into_iter()
+        .iter()
         .map(|operand| match *operand {
             InlineAsmOperand::In { reg, ref value } => CInlineAsmOperand::In {
                 reg,
@@ -506,10 +506,34 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
                             if self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
                                 generated_asm.push('%');
                             }
-                            self.registers[*operand_idx]
-                                .unwrap()
-                                .emit(&mut generated_asm, self.arch, *modifier)
-                                .unwrap();
+
+                            let reg = self.registers[*operand_idx].unwrap();
+                            match self.arch {
+                                InlineAsmArch::X86_64 => match reg {
+                                    InlineAsmReg::X86(reg)
+                                        if reg as u32 >= X86InlineAsmReg::xmm0 as u32
+                                            && reg as u32 <= X86InlineAsmReg::xmm15 as u32 =>
+                                    {
+                                        // rustc emits x0 rather than xmm0
+                                        let class = match *modifier {
+                                            None | Some('x') => "xmm",
+                                            Some('y') => "ymm",
+                                            Some('z') => "zmm",
+                                            _ => unreachable!(),
+                                        };
+                                        write!(
+                                            generated_asm,
+                                            "{class}{}",
+                                            reg as u32 - X86InlineAsmReg::xmm0 as u32
+                                        )
+                                        .unwrap();
+                                    }
+                                    _ => reg
+                                        .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier)
+                                        .unwrap(),
+                                },
+                                _ => reg.emit(&mut generated_asm, self.arch, *modifier).unwrap(),
+                            }
                         }
                         CInlineAsmOperand::Const { ref value } => {
                             generated_asm.push_str(value);
@@ -739,7 +763,7 @@ fn call_inline_asm<'tcx>(
             },
         )
         .unwrap();
-    let inline_asm_func = fx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func);
+    let inline_asm_func = fx.module.declare_func_in_func(inline_asm_func, fx.bcx.func);
     if fx.clif_comments.enabled() {
         fx.add_comment(inline_asm_func, asm_name);
     }
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index 1345c4614e2..e50c74b87f6 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -35,6 +35,10 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
     }
 
     match intrinsic {
+        "llvm.prefetch" => {
+            // Nothing to do. This is merely a perf hint.
+        }
+
         _ if intrinsic.starts_with("llvm.ctlz.v") => {
             intrinsic_args!(fx, args => (a); intrinsic);
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
index f6f3b85d3ef..e66bcbf4e40 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -243,6 +243,20 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
         }
 
         // FIXME generalize vector types
+        "llvm.aarch64.neon.tbl1.v8i8" => {
+            intrinsic_args!(fx, args => (t, idx); intrinsic);
+
+            let zero = fx.bcx.ins().iconst(types::I8, 0);
+            for i in 0..8 {
+                let idx_lane = idx.value_lane(fx, i).load_scalar(fx);
+                let is_zero =
+                    fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThanOrEqual, idx_lane, 16);
+                let t_idx = fx.bcx.ins().uextend(fx.pointer_type, idx_lane);
+                let t_lane = t.value_lane_dyn(fx, t_idx).load_scalar(fx);
+                let res = fx.bcx.ins().select(is_zero, zero, t_lane);
+                ret.place_lane(fx, i).to_ptr().store(fx, res, MemFlags::trusted());
+            }
+        }
         "llvm.aarch64.neon.tbl1.v16i8" => {
             intrinsic_args!(fx, args => (t, idx); intrinsic);
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index 994dc66835c..2e3e7ce986b 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -610,230 +610,56 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi16&ig_expand=4903
             intrinsic_args!(fx, args => (a, b); intrinsic);
 
-            assert_eq!(a.layout(), b.layout());
-            let layout = a.layout();
-
-            let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
-            let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
-            assert_eq!(lane_ty, fx.tcx.types.i16);
-            assert_eq!(ret_lane_ty, fx.tcx.types.u8);
-            assert_eq!(lane_count * 2, ret_lane_count);
-
-            let zero = fx.bcx.ins().iconst(types::I16, 0);
-            let max_u8 = fx.bcx.ins().iconst(types::I16, 255);
-            let ret_lane_layout = fx.layout_of(fx.tcx.types.u8);
-
-            for idx in 0..lane_count {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, zero);
-                let sat = fx.bcx.ins().umin(sat, max_u8);
-                let res = fx.bcx.ins().ireduce(types::I8, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::U8, PackWidth::Sse);
+        }
 
-            for idx in 0..lane_count {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, zero);
-                let sat = fx.bcx.ins().umin(sat, max_u8);
-                let res = fx.bcx.ins().ireduce(types::I8, sat);
+        "llvm.x86.sse2.packsswb.128" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi16&ig_expand=4848
+            intrinsic_args!(fx, args => (a, b); intrinsic);
 
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count + idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::S8, PackWidth::Sse);
         }
 
         "llvm.x86.avx2.packuswb" => {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi16&ig_expand=4906
             intrinsic_args!(fx, args => (a, b); intrinsic);
 
-            assert_eq!(a.layout(), b.layout());
-            let layout = a.layout();
-
-            let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
-            let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
-            assert_eq!(lane_ty, fx.tcx.types.i16);
-            assert_eq!(ret_lane_ty, fx.tcx.types.u8);
-            assert_eq!(lane_count * 2, ret_lane_count);
-
-            let zero = fx.bcx.ins().iconst(types::I16, 0);
-            let max_u8 = fx.bcx.ins().iconst(types::I16, 255);
-            let ret_lane_layout = fx.layout_of(fx.tcx.types.u8);
-
-            for idx in 0..lane_count / 2 {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, zero);
-                let sat = fx.bcx.ins().umin(sat, max_u8);
-                let res = fx.bcx.ins().ireduce(types::I8, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count / 2 {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, zero);
-                let sat = fx.bcx.ins().umin(sat, max_u8);
-                let res = fx.bcx.ins().ireduce(types::I8, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count / 2 + idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count / 2 {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, zero);
-                let sat = fx.bcx.ins().umin(sat, max_u8);
-                let res = fx.bcx.ins().ireduce(types::I8, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count / 2 * 2 + idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count / 2 {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, zero);
-                let sat = fx.bcx.ins().umin(sat, max_u8);
-                let res = fx.bcx.ins().ireduce(types::I8, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count / 2 * 3 + idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::U8, PackWidth::Avx);
         }
 
-        "llvm.x86.sse2.packssdw.128" => {
-            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi32&ig_expand=4889
+        "llvm.x86.avx2.packsswb" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi16&ig_expand=4851
             intrinsic_args!(fx, args => (a, b); intrinsic);
 
-            assert_eq!(a.layout(), b.layout());
-            let layout = a.layout();
-
-            let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
-            let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
-            assert_eq!(lane_ty, fx.tcx.types.i32);
-            assert_eq!(ret_lane_ty, fx.tcx.types.i16);
-            assert_eq!(lane_count * 2, ret_lane_count);
-
-            let min_i16 = fx.bcx.ins().iconst(types::I32, i32::from(i16::MIN) as u32 as i64);
-            let max_i16 = fx.bcx.ins().iconst(types::I32, i32::from(i16::MAX) as u32 as i64);
-            let ret_lane_layout = fx.layout_of(fx.tcx.types.i16);
-
-            for idx in 0..lane_count {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_i16);
-                let sat = fx.bcx.ins().smin(sat, max_i16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_i16);
-                let sat = fx.bcx.ins().smin(sat, max_i16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count + idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::S8, PackWidth::Avx);
         }
 
         "llvm.x86.sse41.packusdw" => {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi32&ig_expand=4912
             intrinsic_args!(fx, args => (a, b); intrinsic);
 
-            assert_eq!(a.layout(), b.layout());
-            let layout = a.layout();
-
-            let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
-            let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
-            assert_eq!(lane_ty, fx.tcx.types.i32);
-            assert_eq!(ret_lane_ty, fx.tcx.types.u16);
-            assert_eq!(lane_count * 2, ret_lane_count);
-
-            let min_u16 = fx.bcx.ins().iconst(types::I32, i64::from(u16::MIN));
-            let max_u16 = fx.bcx.ins().iconst(types::I32, i64::from(u16::MAX));
-            let ret_lane_layout = fx.layout_of(fx.tcx.types.u16);
+            pack_instruction(fx, a, b, ret, PackSize::U16, PackWidth::Sse);
+        }
 
-            for idx in 0..lane_count {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_u16);
-                let sat = fx.bcx.ins().smin(sat, max_u16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
+        "llvm.x86.sse2.packssdw.128" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi32&ig_expand=4889
+            intrinsic_args!(fx, args => (a, b); intrinsic);
 
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::S16, PackWidth::Sse);
+        }
 
-            for idx in 0..lane_count {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_u16);
-                let sat = fx.bcx.ins().smin(sat, max_u16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
+        "llvm.x86.avx2.packusdw" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi32&ig_expand=4883
+            intrinsic_args!(fx, args => (a, b); intrinsic);
 
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count + idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::U16, PackWidth::Avx);
         }
 
         "llvm.x86.avx2.packssdw" => {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi32&ig_expand=4892
             intrinsic_args!(fx, args => (a, b); intrinsic);
 
-            assert_eq!(a.layout(), b.layout());
-            let layout = a.layout();
-
-            let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
-            let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
-            assert_eq!(lane_ty, fx.tcx.types.i32);
-            assert_eq!(ret_lane_ty, fx.tcx.types.i16);
-            assert_eq!(lane_count * 2, ret_lane_count);
-
-            let min_i16 = fx.bcx.ins().iconst(types::I32, i32::from(i16::MIN) as u32 as i64);
-            let max_i16 = fx.bcx.ins().iconst(types::I32, i32::from(i16::MAX) as u32 as i64);
-            let ret_lane_layout = fx.layout_of(fx.tcx.types.i16);
-
-            for idx in 0..lane_count / 2 {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_i16);
-                let sat = fx.bcx.ins().smin(sat, max_i16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count / 2 {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_i16);
-                let sat = fx.bcx.ins().smin(sat, max_i16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count / 2 + idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count / 2 {
-                let lane = a.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_i16);
-                let sat = fx.bcx.ins().smin(sat, max_i16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count / 2 * 2 + idx).write_cvalue(fx, res_lane);
-            }
-
-            for idx in 0..lane_count / 2 {
-                let lane = b.value_lane(fx, idx).load_scalar(fx);
-                let sat = fx.bcx.ins().smax(lane, min_i16);
-                let sat = fx.bcx.ins().smin(sat, max_i16);
-                let res = fx.bcx.ins().ireduce(types::I16, sat);
-
-                let res_lane = CValue::by_val(res, ret_lane_layout);
-                ret.place_lane(fx, lane_count / 2 * 3 + idx).write_cvalue(fx, res_lane);
-            }
+            pack_instruction(fx, a, b, ret, PackSize::S16, PackWidth::Avx);
         }
 
         "llvm.x86.fma.vfmaddsub.ps"
@@ -1407,3 +1233,115 @@ fn llvm_add_sub<'tcx>(
 
     (cb_out, c)
 }
+
+enum PackSize {
+    U8,
+    U16,
+    S8,
+    S16,
+}
+
+impl PackSize {
+    fn ret_clif_type(&self) -> Type {
+        match self {
+            Self::U8 | Self::S8 => types::I8,
+            Self::U16 | Self::S16 => types::I16,
+        }
+    }
+    fn src_clif_type(&self) -> Type {
+        match self {
+            Self::U8 | Self::S8 => types::I16,
+            Self::U16 | Self::S16 => types::I32,
+        }
+    }
+    fn src_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+        match self {
+            Self::U8 | Self::S8 => tcx.types.i16,
+            Self::U16 | Self::S16 => tcx.types.i32,
+        }
+    }
+    fn ret_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+        match self {
+            Self::U8 => tcx.types.u8,
+            Self::S8 => tcx.types.i8,
+            Self::U16 => tcx.types.u16,
+            Self::S16 => tcx.types.i16,
+        }
+    }
+    fn max(&self) -> i64 {
+        match self {
+            Self::U8 => u8::MAX as u64 as i64,
+            Self::S8 => i8::MAX as u8 as u64 as i64,
+            Self::U16 => u16::MAX as u64 as i64,
+            Self::S16 => i16::MAX as u64 as u64 as i64,
+        }
+    }
+    fn min(&self) -> i64 {
+        match self {
+            Self::U8 | Self::U16 => 0,
+            Self::S8 => i16::from(i8::MIN) as u16 as i64,
+            Self::S16 => i32::from(i16::MIN) as u32 as i64,
+        }
+    }
+}
+
+enum PackWidth {
+    Sse = 1,
+    Avx = 2,
+}
+impl PackWidth {
+    fn divisor(&self) -> u64 {
+        match self {
+            Self::Sse => 1,
+            Self::Avx => 2,
+        }
+    }
+}
+
+/// Implement an x86 pack instruction with the intrinsic `_mm{,256}pack{us,s}_epi{16,32}`.
+/// Validated for correctness against LLVM, see commit `c8f5d35508e062bd2d95e6c03429bfec831db6d3`.
+fn pack_instruction<'tcx>(
+    fx: &mut FunctionCx<'_, '_, 'tcx>,
+    a: CValue<'tcx>,
+    b: CValue<'tcx>,
+    ret: CPlace<'tcx>,
+    ret_size: PackSize,
+    width: PackWidth,
+) {
+    assert_eq!(a.layout(), b.layout());
+    let layout = a.layout();
+
+    let (src_lane_count, src_lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+    let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+    assert_eq!(src_lane_ty, ret_size.src_ty(fx.tcx));
+    assert_eq!(ret_lane_ty, ret_size.ret_ty(fx.tcx));
+    assert_eq!(src_lane_count * 2, ret_lane_count);
+
+    let min = fx.bcx.ins().iconst(ret_size.src_clif_type(), ret_size.min());
+    let max = fx.bcx.ins().iconst(ret_size.src_clif_type(), ret_size.max());
+    let ret_lane_layout = fx.layout_of(ret_size.ret_ty(fx.tcx));
+
+    let mut round = |source: CValue<'tcx>, source_offset: u64, dest_offset: u64| {
+        let step_amount = src_lane_count / width.divisor();
+        let dest_offset = step_amount * dest_offset;
+        for idx in 0..step_amount {
+            let lane = source.value_lane(fx, step_amount * source_offset + idx).load_scalar(fx);
+            let sat = fx.bcx.ins().smax(lane, min);
+            let sat = match ret_size {
+                PackSize::U8 | PackSize::U16 => fx.bcx.ins().umin(sat, max),
+                PackSize::S8 | PackSize::S16 => fx.bcx.ins().smin(sat, max),
+            };
+            let res = fx.bcx.ins().ireduce(ret_size.ret_clif_type(), sat);
+            let res_lane = CValue::by_val(res, ret_lane_layout);
+            ret.place_lane(fx, dest_offset + idx).write_cvalue(fx, res_lane);
+        }
+    };
+
+    round(a, 0, 0);
+    round(b, 0, 1);
+
+    if let PackWidth::Avx = width {
+        round(a, 1, 2);
+        round(b, 1, 3);
+    }
+}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index d56d17892d5..ebdc744bcd8 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -293,7 +293,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             }
 
             ret.write_cvalue(fx, base);
-            let ret_lane = ret.place_lane(fx, idx.try_into().unwrap());
+            let ret_lane = ret.place_lane(fx, idx.into());
             ret_lane.write_cvalue(fx, val);
         }
 
@@ -340,7 +340,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 );
             }
 
-            let ret_lane = v.value_lane(fx, idx.try_into().unwrap());
+            let ret_lane = v.value_lane(fx, idx.into());
             ret.write_cvalue(fx, ret_lane);
         }
 
@@ -822,7 +822,35 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
             let lane_layout = fx.layout_of(lane_ty);
 
-            let m = m.load_scalar(fx);
+            let expected_int_bits = lane_count.max(8);
+            let expected_bytes = expected_int_bits / 8 + ((expected_int_bits % 8 > 0) as u64);
+
+            let m = match m.layout().ty.kind() {
+                ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => m.load_scalar(fx),
+                ty::Array(elem, len)
+                    if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
+                        && len.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
+                            == Some(expected_bytes) =>
+                {
+                    m.force_stack(fx).0.load(
+                        fx,
+                        Type::int(expected_int_bits as u16).unwrap(),
+                        MemFlags::trusted(),
+                    )
+                }
+                _ => {
+                    fx.tcx.dcx().span_fatal(
+                        span,
+                        format!(
+                            "invalid monomorphization of `simd_select_bitmask` intrinsic: \
+                            cannot accept `{}` as mask, expected `u{}` or `[u8; {}]`",
+                            ret.layout().ty,
+                            expected_int_bits,
+                            expected_bytes
+                        ),
+                    );
+                }
+            };
 
             for lane in 0..lane_count {
                 let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(lane) as i64);
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index b482f0dd2f0..416f87fcc87 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -18,7 +18,6 @@ extern crate rustc_fs_util;
 extern crate rustc_hir;
 extern crate rustc_incremental;
 extern crate rustc_index;
-extern crate rustc_interface;
 extern crate rustc_metadata;
 extern crate rustc_session;
 extern crate rustc_span;
@@ -42,7 +41,7 @@ use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_session::config::OutputFilenames;
 use rustc_session::Session;
-use rustc_span::Symbol;
+use rustc_span::{sym, Symbol};
 
 pub use crate::config::*;
 use crate::prelude::*;
@@ -190,8 +189,17 @@ impl CodegenBackend for CraneliftCodegenBackend {
         }
     }
 
-    fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
-        vec![] // FIXME necessary for #[cfg(target_feature]
+    fn target_features(&self, sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
+        // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
+        if sess.target.arch == "x86_64" && sess.target.os != "none" {
+            // x86_64 mandates SSE2 support
+            vec![Symbol::intern("fxsr"), sym::sse, Symbol::intern("sse2")]
+        } else if sess.target.arch == "aarch64" && sess.target.os != "none" {
+            // AArch64 mandates Neon support
+            vec![sym::neon]
+        } else {
+            vec![]
+        }
     }
 
     fn print_version(&self) {
@@ -305,16 +313,13 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
     let flags = settings::Flags::new(flags_builder);
 
     let isa_builder = match sess.opts.cg.target_cpu.as_deref() {
-        Some("native") => {
-            let builder = cranelift_native::builder_with_options(true).unwrap();
-            builder
-        }
+        Some("native") => cranelift_native::builder_with_options(true).unwrap(),
         Some(value) => {
             let mut builder =
                 cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| {
                     sess.dcx().fatal(format!("can't compile for {}: {}", target_triple, err));
                 });
-            if let Err(_) = builder.enable(value) {
+            if builder.enable(value).is_err() {
                 sess.dcx()
                     .fatal("the specified target cpu isn't currently supported by Cranelift.");
             }
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index f777e11371f..acfa461a6f3 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -28,10 +28,9 @@ pub(crate) fn unsized_info<'tcx>(
             .bcx
             .ins()
             .iconst(fx.pointer_type, len.eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
-        (
-            &ty::Dynamic(ref data_a, _, src_dyn_kind),
-            &ty::Dynamic(ref data_b, _, target_dyn_kind),
-        ) if src_dyn_kind == target_dyn_kind => {
+        (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind))
+            if src_dyn_kind == target_dyn_kind =>
+        {
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
             if data_a.principal_def_id() == data_b.principal_def_id() {
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs
index 41ea0b122de..d2254d4c15e 100644
--- a/compiler/rustc_codegen_cranelift/src/vtable.rs
+++ b/compiler/rustc_codegen_cranelift/src/vtable.rs
@@ -95,7 +95,7 @@ pub(crate) fn get_vtable<'tcx>(
     let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref));
     let data_id =
         data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not);
-    let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+    let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
     if fx.clif_comments.enabled() {
         fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id));
     }
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
index e9283b19894..cc0fbe46dcc 100644
--- a/compiler/rustc_codegen_gcc/src/errors.rs
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -35,7 +35,7 @@ pub(crate) enum PossibleFeature<'a> {
 struct ExitCode(Option<i32>);
 
 impl IntoDiagnosticArg for ExitCode {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         let ExitCode(exit_code) = self;
         match exit_code {
             Some(t) => t.into_diagnostic_arg(),
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index 7a86ddc7556..d5bc04f594d 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -39,6 +39,9 @@ codegen_llvm_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdy
 
 codegen_llvm_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto`
 
+codegen_llvm_mismatch_data_layout =
+    data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}`
+
 codegen_llvm_missing_features =
     add the missing features in a `target_feature` attribute
 
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 5ef05dfbe4c..6cb62280a59 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -34,6 +34,7 @@ use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
 use smallvec::SmallVec;
 
 use libc::c_uint;
+use std::borrow::Borrow;
 use std::cell::{Cell, RefCell};
 use std::ffi::CStr;
 use std::str;
@@ -155,8 +156,7 @@ pub unsafe fn create_module<'ll>(
     }
 
     // Ensure the data-layout values hardcoded remain the defaults.
-    if sess.target.is_builtin {
-        // tm is disposed by its drop impl
+    {
         let tm = crate::back::write::create_informational_target_machine(tcx.sess);
         llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
 
@@ -164,33 +164,13 @@ pub unsafe fn create_module<'ll>(
         let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
             .expect("got a non-UTF8 data-layout from LLVM");
 
-        // Unfortunately LLVM target specs change over time, and right now we
-        // don't have proper support to work with any more than one
-        // `data_layout` than the one that is in the rust-lang/rust repo. If
-        // this compiler is configured against a custom LLVM, we may have a
-        // differing data layout, even though we should update our own to use
-        // that one.
-        //
-        // As an interim hack, if CFG_LLVM_ROOT is not an empty string then we
-        // disable this check entirely as we may be configured with something
-        // that has a different target layout.
-        //
-        // Unsure if this will actually cause breakage when rustc is configured
-        // as such.
-        //
-        // FIXME(#34960)
-        let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
-        let custom_llvm_used = !cfg_llvm_root.trim().is_empty();
-
-        if !custom_llvm_used && target_data_layout != llvm_data_layout {
-            bug!(
-                "data-layout for target `{rustc_target}`, `{rustc_layout}`, \
-                  differs from LLVM target's `{llvm_target}` default layout, `{llvm_layout}`",
-                rustc_target = sess.opts.target_triple,
-                rustc_layout = target_data_layout,
-                llvm_target = sess.target.llvm_target,
-                llvm_layout = llvm_data_layout
-            );
+        if target_data_layout != llvm_data_layout {
+            tcx.dcx().emit_err(crate::errors::MismatchedDataLayout {
+                rustc_target: sess.opts.target_triple.to_string().as_str(),
+                rustc_layout: target_data_layout.as_str(),
+                llvm_target: sess.target.llvm_target.borrow(),
+                llvm_layout: llvm_data_layout,
+            });
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 6116a6fd222..b1ceb1d4dd5 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -403,6 +403,7 @@ fn codegenned_and_inlined_items(tcx: TyCtxt<'_>) -> DefIdSet {
     let mut result = items.clone();
 
     for cgu in cgus {
+        #[allow(rustc::potential_query_instability)]
         for item in cgu.items().keys() {
             if let mir::mono::MonoItem::Fn(ref instance) = item {
                 let did = instance.def_id();
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 697ce602298..d82ff6656f4 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -244,3 +244,12 @@ pub(crate) struct CopyBitcode {
 pub struct UnknownCompression {
     pub algorithm: &'static str,
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_llvm_mismatch_data_layout)]
+pub struct MismatchedDataLayout<'a> {
+    pub rustc_target: &'a str,
+    pub rustc_layout: &'a str,
+    pub llvm_target: &'a str,
+    pub llvm_layout: &'a str,
+}
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index a81056ed3ad..f4f29078190 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -14,9 +14,7 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
-#![feature(never_type)]
 #![feature(impl_trait_in_assoc_type)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
index a1daadce958..3e5a43c6e73 100644
--- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
+++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
@@ -206,7 +206,7 @@ impl fmt::Display for CguReuse {
 }
 
 impl IntoDiagnosticArg for CguReuse {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
     }
 }
@@ -267,6 +267,7 @@ impl CguReuseTracker {
 
     fn check_expected_reuse(&self, sess: &Session) {
         if let Some(ref data) = self.data {
+            #[allow(rustc::potential_query_instability)]
             let mut keys = data.expected_reuse.keys().collect::<Vec<_>>();
             keys.sort_unstable();
             for cgu_name in keys {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index f098fc9cb59..b29f71bfb95 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -682,6 +682,7 @@ fn link_dwarf_object<'a>(
         }
 
         // Input rlibs contain .o/.dwo files from dependencies.
+        #[allow(rustc::potential_query_instability)]
         let input_rlibs = cg_results
             .crate_info
             .used_crate_source
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 5d497d4a188..06edb794537 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -14,8 +14,11 @@ use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::Emitter;
-use rustc_errors::{translation::Translate, DiagCtxt, FatalError, Level};
-use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, Style};
+use rustc_errors::translation::Translate;
+use rustc_errors::{
+    DiagCtxt, DiagnosticArgName, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, ErrCode,
+    FatalError, FluentBundle, Level, Style,
+};
 use rustc_fs_util::link_or_copy;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_incremental::{
@@ -995,12 +998,10 @@ pub(crate) enum Message<B: WriteBackendMethods> {
 /// process another codegen unit.
 pub struct CguMessage;
 
-type DiagnosticArgName<'source> = Cow<'source, str>;
-
 struct Diagnostic {
     msgs: Vec<(DiagnosticMessage, Style)>,
-    args: FxHashMap<DiagnosticArgName<'static>, rustc_errors::DiagnosticArgValue<'static>>,
-    code: Option<String>,
+    args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>,
+    code: Option<ErrCode>,
     lvl: Level,
 }
 
@@ -1800,18 +1801,18 @@ impl SharedEmitter {
 }
 
 impl Translate for SharedEmitter {
-    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+    fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
         None
     }
 
-    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
         panic!("shared emitter attempted to translate a diagnostic");
     }
 }
 
 impl Emitter for SharedEmitter {
     fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
-        let args: FxHashMap<Cow<'_, str>, rustc_errors::DiagnosticArgValue<'_>> =
+        let args: FxHashMap<Cow<'_, str>, DiagnosticArgValue> =
             diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect();
         drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
             msgs: diag.messages.clone(),
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index cca239a43b3..47b1b080119 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -1,6 +1,6 @@
 use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index f90e1906caf..06ea5b9e8f4 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -4,7 +4,7 @@ use crate::assert_module_sources::CguReuse;
 use crate::back::command::Command;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
+    codes::*, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
     IntoDiagnosticArg, Level,
 };
 use rustc_macros::Diagnostic;
@@ -147,7 +147,7 @@ impl<'a> CopyPath<'a> {
 struct DebugArgPath<'a>(pub &'a Path);
 
 impl IntoDiagnosticArg for DebugArgPath<'_> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0)))
     }
 }
@@ -612,7 +612,7 @@ pub struct UnknownAtomicOperation;
 
 #[derive(Diagnostic)]
 pub enum InvalidMonomorphization<'tcx> {
-    #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = E0511)]
     BasicIntegerType {
         #[primary_span]
         span: Span,
@@ -620,7 +620,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = E0511)]
     BasicFloatType {
         #[primary_span]
         span: Span,
@@ -628,14 +628,14 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = E0511)]
     FloatToIntUnchecked {
         #[primary_span]
         span: Span,
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = E0511)]
     FloatingPointVector {
         #[primary_span]
         span: Span,
@@ -644,7 +644,7 @@ pub enum InvalidMonomorphization<'tcx> {
         in_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = E0511)]
     FloatingPointType {
         #[primary_span]
         span: Span,
@@ -652,14 +652,14 @@ pub enum InvalidMonomorphization<'tcx> {
         in_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = E0511)]
     UnrecognizedIntrinsic {
         #[primary_span]
         span: Span,
         name: Symbol,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = E0511)]
     SimdArgument {
         #[primary_span]
         span: Span,
@@ -667,7 +667,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = E0511)]
     SimdInput {
         #[primary_span]
         span: Span,
@@ -675,7 +675,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = E0511)]
     SimdFirst {
         #[primary_span]
         span: Span,
@@ -683,7 +683,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = E0511)]
     SimdSecond {
         #[primary_span]
         span: Span,
@@ -691,7 +691,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = E0511)]
     SimdThird {
         #[primary_span]
         span: Span,
@@ -699,7 +699,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = E0511)]
     SimdReturn {
         #[primary_span]
         span: Span,
@@ -707,7 +707,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = E0511)]
     InvalidBitmask {
         #[primary_span]
         span: Span,
@@ -717,7 +717,7 @@ pub enum InvalidMonomorphization<'tcx> {
         expected_bytes: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = E0511)]
     ReturnLengthInputType {
         #[primary_span]
         span: Span,
@@ -728,7 +728,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = E0511)]
     SecondArgumentLength {
         #[primary_span]
         span: Span,
@@ -739,7 +739,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = E0511)]
     ThirdArgumentLength {
         #[primary_span]
         span: Span,
@@ -750,7 +750,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = E0511)]
     ReturnIntegerType {
         #[primary_span]
         span: Span,
@@ -759,7 +759,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = E0511)]
     SimdShuffle {
         #[primary_span]
         span: Span,
@@ -767,7 +767,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_length, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_length, code = E0511)]
     ReturnLength {
         #[primary_span]
         span: Span,
@@ -777,7 +777,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_element, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_element, code = E0511)]
     ReturnElement {
         #[primary_span]
         span: Span,
@@ -788,7 +788,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = E0511)]
     ShuffleIndexNotConstant {
         #[primary_span]
         span: Span,
@@ -796,7 +796,7 @@ pub enum InvalidMonomorphization<'tcx> {
         arg_idx: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = E0511)]
     ShuffleIndexOutOfBounds {
         #[primary_span]
         span: Span,
@@ -805,7 +805,7 @@ pub enum InvalidMonomorphization<'tcx> {
         total_len: u128,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = E0511)]
     InsertedType {
         #[primary_span]
         span: Span,
@@ -815,7 +815,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_type, code = E0511)]
     ReturnType {
         #[primary_span]
         span: Span,
@@ -825,7 +825,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = E0511)]
     ExpectedReturnType {
         #[primary_span]
         span: Span,
@@ -834,7 +834,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = E0511)]
     MismatchedLengths {
         #[primary_span]
         span: Span,
@@ -843,7 +843,7 @@ pub enum InvalidMonomorphization<'tcx> {
         v_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = E0511)]
     MaskType {
         #[primary_span]
         span: Span,
@@ -851,7 +851,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = E0511)]
     VectorArgument {
         #[primary_span]
         span: Span,
@@ -860,7 +860,7 @@ pub enum InvalidMonomorphization<'tcx> {
         in_elem: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = E0511)]
     CannotReturn {
         #[primary_span]
         span: Span,
@@ -870,7 +870,7 @@ pub enum InvalidMonomorphization<'tcx> {
         expected_bytes: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = E0511)]
     ExpectedElementType {
         #[primary_span]
         span: Span,
@@ -882,7 +882,7 @@ pub enum InvalidMonomorphization<'tcx> {
         mutability: ExpectedPointerMutability,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = E0511)]
     ThirdArgElementType {
         #[primary_span]
         span: Span,
@@ -891,7 +891,7 @@ pub enum InvalidMonomorphization<'tcx> {
         third_arg: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = E0511)]
     UnsupportedSymbolOfSize {
         #[primary_span]
         span: Span,
@@ -903,7 +903,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = E0511)]
     UnsupportedSymbol {
         #[primary_span]
         span: Span,
@@ -914,7 +914,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = E0511)]
     CastFatPointer {
         #[primary_span]
         span: Span,
@@ -922,7 +922,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = E0511)]
     ExpectedPointer {
         #[primary_span]
         span: Span,
@@ -930,7 +930,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = E0511)]
     ExpectedUsize {
         #[primary_span]
         span: Span,
@@ -938,7 +938,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = E0511)]
     UnsupportedCast {
         #[primary_span]
         span: Span,
@@ -949,7 +949,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_elem: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = E0511)]
     UnsupportedOperation {
         #[primary_span]
         span: Span,
@@ -958,7 +958,7 @@ pub enum InvalidMonomorphization<'tcx> {
         in_elem: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = E0511)]
     ExpectedVectorElementType {
         #[primary_span]
         span: Span,
@@ -974,7 +974,7 @@ pub enum ExpectedPointerMutability {
 }
 
 impl IntoDiagnosticArg for ExpectedPointerMutability {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         match self {
             ExpectedPointerMutability::Mut => DiagnosticArgValue::Str(Cow::Borrowed("*mut")),
             ExpectedPointerMutability::Not => DiagnosticArgValue::Str(Cow::Borrowed("*_")),
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 8f5421823a3..fc833a3863e 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -7,10 +7,8 @@
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(negative_impls)]
-#![feature(never_type)]
 #![feature(strict_provenance)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 
 //! This crate contains codegen code that is used by all codegen backends (LLVM and others).
 //! The backend-agnostic functions of this crate use functions defined in various traits that
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index e8d0430c9d9..dabf78ef90e 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -34,7 +34,7 @@ impl MachineStopType for ConstEvalErrKind {
     }
     fn add_args(
         self: Box<Self>,
-        adder: &mut dyn FnMut(std::borrow::Cow<'static, str>, DiagnosticArgValue<'static>),
+        adder: &mut dyn FnMut(std::borrow::Cow<'static, str>, DiagnosticArgValue),
     ) {
         use ConstEvalErrKind::*;
         match *self {
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 064d97a49d7..4d2b1ba3eec 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -1,8 +1,8 @@
 use std::borrow::Cow;
 
 use rustc_errors::{
-    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee,
-    IntoDiagnostic, Level,
+    codes::*, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage,
+    EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_hir::ConstContext;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -55,14 +55,14 @@ pub(crate) struct UnstableInStable {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_thread_local_access, code = "E0625")]
+#[diag(const_eval_thread_local_access, code = E0625)]
 pub(crate) struct NonConstOpErr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_static_access, code = "E0013")]
+#[diag(const_eval_static_access, code = E0013)]
 #[help]
 pub(crate) struct StaticAccessErr {
     #[primary_span]
@@ -98,7 +98,7 @@ pub(crate) struct PanicNonStrErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_mut_deref, code = "E0658")]
+#[diag(const_eval_mut_deref, code = E0658)]
 pub(crate) struct MutDerefErr {
     #[primary_span]
     pub span: Span,
@@ -106,7 +106,7 @@ pub(crate) struct MutDerefErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_transient_mut_borrow, code = "E0658")]
+#[diag(const_eval_transient_mut_borrow, code = E0658)]
 pub(crate) struct TransientMutBorrowErr {
     #[primary_span]
     pub span: Span,
@@ -114,7 +114,7 @@ pub(crate) struct TransientMutBorrowErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_transient_mut_raw, code = "E0658")]
+#[diag(const_eval_transient_mut_raw, code = E0658)]
 pub(crate) struct TransientMutRawErr {
     #[primary_span]
     pub span: Span,
@@ -146,7 +146,7 @@ pub(crate) struct UnstableConstFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_mutable_refs, code = "E0764")]
+#[diag(const_eval_unallowed_mutable_refs, code = E0764)]
 pub(crate) struct UnallowedMutableRefs {
     #[primary_span]
     pub span: Span,
@@ -156,7 +156,7 @@ pub(crate) struct UnallowedMutableRefs {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_mutable_raw, code = "E0764")]
+#[diag(const_eval_unallowed_mutable_raw, code = E0764)]
 pub(crate) struct UnallowedMutableRaw {
     #[primary_span]
     pub span: Span,
@@ -165,7 +165,7 @@ pub(crate) struct UnallowedMutableRaw {
     pub teach: Option<()>,
 }
 #[derive(Diagnostic)]
-#[diag(const_eval_non_const_fmt_macro_call, code = "E0015")]
+#[diag(const_eval_non_const_fmt_macro_call, code = E0015)]
 pub(crate) struct NonConstFmtMacroCall {
     #[primary_span]
     pub span: Span,
@@ -173,7 +173,7 @@ pub(crate) struct NonConstFmtMacroCall {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_non_const_fn_call, code = "E0015")]
+#[diag(const_eval_non_const_fn_call, code = E0015)]
 pub(crate) struct NonConstFnCall {
     #[primary_span]
     pub span: Span,
@@ -190,7 +190,7 @@ pub(crate) struct UnallowedOpInConstContext {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_heap_allocations, code = "E0010")]
+#[diag(const_eval_unallowed_heap_allocations, code = E0010)]
 pub(crate) struct UnallowedHeapAllocations {
     #[primary_span]
     #[label]
@@ -201,7 +201,7 @@ pub(crate) struct UnallowedHeapAllocations {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_inline_asm, code = "E0015")]
+#[diag(const_eval_unallowed_inline_asm, code = E0015)]
 pub(crate) struct UnallowedInlineAsm {
     #[primary_span]
     pub span: Span,
@@ -209,7 +209,7 @@ pub(crate) struct UnallowedInlineAsm {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_interior_mutable_data_refer, code = "E0492")]
+#[diag(const_eval_interior_mutable_data_refer, code = E0492)]
 pub(crate) struct InteriorMutableDataRefer {
     #[primary_span]
     #[label]
@@ -274,7 +274,7 @@ pub struct RawBytesNote {
 // FIXME(fee1-dead) do not use stringly typed `ConstContext`
 
 #[derive(Diagnostic)]
-#[diag(const_eval_match_eq_non_const, code = "E0015")]
+#[diag(const_eval_match_eq_non_const, code = E0015)]
 #[note]
 pub struct NonConstMatchEq<'tcx> {
     #[primary_span]
@@ -284,7 +284,7 @@ pub struct NonConstMatchEq<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_for_loop_into_iter_non_const, code = "E0015")]
+#[diag(const_eval_for_loop_into_iter_non_const, code = E0015)]
 pub struct NonConstForLoopIntoIter<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -293,7 +293,7 @@ pub struct NonConstForLoopIntoIter<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_question_branch_non_const, code = "E0015")]
+#[diag(const_eval_question_branch_non_const, code = E0015)]
 pub struct NonConstQuestionBranch<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -302,7 +302,7 @@ pub struct NonConstQuestionBranch<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_question_from_residual_non_const, code = "E0015")]
+#[diag(const_eval_question_from_residual_non_const, code = E0015)]
 pub struct NonConstQuestionFromResidual<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -311,7 +311,7 @@ pub struct NonConstQuestionFromResidual<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_try_block_from_output_non_const, code = "E0015")]
+#[diag(const_eval_try_block_from_output_non_const, code = E0015)]
 pub struct NonConstTryBlockFromOutput<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -320,7 +320,7 @@ pub struct NonConstTryBlockFromOutput<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_await_non_const, code = "E0015")]
+#[diag(const_eval_await_non_const, code = E0015)]
 pub struct NonConstAwait<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -329,7 +329,7 @@ pub struct NonConstAwait<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_closure_non_const, code = "E0015")]
+#[diag(const_eval_closure_non_const, code = E0015)]
 pub struct NonConstClosure {
     #[primary_span]
     pub span: Span,
@@ -362,7 +362,7 @@ pub struct ConsiderDereferencing {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_operator_non_const, code = "E0015")]
+#[diag(const_eval_operator_non_const, code = E0015)]
 pub struct NonConstOperator {
     #[primary_span]
     pub span: Span,
@@ -372,7 +372,7 @@ pub struct NonConstOperator {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_deref_coercion_non_const, code = "E0015")]
+#[diag(const_eval_deref_coercion_non_const, code = E0015)]
 #[note]
 pub struct NonConstDerefCoercion<'tcx> {
     #[primary_span]
@@ -385,7 +385,7 @@ pub struct NonConstDerefCoercion<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_live_drop, code = "E0493")]
+#[diag(const_eval_live_drop, code = E0493)]
 pub struct LiveDrop<'tcx> {
     #[primary_span]
     #[label]
@@ -397,7 +397,7 @@ pub struct LiveDrop<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_error, code = "E0080")]
+#[diag(const_eval_error, code = E0080)]
 pub struct ConstEvalError {
     #[primary_span]
     pub span: Span,
@@ -423,7 +423,7 @@ pub struct NullaryIntrinsicError {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_undefined_behavior, code = "E0080")]
+#[diag(const_eval_undefined_behavior, code = E0080)]
 pub struct UndefinedBehavior {
     #[primary_span]
     pub span: Span,
@@ -906,7 +906,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
 }
 
 impl rustc_errors::IntoDiagnosticArg for InternKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(match self {
             InternKind::Static(Mutability::Not) => "static",
             InternKind::Static(Mutability::Mut) => "static_mut",
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 3afd14eb574..38ad8cbf3a6 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -396,7 +396,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// to the allocation it points to. Supports both shared and mutable references, as the actual
     /// checking is offloaded to a helper closure.
     ///
-    /// If this returns `None`, the size is 0; it can however return `Some` even for size 0.
+    /// Returns `None` if and only if the size is 0.
     fn check_and_deref_ptr<T>(
         &self,
         ptr: Pointer<Option<M::Provenance>>,
@@ -1214,10 +1214,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             let size_in_bytes = size.bytes_usize();
             // For particularly large arrays (where this is perf-sensitive) it's common that
             // we're writing a single byte repeatedly. So, optimize that case to a memset.
-            if size_in_bytes == 1 && num_copies >= 1 {
-                // SAFETY: `src_bytes` would be read from anyway by copies below (num_copies >= 1).
-                // Since size_in_bytes = 1, then the `init.no_bytes_init()` check above guarantees
-                // that this read at type `u8` is OK -- it must be an initialized byte.
+            if size_in_bytes == 1 {
+                debug_assert!(num_copies >= 1); // we already handled the zero-sized cases above.
+                // SAFETY: `src_bytes` would be read from anyway by `copy` below (num_copies >= 1).
                 let value = *src_bytes;
                 dest_bytes.write_bytes(value, (size * num_copies).bytes_usize());
             } else if src_alloc_id == dest_alloc_id {
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 80d4bda4827..4653c9016c6 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -260,8 +260,12 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
         // This makes several assumptions about what layouts we will encounter; we match what
         // codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
         let inner_val: Immediate<_> = match (**self, self.layout.abi) {
-            // if the entire value is uninit, then so is the field (can happen in ConstProp)
+            // If the entire value is uninit, then so is the field (can happen in ConstProp).
             (Immediate::Uninit, _) => Immediate::Uninit,
+            // If the field is uninhabited, we can forget the data (can happen in ConstProp).
+            // `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
+            // has an `Uninhabited` variant, which means this case is possible.
+            _ if layout.abi.is_uninhabited() => Immediate::Uninit,
             // the field contains no information, can be left uninit
             // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)
             _ if layout.is_zst() => Immediate::Uninit,
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index bd60e066f72..3a441c1d649 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -201,25 +201,8 @@ where
         // see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
         // So we just "offset" by 0.
         let layout = base.layout().for_variant(self, variant);
-        // In the future we might want to allow this to permit code like this:
-        // (this is a Rust/MIR pseudocode mix)
-        // ```
-        // enum Option2 {
-        //   Some(i32, !),
-        //   None,
-        // }
-        //
-        // fn panic() -> ! { panic!() }
-        //
-        // let x: Option2;
-        // x.Some.0 = 42;
-        // x.Some.1 = panic();
-        // SetDiscriminant(x, Some);
-        // ```
-        // However, for now we don't generate such MIR, and this check here *has* found real
-        // bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting
-        // it.
-        assert!(!layout.abi.is_uninhabited());
+        // This variant may in fact be uninhabited.
+        // See <https://github.com/rust-lang/rust/issues/120337>.
 
         // This cannot be `transmute` as variants *can* have a smaller size than the entire enum.
         base.offset(Size::ZERO, layout, self)
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index d6c36ccc5ec..946a49982aa 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -11,20 +11,13 @@ Rust MIR: a lowered representation of Rust.
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
-#![feature(exact_size_is_empty)]
 #![feature(let_chains)]
-#![feature(map_try_insert)]
-#![feature(min_specialization)]
 #![feature(slice_ptr_get)]
-#![feature(option_get_or_insert_default)]
 #![feature(never_type)]
 #![feature(trait_alias)]
-#![feature(trusted_len)]
-#![feature(trusted_step)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
 #![feature(if_let_guard)]
-#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 39bc2b960e9..fb705d91977 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -2,7 +2,7 @@
 
 use hir::def_id::LocalDefId;
 use hir::{ConstContext, LangItem};
-use rustc_errors::{error_code, DiagnosticBuilder};
+use rustc_errors::{codes::*, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
@@ -372,7 +372,7 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
         ccx.dcx().create_err(errors::UnallowedHeapAllocations {
             span,
             kind: ccx.const_kind(),
-            teach: ccx.tcx.sess.teach(&error_code!(E0010)).then_some(()),
+            teach: ccx.tcx.sess.teach(E0010).then_some(()),
         })
     }
 }
@@ -434,14 +434,14 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
                 span,
                 opt_help: Some(()),
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0492).then_some(()),
             })
         } else {
             ccx.dcx().create_err(errors::InteriorMutableDataRefer {
                 span,
                 opt_help: None,
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0492).then_some(()),
             })
         }
     }
@@ -469,12 +469,12 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
             hir::BorrowKind::Raw => ccx.tcx.dcx().create_err(errors::UnallowedMutableRaw {
                 span,
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0764).then_some(()),
             }),
             hir::BorrowKind::Ref => ccx.dcx().create_err(errors::UnallowedMutableRefs {
                 span,
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0764).then_some(()),
             }),
         }
     }
@@ -588,7 +588,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
         ccx.dcx().create_err(errors::StaticAccessErr {
             span,
             kind: ccx.const_kind(),
-            teach: ccx.tcx.sess.teach(&error_code!(E0013)).then_some(()),
+            teach: ccx.tcx.sess.teach(E0013).then_some(()),
         })
     }
 }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 5564902396e..21bdb66a276 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -810,13 +810,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     let adt_def = self.tcx.adt_def(def_id);
                     assert!(adt_def.is_union());
                     assert_eq!(idx, FIRST_VARIANT);
-                    let dest = adt_def.non_enum_variant().fields[field].ty(self.tcx, args);
-                    if fields.len() != 1 {
+                    let dest_ty = self.tcx.normalize_erasing_regions(
+                        self.param_env,
+                        adt_def.non_enum_variant().fields[field].ty(self.tcx, args),
+                    );
+                    if fields.len() == 1 {
+                        let src_ty = fields.raw[0].ty(self.body, self.tcx);
+                        if !self.mir_assign_valid_types(src_ty, dest_ty) {
+                            self.fail(location, "union field has the wrong type");
+                        }
+                    } else {
                         self.fail(location, "unions should have one initialized field");
                     }
-                    if !self.mir_assign_valid_types(fields.raw[0].ty(self.body, self.tcx), dest) {
-                        self.fail(location, "union field has the wrong type");
-                    }
                 }
                 AggregateKind::Adt(def_id, idx, args, _, None) => {
                     let adt_def = self.tcx.adt_def(def_id);
@@ -826,10 +831,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         self.fail(location, "adt has the wrong number of initialized fields");
                     }
                     for (src, dest) in std::iter::zip(fields, &variant.fields) {
-                        if !self.mir_assign_valid_types(
-                            src.ty(self.body, self.tcx),
-                            dest.ty(self.tcx, args),
-                        ) {
+                        let dest_ty = self
+                            .tcx
+                            .normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args));
+                        if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) {
                             self.fail(location, "adt field has the wrong type");
                         }
                     }
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 077e90350a3..563d8501890 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -10,6 +10,7 @@
 #![allow(internal_features)]
 #![allow(rustc::default_hash_types)]
 #![allow(rustc::potential_query_instability)]
+#![cfg_attr(not(parallel_compiler), feature(cell_leak))]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(unsafe_op_in_unsafe_fn)]
@@ -18,7 +19,6 @@
 #![feature(allocator_api)]
 #![feature(array_windows)]
 #![feature(auto_traits)]
-#![feature(cell_leak)]
 #![feature(cfg_match)]
 #![feature(core_intrinsics)]
 #![feature(extend_one)]
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 97a7dfef3b3..bfdd871455c 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -15,7 +15,6 @@ rustc_builtin_macros = { path = "../rustc_builtin_macros" }
 rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
 rustc_const_eval = { path = "../rustc_const_eval" }
 rustc_data_structures = { path = "../rustc_data_structures" }
-rustc_error_codes = { path = "../rustc_error_codes" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_expand = { path = "../rustc_expand" }
 rustc_feature = { path = "../rustc_feature" }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 11dcf4108d4..5903c43ae98 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -9,11 +9,9 @@
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
 #![feature(decl_macro)]
-#![feature(lazy_cell)]
 #![feature(let_chains)]
 #![feature(panic_update_hook)]
 #![feature(result_flattening)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
@@ -25,9 +23,8 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
 use rustc_data_structures::profiling::{
     get_resident_set_size, print_time_passes_entry, TimePassesFormat,
 };
-use rustc_errors::registry::{InvalidErrorCode, Registry};
-use rustc_errors::{markdown, ColorConfig};
-use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
+use rustc_errors::registry::Registry;
+use rustc_errors::{markdown, ColorConfig, DiagCtxt, ErrCode, ErrorGuaranteed, PResult};
 use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
@@ -209,7 +206,7 @@ impl Callbacks for TimePassesCallbacks {
 }
 
 pub fn diagnostics_registry() -> Registry {
-    Registry::new(rustc_error_codes::DIAGNOSTICS)
+    Registry::new(rustc_errors::codes::DIAGNOSTICS)
 }
 
 /// This is the primary entry point for rustc.
@@ -537,37 +534,36 @@ pub enum Compilation {
 }
 
 fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) {
+    // Allow "E0123" or "0123" form.
     let upper_cased_code = code.to_ascii_uppercase();
-    let normalised =
-        if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
-    match registry.try_find_description(&normalised) {
-        Ok(description) => {
-            let mut is_in_code_block = false;
-            let mut text = String::new();
-            // Slice off the leading newline and print.
-            for line in description.lines() {
-                let indent_level =
-                    line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len());
-                let dedented_line = &line[indent_level..];
-                if dedented_line.starts_with("```") {
-                    is_in_code_block = !is_in_code_block;
-                    text.push_str(&line[..(indent_level + 3)]);
-                } else if is_in_code_block && dedented_line.starts_with("# ") {
-                    continue;
-                } else {
-                    text.push_str(line);
-                }
-                text.push('\n');
-            }
-            if io::stdout().is_terminal() {
-                show_md_content_with_pager(&text, color);
+    let start = if upper_cased_code.starts_with('E') { 1 } else { 0 };
+    if let Ok(code) = upper_cased_code[start..].parse::<u32>()
+        && let Ok(description) = registry.try_find_description(ErrCode::from_u32(code))
+    {
+        let mut is_in_code_block = false;
+        let mut text = String::new();
+        // Slice off the leading newline and print.
+        for line in description.lines() {
+            let indent_level =
+                line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len());
+            let dedented_line = &line[indent_level..];
+            if dedented_line.starts_with("```") {
+                is_in_code_block = !is_in_code_block;
+                text.push_str(&line[..(indent_level + 3)]);
+            } else if is_in_code_block && dedented_line.starts_with("# ") {
+                continue;
             } else {
-                safe_print!("{text}");
+                text.push_str(line);
             }
+            text.push('\n');
         }
-        Err(InvalidErrorCode) => {
-            early_dcx.early_fatal(format!("{code} is not a valid error code"));
+        if io::stdout().is_terminal() {
+            show_md_content_with_pager(&text, color);
+        } else {
+            safe_print!("{text}");
         }
+    } else {
+        early_dcx.early_fatal(format!("{code} is not a valid error code"));
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
deleted file mode 100644
index 9cd9ed54d41..00000000000
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ /dev/null
@@ -1,658 +0,0 @@
-// Error messages for EXXXX errors. Each message should start and end with a
-// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
-// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-//
-// /!\ IMPORTANT /!\
-//
-// Error messages' format must follow the RFC 1567 available here:
-// https://rust-lang.github.io/rfcs/1567-long-error-codes-explanation-normalization.html
-
-register_diagnostics! {
-E0001: include_str!("./error_codes/E0001.md"),
-E0002: include_str!("./error_codes/E0002.md"),
-E0004: include_str!("./error_codes/E0004.md"),
-E0005: include_str!("./error_codes/E0005.md"),
-E0007: include_str!("./error_codes/E0007.md"),
-E0009: include_str!("./error_codes/E0009.md"),
-E0010: include_str!("./error_codes/E0010.md"),
-E0013: include_str!("./error_codes/E0013.md"),
-E0014: include_str!("./error_codes/E0014.md"),
-E0015: include_str!("./error_codes/E0015.md"),
-E0023: include_str!("./error_codes/E0023.md"),
-E0025: include_str!("./error_codes/E0025.md"),
-E0026: include_str!("./error_codes/E0026.md"),
-E0027: include_str!("./error_codes/E0027.md"),
-E0029: include_str!("./error_codes/E0029.md"),
-E0030: include_str!("./error_codes/E0030.md"),
-E0033: include_str!("./error_codes/E0033.md"),
-E0034: include_str!("./error_codes/E0034.md"),
-E0038: include_str!("./error_codes/E0038.md"),
-E0040: include_str!("./error_codes/E0040.md"),
-E0044: include_str!("./error_codes/E0044.md"),
-E0045: include_str!("./error_codes/E0045.md"),
-E0046: include_str!("./error_codes/E0046.md"),
-E0049: include_str!("./error_codes/E0049.md"),
-E0050: include_str!("./error_codes/E0050.md"),
-E0053: include_str!("./error_codes/E0053.md"),
-E0054: include_str!("./error_codes/E0054.md"),
-E0055: include_str!("./error_codes/E0055.md"),
-E0057: include_str!("./error_codes/E0057.md"),
-E0059: include_str!("./error_codes/E0059.md"),
-E0060: include_str!("./error_codes/E0060.md"),
-E0061: include_str!("./error_codes/E0061.md"),
-E0062: include_str!("./error_codes/E0062.md"),
-E0063: include_str!("./error_codes/E0063.md"),
-E0067: include_str!("./error_codes/E0067.md"),
-E0069: include_str!("./error_codes/E0069.md"),
-E0070: include_str!("./error_codes/E0070.md"),
-E0071: include_str!("./error_codes/E0071.md"),
-E0072: include_str!("./error_codes/E0072.md"),
-E0073: include_str!("./error_codes/E0073.md"),
-E0074: include_str!("./error_codes/E0074.md"),
-E0075: include_str!("./error_codes/E0075.md"),
-E0076: include_str!("./error_codes/E0076.md"),
-E0077: include_str!("./error_codes/E0077.md"),
-E0080: include_str!("./error_codes/E0080.md"),
-E0081: include_str!("./error_codes/E0081.md"),
-E0084: include_str!("./error_codes/E0084.md"),
-E0087: include_str!("./error_codes/E0087.md"),
-E0088: include_str!("./error_codes/E0088.md"),
-E0089: include_str!("./error_codes/E0089.md"),
-E0090: include_str!("./error_codes/E0090.md"),
-E0091: include_str!("./error_codes/E0091.md"),
-E0092: include_str!("./error_codes/E0092.md"),
-E0093: include_str!("./error_codes/E0093.md"),
-E0094: include_str!("./error_codes/E0094.md"),
-E0106: include_str!("./error_codes/E0106.md"),
-E0107: include_str!("./error_codes/E0107.md"),
-E0109: include_str!("./error_codes/E0109.md"),
-E0110: include_str!("./error_codes/E0110.md"),
-E0116: include_str!("./error_codes/E0116.md"),
-E0117: include_str!("./error_codes/E0117.md"),
-E0118: include_str!("./error_codes/E0118.md"),
-E0119: include_str!("./error_codes/E0119.md"),
-E0120: include_str!("./error_codes/E0120.md"),
-E0121: include_str!("./error_codes/E0121.md"),
-E0124: include_str!("./error_codes/E0124.md"),
-E0128: include_str!("./error_codes/E0128.md"),
-E0130: include_str!("./error_codes/E0130.md"),
-E0131: include_str!("./error_codes/E0131.md"),
-E0132: include_str!("./error_codes/E0132.md"),
-E0133: include_str!("./error_codes/E0133.md"),
-E0136: include_str!("./error_codes/E0136.md"),
-E0137: include_str!("./error_codes/E0137.md"),
-E0138: include_str!("./error_codes/E0138.md"),
-E0139: include_str!("./error_codes/E0139.md"),
-E0152: include_str!("./error_codes/E0152.md"),
-E0154: include_str!("./error_codes/E0154.md"),
-E0158: include_str!("./error_codes/E0158.md"),
-E0161: include_str!("./error_codes/E0161.md"),
-E0162: include_str!("./error_codes/E0162.md"),
-E0164: include_str!("./error_codes/E0164.md"),
-E0165: include_str!("./error_codes/E0165.md"),
-E0170: include_str!("./error_codes/E0170.md"),
-E0178: include_str!("./error_codes/E0178.md"),
-E0183: include_str!("./error_codes/E0183.md"),
-E0184: include_str!("./error_codes/E0184.md"),
-E0185: include_str!("./error_codes/E0185.md"),
-E0186: include_str!("./error_codes/E0186.md"),
-E0191: include_str!("./error_codes/E0191.md"),
-E0192: include_str!("./error_codes/E0192.md"),
-E0193: include_str!("./error_codes/E0193.md"),
-E0195: include_str!("./error_codes/E0195.md"),
-E0197: include_str!("./error_codes/E0197.md"),
-E0198: include_str!("./error_codes/E0198.md"),
-E0199: include_str!("./error_codes/E0199.md"),
-E0200: include_str!("./error_codes/E0200.md"),
-E0201: include_str!("./error_codes/E0201.md"),
-E0203: include_str!("./error_codes/E0203.md"),
-E0204: include_str!("./error_codes/E0204.md"),
-E0205: include_str!("./error_codes/E0205.md"),
-E0206: include_str!("./error_codes/E0206.md"),
-E0207: include_str!("./error_codes/E0207.md"),
-E0208: include_str!("./error_codes/E0208.md"),
-E0210: include_str!("./error_codes/E0210.md"),
-E0211: include_str!("./error_codes/E0211.md"),
-E0212: include_str!("./error_codes/E0212.md"),
-E0214: include_str!("./error_codes/E0214.md"),
-E0220: include_str!("./error_codes/E0220.md"),
-E0221: include_str!("./error_codes/E0221.md"),
-E0222: include_str!("./error_codes/E0222.md"),
-E0223: include_str!("./error_codes/E0223.md"),
-E0224: include_str!("./error_codes/E0224.md"),
-E0225: include_str!("./error_codes/E0225.md"),
-E0226: include_str!("./error_codes/E0226.md"),
-E0227: include_str!("./error_codes/E0227.md"),
-E0228: include_str!("./error_codes/E0228.md"),
-E0229: include_str!("./error_codes/E0229.md"),
-E0230: include_str!("./error_codes/E0230.md"),
-E0231: include_str!("./error_codes/E0231.md"),
-E0232: include_str!("./error_codes/E0232.md"),
-E0243: include_str!("./error_codes/E0243.md"),
-E0244: include_str!("./error_codes/E0244.md"),
-E0251: include_str!("./error_codes/E0251.md"),
-E0252: include_str!("./error_codes/E0252.md"),
-E0253: include_str!("./error_codes/E0253.md"),
-E0254: include_str!("./error_codes/E0254.md"),
-E0255: include_str!("./error_codes/E0255.md"),
-E0256: include_str!("./error_codes/E0256.md"),
-E0259: include_str!("./error_codes/E0259.md"),
-E0260: include_str!("./error_codes/E0260.md"),
-E0261: include_str!("./error_codes/E0261.md"),
-E0262: include_str!("./error_codes/E0262.md"),
-E0263: include_str!("./error_codes/E0263.md"),
-E0264: include_str!("./error_codes/E0264.md"),
-E0267: include_str!("./error_codes/E0267.md"),
-E0268: include_str!("./error_codes/E0268.md"),
-E0271: include_str!("./error_codes/E0271.md"),
-E0275: include_str!("./error_codes/E0275.md"),
-E0276: include_str!("./error_codes/E0276.md"),
-E0277: include_str!("./error_codes/E0277.md"),
-E0281: include_str!("./error_codes/E0281.md"),
-E0282: include_str!("./error_codes/E0282.md"),
-E0283: include_str!("./error_codes/E0283.md"),
-E0284: include_str!("./error_codes/E0284.md"),
-E0297: include_str!("./error_codes/E0297.md"),
-E0301: include_str!("./error_codes/E0301.md"),
-E0302: include_str!("./error_codes/E0302.md"),
-E0303: include_str!("./error_codes/E0303.md"),
-E0307: include_str!("./error_codes/E0307.md"),
-E0308: include_str!("./error_codes/E0308.md"),
-E0309: include_str!("./error_codes/E0309.md"),
-E0310: include_str!("./error_codes/E0310.md"),
-E0311: include_str!("./error_codes/E0311.md"),
-E0312: include_str!("./error_codes/E0312.md"),
-E0316: include_str!("./error_codes/E0316.md"),
-E0317: include_str!("./error_codes/E0317.md"),
-E0320: include_str!("./error_codes/E0320.md"),
-E0321: include_str!("./error_codes/E0321.md"),
-E0322: include_str!("./error_codes/E0322.md"),
-E0323: include_str!("./error_codes/E0323.md"),
-E0324: include_str!("./error_codes/E0324.md"),
-E0325: include_str!("./error_codes/E0325.md"),
-E0326: include_str!("./error_codes/E0326.md"),
-E0328: include_str!("./error_codes/E0328.md"),
-E0329: include_str!("./error_codes/E0329.md"),
-E0364: include_str!("./error_codes/E0364.md"),
-E0365: include_str!("./error_codes/E0365.md"),
-E0366: include_str!("./error_codes/E0366.md"),
-E0367: include_str!("./error_codes/E0367.md"),
-E0368: include_str!("./error_codes/E0368.md"),
-E0369: include_str!("./error_codes/E0369.md"),
-E0370: include_str!("./error_codes/E0370.md"),
-E0371: include_str!("./error_codes/E0371.md"),
-E0373: include_str!("./error_codes/E0373.md"),
-E0374: include_str!("./error_codes/E0374.md"),
-E0375: include_str!("./error_codes/E0375.md"),
-E0376: include_str!("./error_codes/E0376.md"),
-E0377: include_str!("./error_codes/E0377.md"),
-E0378: include_str!("./error_codes/E0378.md"),
-E0379: include_str!("./error_codes/E0379.md"),
-E0380: include_str!("./error_codes/E0380.md"),
-E0381: include_str!("./error_codes/E0381.md"),
-E0382: include_str!("./error_codes/E0382.md"),
-E0383: include_str!("./error_codes/E0383.md"),
-E0384: include_str!("./error_codes/E0384.md"),
-E0386: include_str!("./error_codes/E0386.md"),
-E0387: include_str!("./error_codes/E0387.md"),
-E0388: include_str!("./error_codes/E0388.md"),
-E0389: include_str!("./error_codes/E0389.md"),
-E0390: include_str!("./error_codes/E0390.md"),
-E0391: include_str!("./error_codes/E0391.md"),
-E0392: include_str!("./error_codes/E0392.md"),
-E0393: include_str!("./error_codes/E0393.md"),
-E0398: include_str!("./error_codes/E0398.md"),
-E0399: include_str!("./error_codes/E0399.md"),
-E0401: include_str!("./error_codes/E0401.md"),
-E0403: include_str!("./error_codes/E0403.md"),
-E0404: include_str!("./error_codes/E0404.md"),
-E0405: include_str!("./error_codes/E0405.md"),
-E0407: include_str!("./error_codes/E0407.md"),
-E0408: include_str!("./error_codes/E0408.md"),
-E0409: include_str!("./error_codes/E0409.md"),
-E0411: include_str!("./error_codes/E0411.md"),
-E0412: include_str!("./error_codes/E0412.md"),
-E0415: include_str!("./error_codes/E0415.md"),
-E0416: include_str!("./error_codes/E0416.md"),
-E0422: include_str!("./error_codes/E0422.md"),
-E0423: include_str!("./error_codes/E0423.md"),
-E0424: include_str!("./error_codes/E0424.md"),
-E0425: include_str!("./error_codes/E0425.md"),
-E0426: include_str!("./error_codes/E0426.md"),
-E0428: include_str!("./error_codes/E0428.md"),
-E0429: include_str!("./error_codes/E0429.md"),
-E0430: include_str!("./error_codes/E0430.md"),
-E0431: include_str!("./error_codes/E0431.md"),
-E0432: include_str!("./error_codes/E0432.md"),
-E0433: include_str!("./error_codes/E0433.md"),
-E0434: include_str!("./error_codes/E0434.md"),
-E0435: include_str!("./error_codes/E0435.md"),
-E0436: include_str!("./error_codes/E0436.md"),
-E0437: include_str!("./error_codes/E0437.md"),
-E0438: include_str!("./error_codes/E0438.md"),
-E0439: include_str!("./error_codes/E0439.md"),
-E0445: include_str!("./error_codes/E0445.md"),
-E0446: include_str!("./error_codes/E0446.md"),
-E0447: include_str!("./error_codes/E0447.md"),
-E0448: include_str!("./error_codes/E0448.md"),
-E0449: include_str!("./error_codes/E0449.md"),
-E0451: include_str!("./error_codes/E0451.md"),
-E0452: include_str!("./error_codes/E0452.md"),
-E0453: include_str!("./error_codes/E0453.md"),
-E0454: include_str!("./error_codes/E0454.md"),
-E0455: include_str!("./error_codes/E0455.md"),
-E0457: include_str!("./error_codes/E0457.md"),
-E0458: include_str!("./error_codes/E0458.md"),
-E0459: include_str!("./error_codes/E0459.md"),
-E0460: include_str!("./error_codes/E0460.md"),
-E0461: include_str!("./error_codes/E0461.md"),
-E0462: include_str!("./error_codes/E0462.md"),
-E0463: include_str!("./error_codes/E0463.md"),
-E0464: include_str!("./error_codes/E0464.md"),
-E0466: include_str!("./error_codes/E0466.md"),
-E0468: include_str!("./error_codes/E0468.md"),
-E0469: include_str!("./error_codes/E0469.md"),
-E0472: include_str!("./error_codes/E0472.md"),
-E0476: include_str!("./error_codes/E0476.md"),
-E0477: include_str!("./error_codes/E0477.md"),
-E0478: include_str!("./error_codes/E0478.md"),
-E0482: include_str!("./error_codes/E0482.md"),
-E0491: include_str!("./error_codes/E0491.md"),
-E0492: include_str!("./error_codes/E0492.md"),
-E0493: include_str!("./error_codes/E0493.md"),
-E0495: include_str!("./error_codes/E0495.md"),
-E0496: include_str!("./error_codes/E0496.md"),
-E0497: include_str!("./error_codes/E0497.md"),
-E0498: include_str!("./error_codes/E0498.md"),
-E0499: include_str!("./error_codes/E0499.md"),
-E0500: include_str!("./error_codes/E0500.md"),
-E0501: include_str!("./error_codes/E0501.md"),
-E0502: include_str!("./error_codes/E0502.md"),
-E0503: include_str!("./error_codes/E0503.md"),
-E0504: include_str!("./error_codes/E0504.md"),
-E0505: include_str!("./error_codes/E0505.md"),
-E0506: include_str!("./error_codes/E0506.md"),
-E0507: include_str!("./error_codes/E0507.md"),
-E0508: include_str!("./error_codes/E0508.md"),
-E0509: include_str!("./error_codes/E0509.md"),
-E0510: include_str!("./error_codes/E0510.md"),
-E0511: include_str!("./error_codes/E0511.md"),
-E0512: include_str!("./error_codes/E0512.md"),
-E0514: include_str!("./error_codes/E0514.md"),
-E0515: include_str!("./error_codes/E0515.md"),
-E0516: include_str!("./error_codes/E0516.md"),
-E0517: include_str!("./error_codes/E0517.md"),
-E0518: include_str!("./error_codes/E0518.md"),
-E0519: include_str!("./error_codes/E0519.md"),
-E0520: include_str!("./error_codes/E0520.md"),
-E0521: include_str!("./error_codes/E0521.md"),
-E0522: include_str!("./error_codes/E0522.md"),
-E0523: include_str!("./error_codes/E0523.md"),
-E0524: include_str!("./error_codes/E0524.md"),
-E0525: include_str!("./error_codes/E0525.md"),
-E0527: include_str!("./error_codes/E0527.md"),
-E0528: include_str!("./error_codes/E0528.md"),
-E0529: include_str!("./error_codes/E0529.md"),
-E0530: include_str!("./error_codes/E0530.md"),
-E0531: include_str!("./error_codes/E0531.md"),
-E0532: include_str!("./error_codes/E0532.md"),
-E0533: include_str!("./error_codes/E0533.md"),
-E0534: include_str!("./error_codes/E0534.md"),
-E0535: include_str!("./error_codes/E0535.md"),
-E0536: include_str!("./error_codes/E0536.md"),
-E0537: include_str!("./error_codes/E0537.md"),
-E0538: include_str!("./error_codes/E0538.md"),
-E0539: include_str!("./error_codes/E0539.md"),
-E0541: include_str!("./error_codes/E0541.md"),
-E0542: include_str!("./error_codes/E0542.md"),
-E0543: include_str!("./error_codes/E0543.md"),
-E0544: include_str!("./error_codes/E0544.md"),
-E0545: include_str!("./error_codes/E0545.md"),
-E0546: include_str!("./error_codes/E0546.md"),
-E0547: include_str!("./error_codes/E0547.md"),
-E0549: include_str!("./error_codes/E0549.md"),
-E0550: include_str!("./error_codes/E0550.md"),
-E0551: include_str!("./error_codes/E0551.md"),
-E0552: include_str!("./error_codes/E0552.md"),
-E0554: include_str!("./error_codes/E0554.md"),
-E0556: include_str!("./error_codes/E0556.md"),
-E0557: include_str!("./error_codes/E0557.md"),
-E0559: include_str!("./error_codes/E0559.md"),
-E0560: include_str!("./error_codes/E0560.md"),
-E0561: include_str!("./error_codes/E0561.md"),
-E0562: include_str!("./error_codes/E0562.md"),
-E0565: include_str!("./error_codes/E0565.md"),
-E0566: include_str!("./error_codes/E0566.md"),
-E0567: include_str!("./error_codes/E0567.md"),
-E0568: include_str!("./error_codes/E0568.md"),
-E0569: include_str!("./error_codes/E0569.md"),
-E0570: include_str!("./error_codes/E0570.md"),
-E0571: include_str!("./error_codes/E0571.md"),
-E0572: include_str!("./error_codes/E0572.md"),
-E0573: include_str!("./error_codes/E0573.md"),
-E0574: include_str!("./error_codes/E0574.md"),
-E0575: include_str!("./error_codes/E0575.md"),
-E0576: include_str!("./error_codes/E0576.md"),
-E0577: include_str!("./error_codes/E0577.md"),
-E0578: include_str!("./error_codes/E0578.md"),
-E0579: include_str!("./error_codes/E0579.md"),
-E0580: include_str!("./error_codes/E0580.md"),
-E0581: include_str!("./error_codes/E0581.md"),
-E0582: include_str!("./error_codes/E0582.md"),
-E0583: include_str!("./error_codes/E0583.md"),
-E0584: include_str!("./error_codes/E0584.md"),
-E0585: include_str!("./error_codes/E0585.md"),
-E0586: include_str!("./error_codes/E0586.md"),
-E0587: include_str!("./error_codes/E0587.md"),
-E0588: include_str!("./error_codes/E0588.md"),
-E0589: include_str!("./error_codes/E0589.md"),
-E0590: include_str!("./error_codes/E0590.md"),
-E0591: include_str!("./error_codes/E0591.md"),
-E0592: include_str!("./error_codes/E0592.md"),
-E0593: include_str!("./error_codes/E0593.md"),
-E0594: include_str!("./error_codes/E0594.md"),
-E0595: include_str!("./error_codes/E0595.md"),
-E0596: include_str!("./error_codes/E0596.md"),
-E0597: include_str!("./error_codes/E0597.md"),
-E0599: include_str!("./error_codes/E0599.md"),
-E0600: include_str!("./error_codes/E0600.md"),
-E0601: include_str!("./error_codes/E0601.md"),
-E0602: include_str!("./error_codes/E0602.md"),
-E0603: include_str!("./error_codes/E0603.md"),
-E0604: include_str!("./error_codes/E0604.md"),
-E0605: include_str!("./error_codes/E0605.md"),
-E0606: include_str!("./error_codes/E0606.md"),
-E0607: include_str!("./error_codes/E0607.md"),
-E0608: include_str!("./error_codes/E0608.md"),
-E0609: include_str!("./error_codes/E0609.md"),
-E0610: include_str!("./error_codes/E0610.md"),
-E0614: include_str!("./error_codes/E0614.md"),
-E0615: include_str!("./error_codes/E0615.md"),
-E0616: include_str!("./error_codes/E0616.md"),
-E0617: include_str!("./error_codes/E0617.md"),
-E0618: include_str!("./error_codes/E0618.md"),
-E0619: include_str!("./error_codes/E0619.md"),
-E0620: include_str!("./error_codes/E0620.md"),
-E0621: include_str!("./error_codes/E0621.md"),
-E0622: include_str!("./error_codes/E0622.md"),
-E0623: include_str!("./error_codes/E0623.md"),
-E0624: include_str!("./error_codes/E0624.md"),
-E0625: include_str!("./error_codes/E0625.md"),
-E0626: include_str!("./error_codes/E0626.md"),
-E0627: include_str!("./error_codes/E0627.md"),
-E0628: include_str!("./error_codes/E0628.md"),
-E0631: include_str!("./error_codes/E0631.md"),
-E0632: include_str!("./error_codes/E0632.md"),
-E0633: include_str!("./error_codes/E0633.md"),
-E0634: include_str!("./error_codes/E0634.md"),
-E0635: include_str!("./error_codes/E0635.md"),
-E0636: include_str!("./error_codes/E0636.md"),
-E0637: include_str!("./error_codes/E0637.md"),
-E0638: include_str!("./error_codes/E0638.md"),
-E0639: include_str!("./error_codes/E0639.md"),
-E0640: include_str!("./error_codes/E0640.md"),
-E0641: include_str!("./error_codes/E0641.md"),
-E0642: include_str!("./error_codes/E0642.md"),
-E0643: include_str!("./error_codes/E0643.md"),
-E0644: include_str!("./error_codes/E0644.md"),
-E0646: include_str!("./error_codes/E0646.md"),
-E0647: include_str!("./error_codes/E0647.md"),
-E0648: include_str!("./error_codes/E0648.md"),
-E0657: include_str!("./error_codes/E0657.md"),
-E0658: include_str!("./error_codes/E0658.md"),
-E0659: include_str!("./error_codes/E0659.md"),
-E0660: include_str!("./error_codes/E0660.md"),
-E0661: include_str!("./error_codes/E0661.md"),
-E0662: include_str!("./error_codes/E0662.md"),
-E0663: include_str!("./error_codes/E0663.md"),
-E0664: include_str!("./error_codes/E0664.md"),
-E0665: include_str!("./error_codes/E0665.md"),
-E0666: include_str!("./error_codes/E0666.md"),
-E0667: include_str!("./error_codes/E0667.md"),
-E0668: include_str!("./error_codes/E0668.md"),
-E0669: include_str!("./error_codes/E0669.md"),
-E0670: include_str!("./error_codes/E0670.md"),
-E0671: include_str!("./error_codes/E0671.md"),
-E0687: include_str!("./error_codes/E0687.md"),
-E0688: include_str!("./error_codes/E0688.md"),
-E0689: include_str!("./error_codes/E0689.md"),
-E0690: include_str!("./error_codes/E0690.md"),
-E0691: include_str!("./error_codes/E0691.md"),
-E0692: include_str!("./error_codes/E0692.md"),
-E0693: include_str!("./error_codes/E0693.md"),
-E0695: include_str!("./error_codes/E0695.md"),
-E0696: include_str!("./error_codes/E0696.md"),
-E0697: include_str!("./error_codes/E0697.md"),
-E0698: include_str!("./error_codes/E0698.md"),
-E0699: include_str!("./error_codes/E0699.md"),
-E0700: include_str!("./error_codes/E0700.md"),
-E0701: include_str!("./error_codes/E0701.md"),
-E0703: include_str!("./error_codes/E0703.md"),
-E0704: include_str!("./error_codes/E0704.md"),
-E0705: include_str!("./error_codes/E0705.md"),
-E0706: include_str!("./error_codes/E0706.md"),
-E0708: include_str!("./error_codes/E0708.md"),
-E0710: include_str!("./error_codes/E0710.md"),
-E0712: include_str!("./error_codes/E0712.md"),
-E0713: include_str!("./error_codes/E0713.md"),
-E0714: include_str!("./error_codes/E0714.md"),
-E0715: include_str!("./error_codes/E0715.md"),
-E0716: include_str!("./error_codes/E0716.md"),
-E0711: include_str!("./error_codes/E0711.md"),
-E0717: include_str!("./error_codes/E0717.md"),
-E0718: include_str!("./error_codes/E0718.md"),
-E0719: include_str!("./error_codes/E0719.md"),
-E0720: include_str!("./error_codes/E0720.md"),
-E0722: include_str!("./error_codes/E0722.md"),
-E0724: include_str!("./error_codes/E0724.md"),
-E0725: include_str!("./error_codes/E0725.md"),
-E0726: include_str!("./error_codes/E0726.md"),
-E0727: include_str!("./error_codes/E0727.md"),
-E0728: include_str!("./error_codes/E0728.md"),
-E0729: include_str!("./error_codes/E0729.md"),
-E0730: include_str!("./error_codes/E0730.md"),
-E0731: include_str!("./error_codes/E0731.md"),
-E0732: include_str!("./error_codes/E0732.md"),
-E0733: include_str!("./error_codes/E0733.md"),
-E0734: include_str!("./error_codes/E0734.md"),
-E0735: include_str!("./error_codes/E0735.md"),
-E0736: include_str!("./error_codes/E0736.md"),
-E0737: include_str!("./error_codes/E0737.md"),
-E0739: include_str!("./error_codes/E0739.md"),
-E0740: include_str!("./error_codes/E0740.md"),
-E0741: include_str!("./error_codes/E0741.md"),
-E0742: include_str!("./error_codes/E0742.md"),
-E0743: include_str!("./error_codes/E0743.md"),
-E0744: include_str!("./error_codes/E0744.md"),
-E0745: include_str!("./error_codes/E0745.md"),
-E0746: include_str!("./error_codes/E0746.md"),
-E0747: include_str!("./error_codes/E0747.md"),
-E0748: include_str!("./error_codes/E0748.md"),
-E0749: include_str!("./error_codes/E0749.md"),
-E0750: include_str!("./error_codes/E0750.md"),
-E0751: include_str!("./error_codes/E0751.md"),
-E0752: include_str!("./error_codes/E0752.md"),
-E0753: include_str!("./error_codes/E0753.md"),
-E0754: include_str!("./error_codes/E0754.md"),
-E0755: include_str!("./error_codes/E0755.md"),
-E0756: include_str!("./error_codes/E0756.md"),
-E0757: include_str!("./error_codes/E0757.md"),
-E0758: include_str!("./error_codes/E0758.md"),
-E0759: include_str!("./error_codes/E0759.md"),
-E0760: include_str!("./error_codes/E0760.md"),
-E0761: include_str!("./error_codes/E0761.md"),
-E0762: include_str!("./error_codes/E0762.md"),
-E0763: include_str!("./error_codes/E0763.md"),
-E0764: include_str!("./error_codes/E0764.md"),
-E0765: include_str!("./error_codes/E0765.md"),
-E0766: include_str!("./error_codes/E0766.md"),
-E0767: include_str!("./error_codes/E0767.md"),
-E0768: include_str!("./error_codes/E0768.md"),
-E0769: include_str!("./error_codes/E0769.md"),
-E0770: include_str!("./error_codes/E0770.md"),
-E0771: include_str!("./error_codes/E0771.md"),
-E0772: include_str!("./error_codes/E0772.md"),
-E0773: include_str!("./error_codes/E0773.md"),
-E0774: include_str!("./error_codes/E0774.md"),
-E0775: include_str!("./error_codes/E0775.md"),
-E0776: include_str!("./error_codes/E0776.md"),
-E0777: include_str!("./error_codes/E0777.md"),
-E0778: include_str!("./error_codes/E0778.md"),
-E0779: include_str!("./error_codes/E0779.md"),
-E0780: include_str!("./error_codes/E0780.md"),
-E0781: include_str!("./error_codes/E0781.md"),
-E0782: include_str!("./error_codes/E0782.md"),
-E0783: include_str!("./error_codes/E0783.md"),
-E0784: include_str!("./error_codes/E0784.md"),
-E0785: include_str!("./error_codes/E0785.md"),
-E0786: include_str!("./error_codes/E0786.md"),
-E0787: include_str!("./error_codes/E0787.md"),
-E0788: include_str!("./error_codes/E0788.md"),
-E0789: include_str!("./error_codes/E0789.md"),
-E0790: include_str!("./error_codes/E0790.md"),
-E0791: include_str!("./error_codes/E0791.md"),
-E0792: include_str!("./error_codes/E0792.md"),
-E0793: include_str!("./error_codes/E0793.md"),
-E0794: include_str!("./error_codes/E0794.md"),
-E0795: include_str!("./error_codes/E0795.md"),
-E0796: include_str!("./error_codes/E0796.md"),
-E0797: include_str!("./error_codes/E0797.md"),
-}
-
-// Undocumented removed error codes. Note that many removed error codes are kept in the list above
-// and marked as no-longer emitted with a note in the markdown file (see E0001 for an example).
-//  E0006, // merged with E0005
-//  E0008, // cannot bind by-move into a pattern guard
-//  E0019, // merged into E0015
-//  E0035, // merged into E0087/E0089
-//  E0036, // merged into E0087/E0089
-//  E0068,
-//  E0085,
-//  E0086,
-//  E0101, // replaced with E0282
-//  E0102, // replaced with E0282
-//  E0103,
-//  E0104,
-//  E0122, // bounds in type aliases are ignored, turned into proper lint
-//  E0123,
-//  E0127,
-//  E0129,
-//  E0134,
-//  E0135,
-//  E0141,
-//  E0153, // unused error code
-//  E0157, // unused error code
-//  E0159, // use of trait `{}` as struct constructor
-//  E0163, // merged into E0071
-//  E0167,
-//  E0168,
-//  E0172, // non-trait found in a type sum, moved to resolve
-//  E0173, // manual implementations of unboxed closure traits are experimental
-//  E0174,
-//  E0182, // merged into E0229
-//  E0187, // cannot infer the kind of the closure
-//  E0188, // can not cast an immutable reference to a mutable pointer
-//  E0189, // deprecated: can only cast a boxed pointer to a boxed object
-//  E0190, // deprecated: can only cast a &-pointer to an &-object
-//  E0194, // merged into E0403
-//  E0196, // cannot determine a type for this closure
-//  E0209, // builtin traits can only be implemented on structs or enums
-//  E0213, // associated types are not accepted in this context
-//  E0215, // angle-bracket notation is not stable with `Fn`
-//  E0216, // parenthetical notation is only stable with `Fn`
-//  E0217, // ambiguous associated type, defined in multiple supertraits
-//  E0218, // no associated type defined
-//  E0219, // associated type defined in higher-ranked supertrait
-//  E0233,
-//  E0234,
-//  E0235, // structure constructor specifies a structure of type but
-//  E0236, // no lang item for range syntax
-//  E0237, // no lang item for range syntax
-//  E0238, // parenthesized parameters may only be used with a trait
-//  E0239, // `next` method of `Iterator` trait has unexpected type
-//  E0240,
-//  E0241,
-//  E0242,
-//  E0245, // not a trait
-//  E0246, // invalid recursive type
-//  E0247,
-//  E0248, // value used as a type, now reported earlier during resolution
-//         // as E0412
-//  E0249,
-//  E0257,
-//  E0258,
-//  E0272, // on_unimplemented #0
-//  E0273, // on_unimplemented #1
-//  E0274, // on_unimplemented #2
-//  E0278, // requirement is not satisfied
-//  E0279,
-//  E0280, // changed to ICE
-//  E0285, // overflow evaluation builtin bounds
-//  E0296, // replaced with a generic attribute input check
-//  E0298, // cannot compare constants
-//  E0299, // mismatched types between arms
-//  E0300, // unexpanded macro
-//  E0304, // expected signed integer constant
-//  E0305, // expected constant
-//  E0313, // removed: found unreachable
-//  E0314, // closure outlives stack frame
-//  E0315, // cannot invoke closure outside of its lifetime
-//  E0319, // trait impls for defaulted traits allowed just for structs/enums
-//  E0372, // coherence not object safe
-//  E0385, // {} in an aliasable location
-//  E0402, // cannot use an outer type parameter in this context
-//  E0406, // merged into 420
-//  E0410, // merged into 408
-//  E0413, // merged into 530
-//  E0414, // merged into 530
-//  E0417, // merged into 532
-//  E0418, // merged into 532
-//  E0419, // merged into 531
-//  E0420, // merged into 532
-//  E0421, // merged into 531
-//  E0427, // merged into 530
-//  E0445, // merged into 446 and type privacy lints
-//  E0456, // plugin `..` is not available for triple `..`
-//  E0465, // removed: merged with E0464
-//  E0467, // removed
-//  E0470, // removed
-//  E0471, // constant evaluation error (in pattern)
-//  E0473, // dereference of reference outside its lifetime
-//  E0474, // captured variable `..` does not outlive the enclosing closure
-//  E0475, // index of slice outside its lifetime
-//  E0479, // the type `..` (provided as the value of a type parameter) is...
-//  E0480, // lifetime of method receiver does not outlive the method call
-//  E0481, // lifetime of function argument does not outlive the function call
-//  E0483, // lifetime of operand does not outlive the operation
-//  E0484, // reference is not valid at the time of borrow
-//  E0485, // automatically reference is not valid at the time of borrow
-//  E0486, // type of expression contains references that are not valid during..
-//  E0487, // unsafe use of destructor: destructor might be called while...
-//  E0488, // lifetime of variable does not enclose its declaration
-//  E0489, // type/lifetime parameter not in scope here
-//  E0490, // removed: unreachable
-//  E0526, // shuffle indices are not constant
-//  E0540, // multiple rustc_deprecated attributes
-//  E0548, // replaced with a generic attribute input check
-//  E0553, // multiple rustc_const_unstable attributes
-//  E0555, // replaced with a generic attribute input check
-//  E0558, // replaced with a generic attribute input check
-//  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
-//  E0564, // only named lifetimes are allowed in `impl Trait`,
-//         // but `{}` was found in the type `{}`
-//  E0598, // lifetime of {} is too short to guarantee its contents can be...
-//  E0611, // merged into E0616
-//  E0612, // merged into E0609
-//  E0613, // Removed (merged with E0609)
-//  E0629, // missing 'feature' (rustc_const_unstable)
-//  E0630, // rustc_const_unstable attribute must be paired with stable/unstable
-//         // attribute
-//  E0645, // trait aliases not finished
-//  E0694, // an unknown tool name found in scoped attributes
-//  E0702, // replaced with a generic attribute input check
-//  E0707, // multiple elided lifetimes used in arguments of `async fn`
-//  E0709, // multiple different lifetimes used in arguments of `async fn`
-//  E0721, // `await` keyword
-//  E0723, // unstable feature in `const` context
-//  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
-//  E0744, // merged into E0728
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index dd281811636..5b2766618fc 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -1,19 +1,679 @@
+//! This library is used to gather all error codes into one place, to make
+//! their maintenance easier.
+
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![deny(rustdoc::invalid_codeblock_attributes)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-//! This library is used to gather all error codes into one place,
-//! the goal being to make their maintenance easier.
 
-macro_rules! register_diagnostics {
-    ($($ecode:ident: $message:expr,)*) => (
-        pub static DIAGNOSTICS: &[(&str, &str)] = &[
-            $( (stringify!($ecode), $message), )*
-        ];
+// This higher-order macro defines the error codes that are in use. It is used
+// in the `rustc_errors` crate. Removed error codes are listed in the comment
+// below.
+//
+// /!\ IMPORTANT /!\
+//
+// Error code explanation are defined in `error_codes/EXXXX.md` files. They must follow the RFC
+// 1567 available here:
+// https://rust-lang.github.io/rfcs/1567-long-error-codes-explanation-normalization.html
+//
+// Also, the contents of this macro is checked by tidy (in `check_error_codes_docs`). If you change
+// the macro syntax you will need to change tidy as well.
+//
+// Both columns are necessary because it's not possible in Rust to create a new identifier such as
+// `E0123` from an integer literal such as `0123`, unfortunately.
+#[macro_export]
+macro_rules! error_codes {
+    ($macro:path) => (
+        $macro!(
+E0001: 0001,
+E0002: 0002,
+E0004: 0004,
+E0005: 0005,
+E0007: 0007,
+E0009: 0009,
+E0010: 0010,
+E0013: 0013,
+E0014: 0014,
+E0015: 0015,
+E0023: 0023,
+E0025: 0025,
+E0026: 0026,
+E0027: 0027,
+E0029: 0029,
+E0030: 0030,
+E0033: 0033,
+E0034: 0034,
+E0038: 0038,
+E0040: 0040,
+E0044: 0044,
+E0045: 0045,
+E0046: 0046,
+E0049: 0049,
+E0050: 0050,
+E0053: 0053,
+E0054: 0054,
+E0055: 0055,
+E0057: 0057,
+E0059: 0059,
+E0060: 0060,
+E0061: 0061,
+E0062: 0062,
+E0063: 0063,
+E0067: 0067,
+E0069: 0069,
+E0070: 0070,
+E0071: 0071,
+E0072: 0072,
+E0073: 0073,
+E0074: 0074,
+E0075: 0075,
+E0076: 0076,
+E0077: 0077,
+E0080: 0080,
+E0081: 0081,
+E0084: 0084,
+E0087: 0087,
+E0088: 0088,
+E0089: 0089,
+E0090: 0090,
+E0091: 0091,
+E0092: 0092,
+E0093: 0093,
+E0094: 0094,
+E0106: 0106,
+E0107: 0107,
+E0109: 0109,
+E0110: 0110,
+E0116: 0116,
+E0117: 0117,
+E0118: 0118,
+E0119: 0119,
+E0120: 0120,
+E0121: 0121,
+E0124: 0124,
+E0128: 0128,
+E0130: 0130,
+E0131: 0131,
+E0132: 0132,
+E0133: 0133,
+E0136: 0136,
+E0137: 0137,
+E0138: 0138,
+E0139: 0139,
+E0152: 0152,
+E0154: 0154,
+E0158: 0158,
+E0161: 0161,
+E0162: 0162,
+E0164: 0164,
+E0165: 0165,
+E0170: 0170,
+E0178: 0178,
+E0183: 0183,
+E0184: 0184,
+E0185: 0185,
+E0186: 0186,
+E0191: 0191,
+E0192: 0192,
+E0193: 0193,
+E0195: 0195,
+E0197: 0197,
+E0198: 0198,
+E0199: 0199,
+E0200: 0200,
+E0201: 0201,
+E0203: 0203,
+E0204: 0204,
+E0205: 0205,
+E0206: 0206,
+E0207: 0207,
+E0208: 0208,
+E0210: 0210,
+E0211: 0211,
+E0212: 0212,
+E0214: 0214,
+E0220: 0220,
+E0221: 0221,
+E0222: 0222,
+E0223: 0223,
+E0224: 0224,
+E0225: 0225,
+E0226: 0226,
+E0227: 0227,
+E0228: 0228,
+E0229: 0229,
+E0230: 0230,
+E0231: 0231,
+E0232: 0232,
+E0243: 0243,
+E0244: 0244,
+E0251: 0251,
+E0252: 0252,
+E0253: 0253,
+E0254: 0254,
+E0255: 0255,
+E0256: 0256,
+E0259: 0259,
+E0260: 0260,
+E0261: 0261,
+E0262: 0262,
+E0263: 0263,
+E0264: 0264,
+E0267: 0267,
+E0268: 0268,
+E0271: 0271,
+E0275: 0275,
+E0276: 0276,
+E0277: 0277,
+E0281: 0281,
+E0282: 0282,
+E0283: 0283,
+E0284: 0284,
+E0297: 0297,
+E0301: 0301,
+E0302: 0302,
+E0303: 0303,
+E0307: 0307,
+E0308: 0308,
+E0309: 0309,
+E0310: 0310,
+E0311: 0311,
+E0312: 0312,
+E0316: 0316,
+E0317: 0317,
+E0320: 0320,
+E0321: 0321,
+E0322: 0322,
+E0323: 0323,
+E0324: 0324,
+E0325: 0325,
+E0326: 0326,
+E0328: 0328,
+E0329: 0329,
+E0364: 0364,
+E0365: 0365,
+E0366: 0366,
+E0367: 0367,
+E0368: 0368,
+E0369: 0369,
+E0370: 0370,
+E0371: 0371,
+E0373: 0373,
+E0374: 0374,
+E0375: 0375,
+E0376: 0376,
+E0377: 0377,
+E0378: 0378,
+E0379: 0379,
+E0380: 0380,
+E0381: 0381,
+E0382: 0382,
+E0383: 0383,
+E0384: 0384,
+E0386: 0386,
+E0387: 0387,
+E0388: 0388,
+E0389: 0389,
+E0390: 0390,
+E0391: 0391,
+E0392: 0392,
+E0393: 0393,
+E0398: 0398,
+E0399: 0399,
+E0401: 0401,
+E0403: 0403,
+E0404: 0404,
+E0405: 0405,
+E0407: 0407,
+E0408: 0408,
+E0409: 0409,
+E0411: 0411,
+E0412: 0412,
+E0415: 0415,
+E0416: 0416,
+E0422: 0422,
+E0423: 0423,
+E0424: 0424,
+E0425: 0425,
+E0426: 0426,
+E0428: 0428,
+E0429: 0429,
+E0430: 0430,
+E0431: 0431,
+E0432: 0432,
+E0433: 0433,
+E0434: 0434,
+E0435: 0435,
+E0436: 0436,
+E0437: 0437,
+E0438: 0438,
+E0439: 0439,
+E0445: 0445,
+E0446: 0446,
+E0447: 0447,
+E0448: 0448,
+E0449: 0449,
+E0451: 0451,
+E0452: 0452,
+E0453: 0453,
+E0454: 0454,
+E0455: 0455,
+E0457: 0457,
+E0458: 0458,
+E0459: 0459,
+E0460: 0460,
+E0461: 0461,
+E0462: 0462,
+E0463: 0463,
+E0464: 0464,
+E0466: 0466,
+E0468: 0468,
+E0469: 0469,
+E0472: 0472,
+E0476: 0476,
+E0477: 0477,
+E0478: 0478,
+E0482: 0482,
+E0491: 0491,
+E0492: 0492,
+E0493: 0493,
+E0495: 0495,
+E0496: 0496,
+E0497: 0497,
+E0498: 0498,
+E0499: 0499,
+E0500: 0500,
+E0501: 0501,
+E0502: 0502,
+E0503: 0503,
+E0504: 0504,
+E0505: 0505,
+E0506: 0506,
+E0507: 0507,
+E0508: 0508,
+E0509: 0509,
+E0510: 0510,
+E0511: 0511,
+E0512: 0512,
+E0514: 0514,
+E0515: 0515,
+E0516: 0516,
+E0517: 0517,
+E0518: 0518,
+E0519: 0519,
+E0520: 0520,
+E0521: 0521,
+E0522: 0522,
+E0523: 0523,
+E0524: 0524,
+E0525: 0525,
+E0527: 0527,
+E0528: 0528,
+E0529: 0529,
+E0530: 0530,
+E0531: 0531,
+E0532: 0532,
+E0533: 0533,
+E0534: 0534,
+E0535: 0535,
+E0536: 0536,
+E0537: 0537,
+E0538: 0538,
+E0539: 0539,
+E0541: 0541,
+E0542: 0542,
+E0543: 0543,
+E0544: 0544,
+E0545: 0545,
+E0546: 0546,
+E0547: 0547,
+E0549: 0549,
+E0550: 0550,
+E0551: 0551,
+E0552: 0552,
+E0554: 0554,
+E0556: 0556,
+E0557: 0557,
+E0559: 0559,
+E0560: 0560,
+E0561: 0561,
+E0562: 0562,
+E0565: 0565,
+E0566: 0566,
+E0567: 0567,
+E0568: 0568,
+E0569: 0569,
+E0570: 0570,
+E0571: 0571,
+E0572: 0572,
+E0573: 0573,
+E0574: 0574,
+E0575: 0575,
+E0576: 0576,
+E0577: 0577,
+E0578: 0578,
+E0579: 0579,
+E0580: 0580,
+E0581: 0581,
+E0582: 0582,
+E0583: 0583,
+E0584: 0584,
+E0585: 0585,
+E0586: 0586,
+E0587: 0587,
+E0588: 0588,
+E0589: 0589,
+E0590: 0590,
+E0591: 0591,
+E0592: 0592,
+E0593: 0593,
+E0594: 0594,
+E0595: 0595,
+E0596: 0596,
+E0597: 0597,
+E0599: 0599,
+E0600: 0600,
+E0601: 0601,
+E0602: 0602,
+E0603: 0603,
+E0604: 0604,
+E0605: 0605,
+E0606: 0606,
+E0607: 0607,
+E0608: 0608,
+E0609: 0609,
+E0610: 0610,
+E0614: 0614,
+E0615: 0615,
+E0616: 0616,
+E0617: 0617,
+E0618: 0618,
+E0619: 0619,
+E0620: 0620,
+E0621: 0621,
+E0622: 0622,
+E0623: 0623,
+E0624: 0624,
+E0625: 0625,
+E0626: 0626,
+E0627: 0627,
+E0628: 0628,
+E0631: 0631,
+E0632: 0632,
+E0633: 0633,
+E0634: 0634,
+E0635: 0635,
+E0636: 0636,
+E0637: 0637,
+E0638: 0638,
+E0639: 0639,
+E0640: 0640,
+E0641: 0641,
+E0642: 0642,
+E0643: 0643,
+E0644: 0644,
+E0646: 0646,
+E0647: 0647,
+E0648: 0648,
+E0657: 0657,
+E0658: 0658,
+E0659: 0659,
+E0660: 0660,
+E0661: 0661,
+E0662: 0662,
+E0663: 0663,
+E0664: 0664,
+E0665: 0665,
+E0666: 0666,
+E0667: 0667,
+E0668: 0668,
+E0669: 0669,
+E0670: 0670,
+E0671: 0671,
+E0687: 0687,
+E0688: 0688,
+E0689: 0689,
+E0690: 0690,
+E0691: 0691,
+E0692: 0692,
+E0693: 0693,
+E0695: 0695,
+E0696: 0696,
+E0697: 0697,
+E0698: 0698,
+E0699: 0699,
+E0700: 0700,
+E0701: 0701,
+E0703: 0703,
+E0704: 0704,
+E0705: 0705,
+E0706: 0706,
+E0708: 0708,
+E0710: 0710,
+E0712: 0712,
+E0713: 0713,
+E0714: 0714,
+E0715: 0715,
+E0716: 0716,
+E0711: 0711,
+E0717: 0717,
+E0718: 0718,
+E0719: 0719,
+E0720: 0720,
+E0722: 0722,
+E0724: 0724,
+E0725: 0725,
+E0726: 0726,
+E0727: 0727,
+E0728: 0728,
+E0729: 0729,
+E0730: 0730,
+E0731: 0731,
+E0732: 0732,
+E0733: 0733,
+E0734: 0734,
+E0735: 0735,
+E0736: 0736,
+E0737: 0737,
+E0739: 0739,
+E0740: 0740,
+E0741: 0741,
+E0742: 0742,
+E0743: 0743,
+E0744: 0744,
+E0745: 0745,
+E0746: 0746,
+E0747: 0747,
+E0748: 0748,
+E0749: 0749,
+E0750: 0750,
+E0751: 0751,
+E0752: 0752,
+E0753: 0753,
+E0754: 0754,
+E0755: 0755,
+E0756: 0756,
+E0757: 0757,
+E0758: 0758,
+E0759: 0759,
+E0760: 0760,
+E0761: 0761,
+E0762: 0762,
+E0763: 0763,
+E0764: 0764,
+E0765: 0765,
+E0766: 0766,
+E0767: 0767,
+E0768: 0768,
+E0769: 0769,
+E0770: 0770,
+E0771: 0771,
+E0772: 0772,
+E0773: 0773,
+E0774: 0774,
+E0775: 0775,
+E0776: 0776,
+E0777: 0777,
+E0778: 0778,
+E0779: 0779,
+E0780: 0780,
+E0781: 0781,
+E0782: 0782,
+E0783: 0783,
+E0784: 0784,
+E0785: 0785,
+E0786: 0786,
+E0787: 0787,
+E0788: 0788,
+E0789: 0789,
+E0790: 0790,
+E0791: 0791,
+E0792: 0792,
+E0793: 0793,
+E0794: 0794,
+E0795: 0795,
+E0796: 0796,
+E0797: 0797,
+        );
     )
 }
 
-mod error_codes;
-pub use error_codes::DIAGNOSTICS;
+// Undocumented removed error codes. Note that many removed error codes are kept in the list above
+// and marked as no-longer emitted with a note in the markdown file (see E0001 for an example).
+//  E0006, // merged with E0005
+//  E0008, // cannot bind by-move into a pattern guard
+//  E0019, // merged into E0015
+//  E0035, // merged into E0087/E0089
+//  E0036, // merged into E0087/E0089
+//  E0068,
+//  E0085,
+//  E0086,
+//  E0101, // replaced with E0282
+//  E0102, // replaced with E0282
+//  E0103,
+//  E0104,
+//  E0122, // bounds in type aliases are ignored, turned into proper lint
+//  E0123,
+//  E0127,
+//  E0129,
+//  E0134,
+//  E0135,
+//  E0141,
+//  E0153, // unused error code
+//  E0157, // unused error code
+//  E0159, // use of trait `{}` as struct constructor
+//  E0163, // merged into E0071
+//  E0167,
+//  E0168,
+//  E0172, // non-trait found in a type sum, moved to resolve
+//  E0173, // manual implementations of unboxed closure traits are experimental
+//  E0174,
+//  E0182, // merged into E0229
+//  E0187, // cannot infer the kind of the closure
+//  E0188, // can not cast an immutable reference to a mutable pointer
+//  E0189, // deprecated: can only cast a boxed pointer to a boxed object
+//  E0190, // deprecated: can only cast a &-pointer to an &-object
+//  E0194, // merged into E0403
+//  E0196, // cannot determine a type for this closure
+//  E0209, // builtin traits can only be implemented on structs or enums
+//  E0213, // associated types are not accepted in this context
+//  E0215, // angle-bracket notation is not stable with `Fn`
+//  E0216, // parenthetical notation is only stable with `Fn`
+//  E0217, // ambiguous associated type, defined in multiple supertraits
+//  E0218, // no associated type defined
+//  E0219, // associated type defined in higher-ranked supertrait
+//  E0233,
+//  E0234,
+//  E0235, // structure constructor specifies a structure of type but
+//  E0236, // no lang item for range syntax
+//  E0237, // no lang item for range syntax
+//  E0238, // parenthesized parameters may only be used with a trait
+//  E0239, // `next` method of `Iterator` trait has unexpected type
+//  E0240,
+//  E0241,
+//  E0242,
+//  E0245, // not a trait
+//  E0246, // invalid recursive type
+//  E0247,
+//  E0248, // value used as a type, now reported earlier during resolution
+//         // as E0412
+//  E0249,
+//  E0257,
+//  E0258,
+//  E0272, // on_unimplemented #0
+//  E0273, // on_unimplemented #1
+//  E0274, // on_unimplemented #2
+//  E0278, // requirement is not satisfied
+//  E0279,
+//  E0280, // changed to ICE
+//  E0285, // overflow evaluation builtin bounds
+//  E0296, // replaced with a generic attribute input check
+//  E0298, // cannot compare constants
+//  E0299, // mismatched types between arms
+//  E0300, // unexpanded macro
+//  E0304, // expected signed integer constant
+//  E0305, // expected constant
+//  E0313, // removed: found unreachable
+//  E0314, // closure outlives stack frame
+//  E0315, // cannot invoke closure outside of its lifetime
+//  E0319, // trait impls for defaulted traits allowed just for structs/enums
+//  E0372, // coherence not object safe
+//  E0385, // {} in an aliasable location
+//  E0402, // cannot use an outer type parameter in this context
+//  E0406, // merged into 420
+//  E0410, // merged into 408
+//  E0413, // merged into 530
+//  E0414, // merged into 530
+//  E0417, // merged into 532
+//  E0418, // merged into 532
+//  E0419, // merged into 531
+//  E0420, // merged into 532
+//  E0421, // merged into 531
+//  E0427, // merged into 530
+//  E0445, // merged into 446 and type privacy lints
+//  E0456, // plugin `..` is not available for triple `..`
+//  E0465, // removed: merged with E0464
+//  E0467, // removed
+//  E0470, // removed
+//  E0471, // constant evaluation error (in pattern)
+//  E0473, // dereference of reference outside its lifetime
+//  E0474, // captured variable `..` does not outlive the enclosing closure
+//  E0475, // index of slice outside its lifetime
+//  E0479, // the type `..` (provided as the value of a type parameter) is...
+//  E0480, // lifetime of method receiver does not outlive the method call
+//  E0481, // lifetime of function argument does not outlive the function call
+//  E0483, // lifetime of operand does not outlive the operation
+//  E0484, // reference is not valid at the time of borrow
+//  E0485, // automatically reference is not valid at the time of borrow
+//  E0486, // type of expression contains references that are not valid during..
+//  E0487, // unsafe use of destructor: destructor might be called while...
+//  E0488, // lifetime of variable does not enclose its declaration
+//  E0489, // type/lifetime parameter not in scope here
+//  E0490, // removed: unreachable
+//  E0526, // shuffle indices are not constant
+//  E0540, // multiple rustc_deprecated attributes
+//  E0548, // replaced with a generic attribute input check
+//  E0553, // multiple rustc_const_unstable attributes
+//  E0555, // replaced with a generic attribute input check
+//  E0558, // replaced with a generic attribute input check
+//  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
+//  E0564, // only named lifetimes are allowed in `impl Trait`,
+//         // but `{}` was found in the type `{}`
+//  E0598, // lifetime of {} is too short to guarantee its contents can be...
+//  E0611, // merged into E0616
+//  E0612, // merged into E0609
+//  E0613, // Removed (merged with E0609)
+//  E0629, // missing 'feature' (rustc_const_unstable)
+//  E0630, // rustc_const_unstable attribute must be paired with stable/unstable
+//         // attribute
+//  E0645, // trait aliases not finished
+//  E0694, // an unknown tool name found in scoped attributes
+//  E0702, // replaced with a generic attribute input check
+//  E0707, // multiple elided lifetimes used in arguments of `async fn`
+//  E0709, // multiple different lifetimes used in arguments of `async fn`
+//  E0721, // `await` keyword
+//  E0723, // unstable feature in `const` context
+//  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
+//  E0744, // merged into E0728
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index fc544c31e89..8fd7c576479 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,6 +1,5 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![feature(let_chains)]
 #![feature(lazy_cell)]
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 0c1fcecb571..a2d1fd2a924 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -10,9 +10,11 @@ derive_setters = "0.1.6"
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_error_codes = { path = "../rustc_error_codes" }
 rustc_error_messages = { path = "../rustc_error_messages" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index f0699a56f98..949f52ef6b5 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -9,8 +9,8 @@ use crate::emitter::FileWithAnnotatedLines;
 use crate::snippet::Line;
 use crate::translation::{to_fluent_args, Translate};
 use crate::{
-    CodeSuggestion, Diagnostic, DiagnosticMessage, Emitter, FluentBundle, LazyFallbackBundle,
-    Level, MultiSpan, Style, SubDiagnostic,
+    CodeSuggestion, Diagnostic, DiagnosticMessage, Emitter, ErrCode, FluentBundle,
+    LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
 };
 use annotate_snippets::{Annotation, AnnotationType, Renderer, Slice, Snippet, SourceAnnotation};
 use rustc_data_structures::sync::Lrc;
@@ -127,7 +127,7 @@ impl AnnotateSnippetEmitter {
         level: &Level,
         messages: &[(DiagnosticMessage, Style)],
         args: &FluentArgs<'_>,
-        code: &Option<String>,
+        code: &Option<ErrCode>,
         msp: &MultiSpan,
         _children: &[SubDiagnostic],
         _suggestions: &[CodeSuggestion],
@@ -178,6 +178,7 @@ impl AnnotateSnippetEmitter {
                         .collect::<Vec<Owned>>()
                 })
                 .collect();
+            let code = code.map(|code| code.to_string());
             let snippet = Snippet {
                 title: Some(Annotation {
                     label: Some(&message),
diff --git a/compiler/rustc_errors/src/codes.rs b/compiler/rustc_errors/src/codes.rs
new file mode 100644
index 00000000000..947cf27ca79
--- /dev/null
+++ b/compiler/rustc_errors/src/codes.rs
@@ -0,0 +1,39 @@
+//! This module defines the following.
+//! - The `ErrCode` type.
+//! - A constant for every error code, with a name like `E0123`.
+//! - A static table `DIAGNOSTICS` pairing every error code constant with its
+//!   long description text.
+
+use std::fmt;
+
+rustc_index::newtype_index! {
+    #[max = 9999] // Because all error codes have four digits.
+    #[orderable]
+    #[encodable]
+    #[debug_format = "ErrCode({})"]
+    pub struct ErrCode {}
+}
+
+impl fmt::Display for ErrCode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "E{:04}", self.as_u32())
+    }
+}
+
+macro_rules! define_error_code_constants_and_diagnostics_table {
+    ($($name:ident: $num:literal,)*) => (
+        $(
+            pub const $name: $crate::ErrCode = $crate::ErrCode::from_u32($num);
+        )*
+        pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[
+            $( (
+                $name,
+                include_str!(
+                    concat!("../../rustc_error_codes/src/error_codes/", stringify!($name), ".md")
+                )
+            ), )*
+        ];
+    )
+}
+
+rustc_error_codes::error_codes!(define_error_code_constants_and_diagnostics_table);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 4934bc2450c..bf1ab37a1cf 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -1,7 +1,8 @@
 use crate::snippet::Style;
 use crate::{
-    CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level,
-    MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
+    CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee,
+    ErrCode, Level, MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart,
+    SuggestionStyle,
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
@@ -22,19 +23,18 @@ pub struct SuggestionsDisabled;
 /// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of
 /// `DiagnosticArg` are converted to `FluentArgs` (consuming the collection) at the start of
 /// diagnostic emission.
-pub type DiagnosticArg<'iter, 'source> =
-    (&'iter DiagnosticArgName<'source>, &'iter DiagnosticArgValue<'source>);
+pub type DiagnosticArg<'iter> = (&'iter DiagnosticArgName, &'iter DiagnosticArgValue);
 
 /// Name of a diagnostic argument.
-pub type DiagnosticArgName<'source> = Cow<'source, str>;
+pub type DiagnosticArgName = Cow<'static, str>;
 
 /// Simplified version of `FluentValue` that can implement `Encodable` and `Decodable`. Converted
 /// to a `FluentValue` by the emitter to be used in diagnostic translation.
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
-pub enum DiagnosticArgValue<'source> {
-    Str(Cow<'source, str>),
+pub enum DiagnosticArgValue {
+    Str(Cow<'static, str>),
     Number(i128),
-    StrListSepByAnd(Vec<Cow<'source, str>>),
+    StrListSepByAnd(Vec<Cow<'static, str>>),
 }
 
 /// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic`
@@ -42,23 +42,17 @@ pub enum DiagnosticArgValue<'source> {
 /// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*`
 /// crates to implement this.
 pub trait IntoDiagnosticArg {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>;
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue;
 }
 
-impl<'source> IntoDiagnosticArg for DiagnosticArgValue<'source> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        match self {
-            DiagnosticArgValue::Str(s) => DiagnosticArgValue::Str(Cow::Owned(s.into_owned())),
-            DiagnosticArgValue::Number(n) => DiagnosticArgValue::Number(n),
-            DiagnosticArgValue::StrListSepByAnd(l) => DiagnosticArgValue::StrListSepByAnd(
-                l.into_iter().map(|s| Cow::Owned(s.into_owned())).collect(),
-            ),
-        }
+impl IntoDiagnosticArg for DiagnosticArgValue {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
+        self
     }
 }
 
-impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
-    fn into(self) -> FluentValue<'source> {
+impl Into<FluentValue<'static>> for DiagnosticArgValue {
+    fn into(self) -> FluentValue<'static> {
         match self {
             DiagnosticArgValue::Str(s) => From::from(s),
             DiagnosticArgValue::Number(n) => From::from(n),
@@ -104,11 +98,11 @@ pub struct Diagnostic {
     pub(crate) level: Level,
 
     pub messages: Vec<(DiagnosticMessage, Style)>,
-    pub code: Option<String>,
+    pub code: Option<ErrCode>,
     pub span: MultiSpan,
     pub children: Vec<SubDiagnostic>,
     pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
-    args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>,
+    args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>,
 
     /// This is not used for highlighting or rendering any error message. Rather, it can be used
     /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
@@ -893,8 +887,8 @@ impl Diagnostic {
         self
     }
 
-    pub fn code(&mut self, s: String) -> &mut Self {
-        self.code = Some(s);
+    pub fn code(&mut self, code: ErrCode) -> &mut Self {
+        self.code = Some(code);
         self
     }
 
@@ -903,8 +897,8 @@ impl Diagnostic {
         self
     }
 
-    pub fn get_code(&self) -> Option<&str> {
-        self.code.as_deref()
+    pub fn get_code(&self) -> Option<ErrCode> {
+        self.code
     }
 
     pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
@@ -915,7 +909,7 @@ impl Diagnostic {
     // Exact iteration order of diagnostic arguments shouldn't make a difference to output because
     // they're only used in interpolation.
     #[allow(rustc::potential_query_instability)]
-    pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_, 'static>> {
+    pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
         self.args.iter()
     }
 
@@ -928,10 +922,7 @@ impl Diagnostic {
         self
     }
 
-    pub fn replace_args(
-        &mut self,
-        args: FxHashMap<DiagnosticArgName<'static>, DiagnosticArgValue<'static>>,
-    ) {
+    pub fn replace_args(&mut self, args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>) {
         self.args = args;
     }
 
@@ -989,8 +980,8 @@ impl Diagnostic {
     ) -> (
         &Level,
         &[(DiagnosticMessage, Style)],
-        Vec<(&Cow<'static, str>, &DiagnosticArgValue<'static>)>,
-        &Option<String>,
+        Vec<(&Cow<'static, str>, &DiagnosticArgValue)>,
+        &Option<ErrCode>,
         &Option<IsLint>,
         &MultiSpan,
         &Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 87e2d295c7f..8bfb1816486 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -1,7 +1,7 @@
 use crate::diagnostic::IntoDiagnosticArg;
 use crate::{DiagCtxt, Level, MultiSpan, StashKey};
 use crate::{
-    Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed, ExplicitBug,
+    Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrCode, ErrorGuaranteed, ExplicitBug,
     SubdiagnosticMessage,
 };
 use rustc_lint_defs::Applicability;
@@ -399,7 +399,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
         name: String, has_future_breakage: bool,
     ));
     forward!((code, with_code)(
-        s: String,
+        code: ErrCode,
     ));
     forward!((arg, with_arg)(
         name: impl Into<Cow<'static, str>>, arg: impl IntoDiagnosticArg,
@@ -439,12 +439,7 @@ impl<G: EmissionGuarantee> Drop for DiagnosticBuilder<'_, G> {
 
 #[macro_export]
 macro_rules! struct_span_code_err {
-    ($dcx:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        $dcx.struct_span_err($span, format!($($message)*)).with_code($crate::error_code!($code))
+    ($dcx:expr, $span:expr, $code:expr, $($message:tt)*) => ({
+        $dcx.struct_span_err($span, format!($($message)*)).with_code($code)
     })
 }
-
-#[macro_export]
-macro_rules! error_code {
-    ($code:ident) => {{ stringify!($code).to_owned() }};
-}
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index f6679ae9bb3..faab3fc663a 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -1,7 +1,7 @@
 use crate::diagnostic::DiagnosticLocation;
 use crate::{fluent_generated as fluent, AddToDiagnostic};
 use crate::{
-    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
+    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, ErrCode, IntoDiagnostic,
     IntoDiagnosticArg, Level,
 };
 use rustc_ast as ast;
@@ -23,7 +23,7 @@ use std::process::ExitStatus;
 pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
 
 impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.0.to_string().into_diagnostic_arg()
     }
 }
@@ -41,7 +41,7 @@ impl<'a, T: fmt::Display> From<&'a T> for DiagnosticArgFromDisplay<'a> {
 }
 
 impl<'a, T: Clone + IntoDiagnosticArg> IntoDiagnosticArg for &'a T {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.clone().into_diagnostic_arg()
     }
 }
@@ -50,7 +50,7 @@ macro_rules! into_diagnostic_arg_using_display {
     ($( $ty:ty ),+ $(,)?) => {
         $(
             impl IntoDiagnosticArg for $ty {
-                fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+                fn into_diagnostic_arg(self) -> DiagnosticArgValue {
                     self.to_string().into_diagnostic_arg()
                 }
             }
@@ -58,16 +58,29 @@ macro_rules! into_diagnostic_arg_using_display {
     }
 }
 
+macro_rules! into_diagnostic_arg_for_number {
+    ($( $ty:ty ),+ $(,)?) => {
+        $(
+            impl IntoDiagnosticArg for $ty {
+                fn into_diagnostic_arg(self) -> DiagnosticArgValue {
+                    // HACK: `FluentNumber` the underline backing struct represent
+                    // numbers using a f64 which can't represent all the i128 numbers
+                    // So in order to be able to use fluent selectors and still
+                    // have all the numbers representable we only convert numbers
+                    // below a certain threshold.
+                    if let Ok(n) = TryInto::<i128>::try_into(self) && n >= -100 && n <= 100 {
+                        DiagnosticArgValue::Number(n)
+                    } else {
+                        self.to_string().into_diagnostic_arg()
+                    }
+                }
+            }
+        )+
+    }
+}
+
 into_diagnostic_arg_using_display!(
     ast::ParamKindOrd,
-    i8,
-    u8,
-    i16,
-    u16,
-    u32,
-    i64,
-    i128,
-    u128,
     std::io::Error,
     Box<dyn std::error::Error>,
     std::num::NonZeroU32,
@@ -80,22 +93,13 @@ into_diagnostic_arg_using_display!(
     &TargetTriple,
     SplitDebuginfo,
     ExitStatus,
+    ErrCode,
 );
 
-impl IntoDiagnosticArg for i32 {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Number(self.into())
-    }
-}
-
-impl IntoDiagnosticArg for u64 {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Number(self.into())
-    }
-}
+into_diagnostic_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
 
 impl IntoDiagnosticArg for bool {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         if self {
             DiagnosticArgValue::Str(Cow::Borrowed("true"))
         } else {
@@ -105,13 +109,13 @@ impl IntoDiagnosticArg for bool {
 }
 
 impl IntoDiagnosticArg for char {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
     }
 }
 
 impl IntoDiagnosticArg for Vec<char> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::StrListSepByAnd(
             self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
         )
@@ -119,55 +123,49 @@ impl IntoDiagnosticArg for Vec<char> {
 }
 
 impl IntoDiagnosticArg for Symbol {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_ident_string().into_diagnostic_arg()
     }
 }
 
 impl<'a> IntoDiagnosticArg for &'a str {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
 
 impl IntoDiagnosticArg for String {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self))
     }
 }
 
 impl<'a> IntoDiagnosticArg for Cow<'a, str> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.into_owned()))
     }
 }
 
 impl<'a> IntoDiagnosticArg for &'a Path {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
     }
 }
 
 impl IntoDiagnosticArg for PathBuf {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
     }
 }
 
-impl IntoDiagnosticArg for usize {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Number(self as i128)
-    }
-}
-
 impl IntoDiagnosticArg for PanicStrategy {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
     }
 }
 
 impl IntoDiagnosticArg for hir::ConstContext {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(match self {
             hir::ConstContext::ConstFn => "const_fn",
             hir::ConstContext::Static(_) => "static",
@@ -177,49 +175,49 @@ impl IntoDiagnosticArg for hir::ConstContext {
 }
 
 impl IntoDiagnosticArg for ast::Expr {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(pprust::expr_to_string(&self)))
     }
 }
 
 impl IntoDiagnosticArg for ast::Path {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
     }
 }
 
 impl IntoDiagnosticArg for ast::token::Token {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(pprust::token_to_string(&self))
     }
 }
 
 impl IntoDiagnosticArg for ast::token::TokenKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(pprust::token_kind_to_string(&self))
     }
 }
 
 impl IntoDiagnosticArg for type_ir::FloatTy {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(self.name_str()))
     }
 }
 
 impl IntoDiagnosticArg for std::ffi::CString {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
     }
 }
 
 impl IntoDiagnosticArg for rustc_data_structures::small_c_str::SmallCStr {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
     }
 }
 
 impl IntoDiagnosticArg for ast::Visibility {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         let s = pprust::vis_to_string(&self);
         let s = s.trim_end().to_string();
         DiagnosticArgValue::Str(Cow::Owned(s))
@@ -227,7 +225,7 @@ impl IntoDiagnosticArg for ast::Visibility {
 }
 
 impl IntoDiagnosticArg for rustc_lint_defs::Level {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag()))
     }
 }
@@ -242,7 +240,7 @@ impl From<Vec<Symbol>> for DiagnosticSymbolList {
 }
 
 impl IntoDiagnosticArg for DiagnosticSymbolList {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::StrListSepByAnd(
             self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
         )
@@ -250,7 +248,7 @@ impl IntoDiagnosticArg for DiagnosticSymbolList {
 }
 
 impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
     }
 }
@@ -336,13 +334,13 @@ pub struct DelayedAtWithoutNewline {
 }
 
 impl IntoDiagnosticArg for DiagnosticLocation {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::from(self.to_string()))
     }
 }
 
 impl IntoDiagnosticArg for Backtrace {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::from(self.to_string()))
     }
 }
@@ -355,7 +353,7 @@ pub struct InvalidFlushedDelayedDiagnosticLevel {
     pub level: Level,
 }
 impl IntoDiagnosticArg for Level {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::from(self.to_string()))
     }
 }
@@ -370,7 +368,7 @@ pub struct IndicateAnonymousLifetime {
 }
 
 impl IntoDiagnosticArg for type_ir::ClosureKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(self.as_str().into())
     }
 }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 23efdaea0eb..9f76c1dd248 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -17,8 +17,8 @@ use crate::styled_buffer::StyledBuffer;
 use crate::translation::{to_fluent_args, Translate};
 use crate::{
     diagnostic::DiagnosticLocation, CodeSuggestion, DiagCtxt, Diagnostic, DiagnosticMessage,
-    FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
-    SuggestionStyle, TerminalUrl,
+    ErrCode, FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic,
+    SubstitutionHighlight, SuggestionStyle, TerminalUrl,
 };
 use rustc_lint_defs::pluralize;
 
@@ -1309,7 +1309,7 @@ impl HumanEmitter {
         msp: &MultiSpan,
         msgs: &[(DiagnosticMessage, Style)],
         args: &FluentArgs<'_>,
-        code: &Option<String>,
+        code: &Option<ErrCode>,
         level: &Level,
         max_line_num_len: usize,
         is_secondary: bool,
@@ -1340,9 +1340,9 @@ impl HumanEmitter {
                 buffer.append(0, "[", Style::Level(*level));
                 let code = if let TerminalUrl::Yes = self.terminal_url {
                     let path = "https://doc.rust-lang.org/error_codes";
-                    Cow::Owned(format!("\x1b]8;;{path}/{code}.html\x07{code}\x1b]8;;\x07"))
+                    format!("\x1b]8;;{path}/{code}.html\x07{code}\x1b]8;;\x07")
                 } else {
-                    Cow::Borrowed(code)
+                    code.to_string()
                 };
                 buffer.append(0, &code, Style::Level(*level));
                 buffer.append(0, "]", Style::Level(*level));
@@ -2076,7 +2076,7 @@ impl HumanEmitter {
         level: &Level,
         messages: &[(DiagnosticMessage, Style)],
         args: &FluentArgs<'_>,
-        code: &Option<String>,
+        code: &Option<ErrCode>,
         span: &MultiSpan,
         children: &[SubDiagnostic],
         suggestions: &[CodeSuggestion],
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 51b064f4c61..6f922998279 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -400,10 +400,10 @@ impl Diagnostic {
 
         let translated_message = je.translate_messages(&diag.messages, &args);
 
-        let code = if let Some(code) = &diag.code {
+        let code = if let Some(code) = diag.code {
             Some(DiagnosticCode {
                 code: code.to_string(),
-                explanation: je.registry.as_ref().unwrap().try_find_description(&code).ok(),
+                explanation: je.registry.as_ref().unwrap().try_find_description(code).ok(),
             })
         } else if let Some(IsLint { name, .. }) = &diag.is_lint {
             Some(DiagnosticCode { code: name.to_string(), explanation: None })
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 9d80c456517..960b68196ff 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -2,24 +2,26 @@
 //!
 //! This module contains the code for creating and emitting diagnostics.
 
+// tidy-alphabetical-start
+#![allow(incomplete_features)]
+#![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(rustdoc_internals)]
 #![feature(array_windows)]
 #![feature(associated_type_defaults)]
 #![feature(box_into_inner)]
+#![feature(box_patterns)]
+#![feature(error_reporter)]
 #![feature(extract_if)]
-#![feature(if_let_guard)]
 #![feature(let_chains)]
+#![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
-#![feature(yeet_expr)]
+#![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![feature(box_patterns)]
-#![feature(error_reporter)]
-#![allow(incomplete_features)]
-#![allow(internal_features)]
+#![feature(yeet_expr)]
+// tidy-alphabetical-end
 
 #[macro_use]
 extern crate rustc_macros;
@@ -29,9 +31,10 @@ extern crate tracing;
 
 extern crate self as rustc_errors;
 
+pub use codes::*;
 pub use diagnostic::{
-    AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue,
-    DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
+    AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgName,
+    DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
 };
 pub use diagnostic_builder::{
     BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
@@ -77,6 +80,7 @@ use std::path::{Path, PathBuf};
 use Level::*;
 
 pub mod annotate_snippet_emitter_writer;
+pub mod codes;
 mod diagnostic;
 mod diagnostic_builder;
 mod diagnostic_impls;
@@ -445,10 +449,10 @@ struct DiagCtxtInner {
     /// This set contains the code of all emitted diagnostics to avoid
     /// emitting the same diagnostic with extended help (`--teach`) twice, which
     /// would be unnecessary repetition.
-    taught_diagnostics: FxHashSet<String>,
+    taught_diagnostics: FxHashSet<ErrCode>,
 
     /// Used to suggest rustc --explain `<error code>`
-    emitted_diagnostic_codes: FxIndexSet<String>,
+    emitted_diagnostic_codes: FxIndexSet<ErrCode>,
 
     /// This set contains a hash of every diagnostic that has been emitted by
     /// this `DiagCtxt`. These hashes is used to avoid emitting the same error
@@ -510,6 +514,7 @@ pub enum StashKey {
     MaybeForgetReturn,
     /// Query cycle detected, stashing in favor of a better error.
     Cycle,
+    UndeterminedMacroResolution,
 }
 
 fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
@@ -624,7 +629,7 @@ impl DiagCtxt {
     pub fn eagerly_translate<'a>(
         &self,
         message: DiagnosticMessage,
-        args: impl Iterator<Item = DiagnosticArg<'a, 'static>>,
+        args: impl Iterator<Item = DiagnosticArg<'a>>,
     ) -> SubdiagnosticMessage {
         SubdiagnosticMessage::Eager(Cow::from(self.eagerly_translate_to_string(message, args)))
     }
@@ -633,7 +638,7 @@ impl DiagCtxt {
     pub fn eagerly_translate_to_string<'a>(
         &self,
         message: DiagnosticMessage,
-        args: impl Iterator<Item = DiagnosticArg<'a, 'static>>,
+        args: impl Iterator<Item = DiagnosticArg<'a>>,
     ) -> String {
         let inner = self.inner.borrow();
         let args = crate::translation::to_fluent_args(args);
@@ -1003,9 +1008,9 @@ impl DiagCtxt {
             let mut error_codes = inner
                 .emitted_diagnostic_codes
                 .iter()
-                .filter_map(|code| {
+                .filter_map(|&code| {
                     if registry.try_find_description(code).is_ok().clone() {
-                        Some(code.clone())
+                        Some(code.to_string())
                     } else {
                         None
                     }
@@ -1051,8 +1056,8 @@ impl DiagCtxt {
     ///
     /// Used to suppress emitting the same error multiple times with extended explanation when
     /// calling `-Zteach`.
-    pub fn must_teach(&self, code: &str) -> bool {
-        self.inner.borrow_mut().taught_diagnostics.insert(code.to_string())
+    pub fn must_teach(&self, code: ErrCode) -> bool {
+        self.inner.borrow_mut().taught_diagnostics.insert(code)
     }
 
     pub fn force_print_diagnostic(&self, db: Diagnostic) {
@@ -1312,8 +1317,8 @@ impl DiagCtxtInner {
 
         let mut guaranteed = None;
         (*TRACK_DIAGNOSTIC)(diagnostic, &mut |mut diagnostic| {
-            if let Some(ref code) = diagnostic.code {
-                self.emitted_diagnostic_codes.insert(code.clone());
+            if let Some(code) = diagnostic.code {
+                self.emitted_diagnostic_codes.insert(code);
             }
 
             let already_emitted = {
diff --git a/compiler/rustc_errors/src/registry.rs b/compiler/rustc_errors/src/registry.rs
index f26d8e7ebdc..8834d04d971 100644
--- a/compiler/rustc_errors/src/registry.rs
+++ b/compiler/rustc_errors/src/registry.rs
@@ -1,3 +1,4 @@
+use crate::ErrCode;
 use rustc_data_structures::fx::FxHashMap;
 
 #[derive(Debug)]
@@ -5,17 +6,17 @@ pub struct InvalidErrorCode;
 
 #[derive(Clone)]
 pub struct Registry {
-    long_descriptions: FxHashMap<&'static str, &'static str>,
+    long_descriptions: FxHashMap<ErrCode, &'static str>,
 }
 
 impl Registry {
-    pub fn new(long_descriptions: &[(&'static str, &'static str)]) -> Registry {
+    pub fn new(long_descriptions: &[(ErrCode, &'static str)]) -> Registry {
         Registry { long_descriptions: long_descriptions.iter().copied().collect() }
     }
 
     /// Returns `InvalidErrorCode` if the code requested does not exist in the
     /// registry.
-    pub fn try_find_description(&self, code: &str) -> Result<&'static str, InvalidErrorCode> {
-        self.long_descriptions.get(code).copied().ok_or(InvalidErrorCode)
+    pub fn try_find_description(&self, code: ErrCode) -> Result<&'static str, InvalidErrorCode> {
+        self.long_descriptions.get(&code).copied().ok_or(InvalidErrorCode)
     }
 }
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index ed35eb1b6c4..5bdac367d55 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -12,9 +12,9 @@ use std::error::Report;
 ///
 /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
 /// passed around as a reference thereafter.
-pub fn to_fluent_args<'iter, 'arg: 'iter>(
-    iter: impl Iterator<Item = DiagnosticArg<'iter, 'arg>>,
-) -> FluentArgs<'arg> {
+pub fn to_fluent_args<'iter>(
+    iter: impl Iterator<Item = DiagnosticArg<'iter>>,
+) -> FluentArgs<'static> {
     let mut args = if let Some(size) = iter.size_hint().1 {
         FluentArgs::with_capacity(size)
     } else {
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 29b70f33a6c..657e19277a7 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -796,9 +796,15 @@ impl SyntaxExtension {
     /// | external      | no  | if-ext        | if-ext   | yes |
     /// | yes           | yes | yes           | yes      | yes |
     fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], is_local: bool) -> bool {
-        let collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
+        let mut collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
             .map(|v| Self::collapse_debuginfo_by_name(sess, v))
             .unwrap_or(CollapseMacroDebuginfo::Unspecified);
+        if collapse_debuginfo_attr == CollapseMacroDebuginfo::Unspecified
+            && attr::contains_name(attrs, sym::rustc_builtin_macro)
+        {
+            collapse_debuginfo_attr = CollapseMacroDebuginfo::Yes;
+        }
+
         let flag = sess.opts.unstable_opts.collapse_macro_debuginfo;
         let attr = collapse_debuginfo_attr;
         let ext = !is_local;
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index f574e81e905..781186764fa 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -373,7 +373,9 @@ impl<'a> StripUnconfigured<'a> {
     /// If attributes are not allowed on expressions, emit an error for `attr`
     #[instrument(level = "trace", skip(self))]
     pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
-        if self.features.is_some_and(|features| !features.stmt_expr_attributes) {
+        if self.features.is_some_and(|features| !features.stmt_expr_attributes)
+            && !attr.span.allows_unstable(sym::stmt_expr_attributes)
+        {
             let mut err = feature_err(
                 &self.sess,
                 sym::stmt_expr_attributes,
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index 4a1c00f0104..2584ff62e98 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -1,4 +1,5 @@
 use rustc_ast::ast;
+use rustc_errors::codes::*;
 use rustc_macros::Diagnostic;
 use rustc_session::Limit;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
@@ -175,7 +176,7 @@ pub(crate) struct TakesNoArguments<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_feature_removed, code = "E0557")]
+#[diag(expand_feature_removed, code = E0557)]
 pub(crate) struct FeatureRemoved<'a> {
     #[primary_span]
     #[label]
@@ -191,7 +192,7 @@ pub(crate) struct FeatureRemovedReason<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_feature_not_allowed, code = "E0725")]
+#[diag(expand_feature_not_allowed, code = E0725)]
 pub(crate) struct FeatureNotAllowed {
     #[primary_span]
     pub span: Span,
@@ -210,7 +211,7 @@ pub(crate) struct RecursionLimitReached<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_malformed_feature_attribute, code = "E0556")]
+#[diag(expand_malformed_feature_attribute, code = E0556)]
 pub(crate) struct MalformedFeatureAttribute {
     #[primary_span]
     pub span: Span,
@@ -347,7 +348,7 @@ pub(crate) struct ModuleInBlockName {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_module_file_not_found, code = "E0583")]
+#[diag(expand_module_file_not_found, code = E0583)]
 #[help]
 #[note]
 pub(crate) struct ModuleFileNotFound {
@@ -359,7 +360,7 @@ pub(crate) struct ModuleFileNotFound {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_module_multiple_candidates, code = "E0761")]
+#[diag(expand_module_multiple_candidates, code = E0761)]
 #[help]
 pub(crate) struct ModuleMultipleCandidates {
     #[primary_span]
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index bed667048c8..2cf6a8df7c5 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -9,9 +9,7 @@
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
-#![feature(rustc_attrs)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![allow(internal_features)]
 
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 1a39708ed8e..83e0f870c8a 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -485,7 +485,9 @@ pub fn compile_declarative_macro(
                     )
                     .pop()
                     .unwrap();
-                    valid &= check_lhs_nt_follows(sess, def, &tt);
+                    // We don't handle errors here, the driver will abort
+                    // after parsing/expansion. we can report every error in every macro this way.
+                    valid &= check_lhs_nt_follows(sess, def, &tt).is_ok();
                     return tt;
                 }
                 sess.dcx().span_bug(def.span, "wrong-structured lhs")
@@ -589,18 +591,19 @@ pub fn compile_declarative_macro(
     (mk_syn_ext(expander), rule_spans)
 }
 
-fn check_lhs_nt_follows(sess: &Session, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
+fn check_lhs_nt_follows(
+    sess: &Session,
+    def: &ast::Item,
+    lhs: &mbe::TokenTree,
+) -> Result<(), ErrorGuaranteed> {
     // lhs is going to be like TokenTree::Delimited(...), where the
     // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
     if let mbe::TokenTree::Delimited(.., delimited) = lhs {
         check_matcher(sess, def, &delimited.tts)
     } else {
         let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
-        sess.dcx().span_err(lhs.span(), msg);
-        false
+        Err(sess.dcx().span_err(lhs.span(), msg))
     }
-    // we don't abort on errors on rejection, the driver will do that for us
-    // after parsing/expansion. we can report every error in every macro this way.
 }
 
 fn is_empty_token_tree(sess: &Session, seq: &mbe::SequenceRepetition) -> bool {
@@ -675,12 +678,15 @@ fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> bool {
     false
 }
 
-fn check_matcher(sess: &Session, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
+fn check_matcher(
+    sess: &Session,
+    def: &ast::Item,
+    matcher: &[mbe::TokenTree],
+) -> Result<(), ErrorGuaranteed> {
     let first_sets = FirstSets::new(matcher);
     let empty_suffix = TokenSet::empty();
-    let err = sess.dcx().err_count();
-    check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix);
-    err == sess.dcx().err_count()
+    check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix)?;
+    Ok(())
 }
 
 fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
@@ -1020,11 +1026,13 @@ fn check_matcher_core<'tt>(
     first_sets: &FirstSets<'tt>,
     matcher: &'tt [mbe::TokenTree],
     follow: &TokenSet<'tt>,
-) -> TokenSet<'tt> {
+) -> Result<TokenSet<'tt>, ErrorGuaranteed> {
     use mbe::TokenTree;
 
     let mut last = TokenSet::empty();
 
+    let mut errored = Ok(());
+
     // 2. For each token and suffix  [T, SUFFIX] in M:
     // ensure that T can be followed by SUFFIX, and if SUFFIX may be empty,
     // then ensure T can also be followed by any element of FOLLOW.
@@ -1068,7 +1076,7 @@ fn check_matcher_core<'tt>(
                     token::CloseDelim(d.delim),
                     span.close,
                 ));
-                check_matcher_core(sess, def, first_sets, &d.tts, &my_suffix);
+                check_matcher_core(sess, def, first_sets, &d.tts, &my_suffix)?;
                 // don't track non NT tokens
                 last.replace_with_irrelevant();
 
@@ -1100,7 +1108,7 @@ fn check_matcher_core<'tt>(
                 // At this point, `suffix_first` is built, and
                 // `my_suffix` is some TokenSet that we can use
                 // for checking the interior of `seq_rep`.
-                let next = check_matcher_core(sess, def, first_sets, &seq_rep.tts, my_suffix);
+                let next = check_matcher_core(sess, def, first_sets, &seq_rep.tts, my_suffix)?;
                 if next.maybe_empty {
                     last.add_all(&next);
                 } else {
@@ -1206,14 +1214,15 @@ fn check_matcher_core<'tt>(
                                     ));
                                 }
                             }
-                            err.emit();
+                            errored = Err(err.emit());
                         }
                     }
                 }
             }
         }
     }
-    last
+    errored?;
+    Ok(last)
 }
 
 fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 6eed2178ead..e66a66e23dc 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -516,6 +516,9 @@ declare_features! (
     (unstable, macro_metavar_expr, "1.61.0", Some(83527)),
     /// Allows `#[marker]` on certain traits allowing overlapping implementations.
     (unstable, marker_trait_attr, "1.30.0", Some(29864)),
+    /// Allows exhaustive pattern matching on types that contain uninhabited types in cases that are
+    /// unambiguously sound.
+    (incomplete, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(119612)),
     /// A minimal, sound subset of specialization intended to be used by the
     /// standard library until the soundness issues with specialization
     /// are fixed.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 23881cfd7df..681e228a0f2 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1273,7 +1273,6 @@ pub struct Arm<'hir> {
 /// desugaring to if-let. Only let-else supports the type annotation at present.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Let<'hir> {
-    pub hir_id: HirId,
     pub span: Span,
     pub pat: &'hir Pat<'hir>,
     pub ty: Option<&'hir Ty<'hir>>,
@@ -1532,14 +1531,16 @@ pub type Lit = Spanned<LitKind>;
 
 #[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum ArrayLen {
-    Infer(HirId, Span),
+    Infer(InferArg),
     Body(AnonConst),
 }
 
 impl ArrayLen {
     pub fn hir_id(&self) -> HirId {
         match self {
-            &ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, .. }) => hir_id,
+            ArrayLen::Infer(InferArg { hir_id, .. }) | ArrayLen::Body(AnonConst { hir_id, .. }) => {
+                *hir_id
+            }
         }
     }
 }
@@ -2424,7 +2425,7 @@ impl<'hir> Ty<'hir> {
             TyKind::Infer => true,
             TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
             TyKind::Array(ty, length) => {
-                ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(_, _))
+                ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(..))
             }
             TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
             TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 116de6fb04d..27c834d848f 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -341,9 +341,6 @@ pub trait Visitor<'v>: Sized {
     fn visit_expr(&mut self, ex: &'v Expr<'v>) {
         walk_expr(self, ex)
     }
-    fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
-        walk_let_expr(self, lex)
-    }
     fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
         walk_expr_field(self, field)
     }
@@ -672,7 +669,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
 
 pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
     match len {
-        &ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id),
+        ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
         ArrayLen::Body(c) => visitor.visit_anon_const(c),
     }
 }
@@ -729,7 +726,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         ExprKind::DropTemps(ref subexpression) => {
             visitor.visit_expr(subexpression);
         }
-        ExprKind::Let(ref let_expr) => visitor.visit_let_expr(let_expr),
+        ExprKind::Let(Let { span: _, pat, ty, init, is_recovered: _ }) => {
+            // match the visit order in walk_local
+            visitor.visit_expr(init);
+            visitor.visit_pat(pat);
+            walk_list!(visitor, visit_ty, ty);
+        }
         ExprKind::If(ref cond, ref then, ref else_opt) => {
             visitor.visit_expr(cond);
             visitor.visit_expr(then);
@@ -806,14 +808,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
     }
 }
 
-pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>) {
-    // match the visit order in walk_local
-    visitor.visit_expr(let_expr.init);
-    visitor.visit_id(let_expr.hir_id);
-    visitor.visit_pat(let_expr.pat);
-    walk_list!(visitor, visit_ty, let_expr.ty);
-}
-
 pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
     visitor.visit_id(field.hir_id);
     visitor.visit_ident(field.ident);
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 87de3c0870b..6c64d802e68 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -9,7 +9,6 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(variant_count)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 3aad510f366..c22daad334f 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index bfe88df4e1a..407517b15ef 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -6,8 +6,11 @@ use crate::errors::{
 use crate::fluent_generated as fluent;
 use crate::traits::error_reporting::report_object_safety_error;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
+use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordMap;
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed};
+use rustc_errors::{
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::traits::FulfillmentError;
@@ -461,22 +464,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             return err.emit();
         }
 
-        let mut bound_spans = Vec::new();
+        let mut bound_spans: SortedMap<Span, Vec<String>> = Default::default();
 
         let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
-            let msg = format!(
-                "doesn't satisfy `{}`",
-                if obligation.len() > 50 { quiet } else { obligation }
-            );
+            let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
             match &self_ty.kind() {
                 // Point at the type that couldn't satisfy the bound.
-                ty::Adt(def, _) => bound_spans.push((tcx.def_span(def.did()), msg)),
+                ty::Adt(def, _) => {
+                    bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
+                }
                 // Point at the trait object that couldn't satisfy the bound.
                 ty::Dynamic(preds, _, _) => {
                     for pred in preds.iter() {
                         match pred.skip_binder() {
                             ty::ExistentialPredicate::Trait(tr) => {
-                                bound_spans.push((tcx.def_span(tr.def_id), msg.clone()))
+                                bound_spans
+                                    .get_mut_or_insert_default(tcx.def_span(tr.def_id))
+                                    .push(msg.clone());
                             }
                             ty::ExistentialPredicate::Projection(_)
                             | ty::ExistentialPredicate::AutoTrait(_) => {}
@@ -485,7 +489,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 }
                 // Point at the closure that couldn't satisfy the bound.
                 ty::Closure(def_id, _) => {
-                    bound_spans.push((tcx.def_span(*def_id), format!("doesn't satisfy `{quiet}`")))
+                    bound_spans
+                        .get_mut_or_insert_default(tcx.def_span(*def_id))
+                        .push(format!("`{quiet}`"));
                 }
                 _ => {}
             }
@@ -554,12 +560,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             format!("associated type cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
         );
 
-        bound_spans.sort();
-        bound_spans.dedup();
-        for (span, msg) in bound_spans {
+        for (span, mut bounds) in bound_spans {
             if !tcx.sess.source_map().is_span_accessible(span) {
                 continue;
             }
+            bounds.sort();
+            bounds.dedup();
+            let msg = match &bounds[..] {
+                [bound] => format!("doesn't satisfy {bound}"),
+                bounds if bounds.len() > 4 => format!("doesn't satisfy {} bounds", bounds.len()),
+                [bounds @ .., last] => format!("doesn't satisfy {} or {last}", bounds.join(", ")),
+                [] => unreachable!(),
+            };
             err.span_label(span, msg);
         }
         add_def_label(&mut err);
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 4284758b117..30b10446afc 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -5,7 +5,9 @@ use crate::astconv::{
 };
 use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
 use rustc_ast::ast::ParamKindOrd;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index 33e782abc68..a6ac8ecd950 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -1,5 +1,5 @@
 use rustc_ast::TraitObjectSyntax;
-use rustc_errors::{Diagnostic, StashKey};
+use rustc_errors::{codes::*, Diagnostic, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
@@ -132,7 +132,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     ],
                     Applicability::MachineApplicable,
                 );
-            } else if diag.is_error() && is_downgradable {
+            } else if is_downgradable {
                 // We'll emit the object safety error already, with a structured suggestion.
                 diag.downgrade_to_delayed_bug();
             }
@@ -158,7 +158,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             if !is_object_safe {
                 diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`"));
-                if diag.is_error() && is_downgradable {
+                if is_downgradable {
                     // We'll emit the object safety error already, with a structured suggestion.
                     diag.downgrade_to_delayed_bug();
                 }
@@ -241,9 +241,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             } else {
                 let msg = "trait objects without an explicit `dyn` are deprecated";
                 tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
-                    if self_ty.span.can_be_used_for_suggestions()
-                        && !self.maybe_lint_impl_trait(self_ty, lint)
-                    {
+                    if self_ty.span.can_be_used_for_suggestions() {
                         lint.multipart_suggestion_verbose(
                             "use `dyn`",
                             sugg,
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 7c97c2a1a6f..89f39897ea8 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -18,8 +18,8 @@ use crate::require_c_abi_if_c_variadic;
 use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{
-    error_code, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
-    ErrorGuaranteed, FatalError, MultiSpan,
+    codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
+    FatalError, MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -1072,9 +1072,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 if let Some(binding) = binding
                     && let ConvertedBindingKind::Equality(_) = binding.kind
                 {
-                    error_code!(E0222)
+                    E0222
                 } else {
-                    error_code!(E0221)
+                    E0221
                 },
             );
 
@@ -1630,7 +1630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             let reported = tcx
                 .dcx()
                 .struct_span_err(span, msg)
-                .with_code(rustc_errors::error_code!(E0624))
+                .with_code(E0624)
                 .with_span_label(span, format!("private {kind}"))
                 .with_span_label(def_span, format!("{kind} defined here"))
                 .emit();
@@ -2529,7 +2529,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             hir::TyKind::Array(ty, length) => {
                 let length = match length {
-                    &hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
+                    hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span),
                     hir::ArrayLen::Body(constant) => {
                         ty::Const::from_anon_const(tcx, constant.def_id)
                     }
diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
index 5f35f75c77b..2d85ad5789e 100644
--- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
@@ -2,7 +2,7 @@ use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBou
 use crate::bounds::Bounds;
 use crate::errors::TraitObjectDeclaredWithNoTraits;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index c63bafcdcd4..2fe3499e8e6 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -5,7 +5,7 @@ use super::compare_impl_item::check_type_bounds;
 use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
 use super::*;
 use rustc_attr as attr;
-use rustc_errors::{ErrorGuaranteed, MultiSpan};
+use rustc_errors::{codes::*, ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LocalDefId};
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 57829d9d418..379c1154e5f 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2,7 +2,7 @@ use super::potentially_plural_count;
 use crate::errors::LifetimesOrBoundsMismatchOnTrait;
 use hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit;
@@ -20,6 +20,7 @@ use rustc_middle::ty::{
 };
 use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
 use rustc_span::Span;
+use rustc_trait_selection::regions::InferCtxtRegionExt;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
@@ -1382,7 +1383,7 @@ fn compare_number_of_generics<'tcx>(
                     kind = kind,
                 ),
             );
-            err.code("E0049".into());
+            err.code(E0049);
 
             let msg =
                 format!("expected {trait_count} {kind} parameter{}", pluralize!(trait_count),);
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index 6d2ebb150b9..3d3b21eabb3 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -8,6 +8,7 @@ use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 use rustc_span::Span;
+use rustc_trait_selection::regions::InferCtxtRegionExt;
 use rustc_trait_selection::traits::{
     elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt,
 };
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index 3275a81c3dd..7b60457affa 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -2,12 +2,13 @@
 //
 // We don't do any drop checking during hir typeck.
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
+use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_middle::ty::util::CheckRegions;
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_trait_selection::regions::InferCtxtRegionExt;
 use rustc_trait_selection::traits::{self, ObligationCtxt};
 
 use crate::errors;
@@ -188,6 +189,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                 RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => {
                     format!("{b}: {a}", a = ty::Region::new_var(tcx, a))
                 }
+                RegionResolutionError::CannotNormalize(..) => unreachable!(),
             };
             guar = Some(
                 struct_span_code_err!(
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 60e4403c1c7..2d0d6611444 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -8,7 +8,7 @@ use crate::errors::{
 };
 
 use hir::def_id::DefId;
-use rustc_errors::{struct_span_code_err, DiagnosticMessage};
+use rustc_errors::{codes::*, struct_span_code_err, DiagnosticMessage};
 use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 70213ee0614..b9c9eec2813 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -4,16 +4,14 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
+    codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
 };
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
-use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
-use rustc_infer::infer::outlives::obligations::TypeOutlives;
+use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
-use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -26,6 +24,7 @@ use rustc_session::parse::feature_err;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
+use rustc_trait_selection::regions::InferCtxtRegionExt;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::misc::{
     type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError,
@@ -731,10 +730,12 @@ fn ty_known_to_outlive<'tcx>(
     ty: Ty<'tcx>,
     region: ty::Region<'tcx>,
 ) -> bool {
-    resolve_regions_with_wf_tys(tcx, id, param_env, wf_tys, |infcx, region_bound_pairs| {
-        let origin = infer::RelateParamBound(DUMMY_SP, ty, None);
-        let outlives = &mut TypeOutlives::new(infcx, tcx, region_bound_pairs, None, param_env);
-        outlives.type_must_outlive(origin, ty, region, ConstraintCategory::BoringNoLocation);
+    test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
+        infcx.register_region_obligation(infer::RegionObligation {
+            sub_region: region,
+            sup_type: ty,
+            origin: infer::RelateParamBound(DUMMY_SP, ty, None),
+        });
     })
 }
 
@@ -748,40 +749,32 @@ fn region_known_to_outlive<'tcx>(
     region_a: ty::Region<'tcx>,
     region_b: ty::Region<'tcx>,
 ) -> bool {
-    resolve_regions_with_wf_tys(tcx, id, param_env, wf_tys, |mut infcx, _| {
-        use rustc_infer::infer::outlives::obligations::TypeOutlivesDelegate;
-        let origin = infer::RelateRegionParamBound(DUMMY_SP);
-        // `region_a: region_b` -> `region_b <= region_a`
-        infcx.push_sub_region_constraint(
-            origin,
-            region_b,
-            region_a,
-            ConstraintCategory::BoringNoLocation,
-        );
+    test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
+        infcx.sub_regions(infer::RelateRegionParamBound(DUMMY_SP), region_b, region_a);
     })
 }
 
 /// Given a known `param_env` and a set of well formed types, set up an
 /// `InferCtxt`, call the passed function (to e.g. set up region constraints
 /// to be tested), then resolve region and return errors
-fn resolve_regions_with_wf_tys<'tcx>(
+fn test_region_obligations<'tcx>(
     tcx: TyCtxt<'tcx>,
     id: LocalDefId,
     param_env: ty::ParamEnv<'tcx>,
     wf_tys: &FxIndexSet<Ty<'tcx>>,
-    add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'tcx>, &'a RegionBoundPairs<'tcx>),
+    add_constraints: impl FnOnce(&InferCtxt<'tcx>),
 ) -> bool {
     // Unfortunately, we have to use a new `InferCtxt` each call, because
     // region constraints get added and solved there and we need to test each
     // call individually.
     let infcx = tcx.infer_ctxt().build();
+
+    add_constraints(&infcx);
+
     let outlives_environment = OutlivesEnvironment::with_bounds(
         param_env,
         infcx.implied_bounds_tys(param_env, id, wf_tys),
     );
-    let region_bound_pairs = outlives_environment.region_bound_pairs();
-
-    add_constraints(&infcx, region_bound_pairs);
 
     let errors = infcx.resolve_regions(&outlives_environment);
     debug!(?errors, "errors");
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 63ea0272014..951440d6a2d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index dafa899ef24..8cf1f2c9407 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -6,7 +6,7 @@
 // mappings. That mapping code resides here.
 
 use crate::errors;
-use rustc_errors::{error_code, struct_span_code_err};
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
@@ -61,7 +61,7 @@ fn enforce_trait_manually_implementable(
         // Maintain explicit error code for `Unsize`, since it has a useful
         // explanation about using `CoerceUnsized` instead.
         if Some(trait_def_id) == tcx.lang_items().unsize_trait() {
-            err.code(error_code!(E0328));
+            err.code(E0328);
         }
 
         return Err(err.emit());
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index e4c407af53f..e3b5c724cde 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -1,7 +1,7 @@
 //! Unsafety checker: every impl either implements a trait defined in this
 //! crate or pertains to a type defined in this crate.
 
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::Unsafety;
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index d8ce2307995..8d862d5eb71 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -146,8 +146,8 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
         }
     }
     fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
-        if let &hir::ArrayLen::Infer(_, span) = length {
-            self.0.push(span);
+        if let hir::ArrayLen::Infer(inf) = length {
+            self.0.push(inf.span);
         }
         intravisit::walk_array_len(self, length)
     }
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a857e01f4fa..97d792e49ae 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -8,7 +8,7 @@
 
 use rustc_ast::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index f14390b77c6..e5871276d64 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -2,8 +2,8 @@
 
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    error_code, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
-    Level, MultiSpan,
+    codes::*, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
+    MultiSpan,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
@@ -52,7 +52,7 @@ pub struct AssocKindMismatchWrapInBracesSugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_assoc_item_not_found, code = "E0220")]
+#[diag(hir_analysis_assoc_item_not_found, code = E0220)]
 pub struct AssocItemNotFound<'a> {
     #[primary_span]
     pub span: Span,
@@ -122,7 +122,7 @@ pub enum AssocItemNotFoundSugg<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_unrecognized_atomic_operation, code = "E0092")]
+#[diag(hir_analysis_unrecognized_atomic_operation, code = E0092)]
 pub struct UnrecognizedAtomicOperation<'a> {
     #[primary_span]
     #[label]
@@ -131,7 +131,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_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]
@@ -142,7 +142,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_unrecognized_intrinsic_function, code = "E0093")]
+#[diag(hir_analysis_unrecognized_intrinsic_function, code = E0093)]
 pub struct UnrecognizedIntrinsicFunction {
     #[primary_span]
     #[label]
@@ -151,7 +151,7 @@ pub struct UnrecognizedIntrinsicFunction {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_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]
@@ -178,7 +178,7 @@ pub struct AsyncTraitImplShouldBeAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_drop_impl_on_wrong_item, code = "E0120")]
+#[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
 pub struct DropImplOnWrongItem {
     #[primary_span]
     #[label]
@@ -186,7 +186,7 @@ pub struct DropImplOnWrongItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_field_already_declared, code = "E0124")]
+#[diag(hir_analysis_field_already_declared, code = E0124)]
 pub struct FieldAlreadyDeclared {
     pub field_name: Ident,
     #[primary_span]
@@ -197,7 +197,7 @@ pub struct FieldAlreadyDeclared {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_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]
@@ -205,14 +205,14 @@ pub struct CopyImplOnTypeWithDtor {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_multiple_relaxed_default_bounds, code = "E0203")]
+#[diag(hir_analysis_multiple_relaxed_default_bounds, code = E0203)]
 pub struct MultipleRelaxedDefaultBounds {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_copy_impl_on_non_adt, code = "E0206")]
+#[diag(hir_analysis_copy_impl_on_non_adt, code = E0206)]
 pub struct CopyImplOnNonAdt {
     #[primary_span]
     #[label]
@@ -228,7 +228,7 @@ pub struct ConstParamTyImplOnNonAdt {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_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,
@@ -237,14 +237,14 @@ pub struct TraitObjectDeclaredWithNoTraits {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_ambiguous_lifetime_bound, code = "E0227")]
+#[diag(hir_analysis_ambiguous_lifetime_bound, code = E0227)]
 pub struct AmbiguousLifetimeBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_assoc_type_binding_not_allowed, code = "E0229")]
+#[diag(hir_analysis_assoc_type_binding_not_allowed, code = E0229)]
 pub struct AssocTypeBindingNotAllowed {
     #[primary_span]
     #[label]
@@ -264,7 +264,7 @@ pub struct ParenthesizedFnTraitExpansion {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_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]
@@ -275,7 +275,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_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]
@@ -320,7 +320,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for MissingTypeParams {
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
         let mut err = DiagnosticBuilder::new(dcx, level, fluent::hir_analysis_missing_type_params);
         err.span(self.span);
-        err.code(error_code!(E0393));
+        err.code(E0393);
         err.arg("parameterCount", self.missing_type_params.len());
         err.arg(
             "parameters",
@@ -373,7 +373,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for MissingTypeParams {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_manual_implementation, code = "E0183")]
+#[diag(hir_analysis_manual_implementation, code = E0183)]
 #[help]
 pub struct ManualImplementation {
     #[primary_span]
@@ -421,7 +421,7 @@ pub struct SelfInImplSelf {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_linkage_type, code = "E0791")]
+#[diag(hir_analysis_linkage_type, code = E0791)]
 pub(crate) struct LinkageType {
     #[primary_span]
     pub span: Span,
@@ -429,7 +429,7 @@ pub(crate) struct LinkageType {
 
 #[derive(Diagnostic)]
 #[help]
-#[diag(hir_analysis_auto_deref_reached_recursion_limit, code = "E0055")]
+#[diag(hir_analysis_auto_deref_reached_recursion_limit, code = E0055)]
 pub struct AutoDerefReachedRecursionLimit<'a> {
     #[primary_span]
     #[label]
@@ -440,7 +440,7 @@ pub struct AutoDerefReachedRecursionLimit<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_where_clause_on_main, code = "E0646")]
+#[diag(hir_analysis_where_clause_on_main, code = E0646)]
 pub(crate) struct WhereClauseOnMain {
     #[primary_span]
     pub span: Span,
@@ -485,7 +485,7 @@ pub(crate) struct StartTargetFeature {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_start_not_async, code = "E0752")]
+#[diag(hir_analysis_start_not_async, code = E0752)]
 pub(crate) struct StartAsync {
     #[primary_span]
     #[label]
@@ -493,7 +493,7 @@ pub(crate) struct StartAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_start_function_where, code = "E0647")]
+#[diag(hir_analysis_start_function_where, code = E0647)]
 pub(crate) struct StartFunctionWhere {
     #[primary_span]
     #[label]
@@ -501,7 +501,7 @@ pub(crate) struct StartFunctionWhere {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_start_function_parameters, code = "E0132")]
+#[diag(hir_analysis_start_function_parameters, code = E0132)]
 pub(crate) struct StartFunctionParameters {
     #[primary_span]
     #[label]
@@ -509,14 +509,14 @@ pub(crate) struct StartFunctionParameters {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_main_function_return_type_generic, code = "E0131")]
+#[diag(hir_analysis_main_function_return_type_generic, code = E0131)]
 pub(crate) struct MainFunctionReturnTypeGeneric {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_main_function_async, code = "E0752")]
+#[diag(hir_analysis_main_function_async, code = E0752)]
 pub(crate) struct MainFunctionAsync {
     #[primary_span]
     pub span: Span,
@@ -525,7 +525,7 @@ pub(crate) struct MainFunctionAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_main_function_generic_parameters, code = "E0131")]
+#[diag(hir_analysis_main_function_generic_parameters, code = E0131)]
 pub(crate) struct MainFunctionGenericParameters {
     #[primary_span]
     pub span: Span,
@@ -534,7 +534,7 @@ pub(crate) struct MainFunctionGenericParameters {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_variadic_function_compatible_convention, code = "E0045")]
+#[diag(hir_analysis_variadic_function_compatible_convention, code = E0045)]
 pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
     #[primary_span]
     #[label]
@@ -587,7 +587,7 @@ pub(crate) struct TypeOf<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_pass_to_variadic_function, code = "E0617")]
+#[diag(hir_analysis_pass_to_variadic_function, code = E0617)]
 pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
     #[primary_span]
     pub span: Span,
@@ -601,7 +601,7 @@ pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cast_thin_pointer_to_fat_pointer, code = "E0607")]
+#[diag(hir_analysis_cast_thin_pointer_to_fat_pointer, code = E0607)]
 pub(crate) struct CastThinPointerToFatPointer<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -610,7 +610,7 @@ pub(crate) struct CastThinPointerToFatPointer<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_invalid_union_field, code = "E0740")]
+#[diag(hir_analysis_invalid_union_field, code = E0740)]
 pub(crate) struct InvalidUnionField {
     #[primary_span]
     pub field_span: Span,
@@ -649,7 +649,7 @@ pub(crate) struct ReturnTypeNotationEqualityBound {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = "E0121")]
+#[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = E0121)]
 pub(crate) struct PlaceholderNotAllowedItemSignatures {
     #[primary_span]
     #[label]
@@ -658,7 +658,7 @@ pub(crate) struct PlaceholderNotAllowedItemSignatures {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_associated_type_trait_uninferred_generic_params, code = "E0212")]
+#[diag(hir_analysis_associated_type_trait_uninferred_generic_params, code = E0212)]
 pub(crate) struct AssociatedTypeTraitUninferredGenericParams {
     #[primary_span]
     pub span: Span,
@@ -684,7 +684,7 @@ pub(crate) struct AssociatedTypeTraitUninferredGenericParamsMultipartSuggestion
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_enum_discriminant_overflowed, code = "E0370")]
+#[diag(hir_analysis_enum_discriminant_overflowed, code = E0370)]
 #[note]
 pub(crate) struct EnumDiscriminantOverflowed {
     #[primary_span]
@@ -774,7 +774,7 @@ pub(crate) struct SIMDFFIHighlyExperimental {
 
 #[derive(Diagnostic)]
 pub enum ImplNotMarkedDefault {
-    #[diag(hir_analysis_impl_not_marked_default, code = "E0520")]
+    #[diag(hir_analysis_impl_not_marked_default, code = E0520)]
     #[note]
     Ok {
         #[primary_span]
@@ -784,7 +784,7 @@ pub enum ImplNotMarkedDefault {
         ok_label: Span,
         ident: Symbol,
     },
-    #[diag(hir_analysis_impl_not_marked_default_err, code = "E0520")]
+    #[diag(hir_analysis_impl_not_marked_default_err, code = E0520)]
     #[note]
     Err {
         #[primary_span]
@@ -795,7 +795,7 @@ pub enum ImplNotMarkedDefault {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_missing_trait_item, code = "E0046")]
+#[diag(hir_analysis_missing_trait_item, code = E0046)]
 pub(crate) struct MissingTraitItem {
     #[primary_span]
     #[label]
@@ -846,7 +846,7 @@ pub(crate) struct MissingTraitItemSuggestionNone {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_missing_one_of_trait_item, code = "E0046")]
+#[diag(hir_analysis_missing_one_of_trait_item, code = E0046)]
 pub(crate) struct MissingOneOfTraitItem {
     #[primary_span]
     #[label]
@@ -857,7 +857,7 @@ pub(crate) struct MissingOneOfTraitItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_missing_trait_item_unstable, code = "E0046")]
+#[diag(hir_analysis_missing_trait_item_unstable, code = E0046)]
 #[note]
 pub(crate) struct MissingTraitItemUnstable {
     #[primary_span]
@@ -872,7 +872,7 @@ pub(crate) struct MissingTraitItemUnstable {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_transparent_enum_variant, code = "E0731")]
+#[diag(hir_analysis_transparent_enum_variant, code = E0731)]
 pub(crate) struct TransparentEnumVariant {
     #[primary_span]
     #[label]
@@ -886,7 +886,7 @@ pub(crate) struct TransparentEnumVariant {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_transparent_non_zero_sized_enum, code = "E0690")]
+#[diag(hir_analysis_transparent_non_zero_sized_enum, code = E0690)]
 pub(crate) struct TransparentNonZeroSizedEnum<'a> {
     #[primary_span]
     #[label]
@@ -898,7 +898,7 @@ pub(crate) struct TransparentNonZeroSizedEnum<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_transparent_non_zero_sized, code = "E0690")]
+#[diag(hir_analysis_transparent_non_zero_sized, code = E0690)]
 pub(crate) struct TransparentNonZeroSized<'a> {
     #[primary_span]
     #[label]
@@ -1045,7 +1045,7 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside, code = "E0390")]
+#[diag(hir_analysis_inherent_ty_outside, code = E0390)]
 #[help]
 pub struct InherentTyOutside {
     #[primary_span]
@@ -1054,7 +1054,7 @@ pub struct InherentTyOutside {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
 pub struct DispatchFromDynCoercion<'a> {
     #[primary_span]
     pub span: Span,
@@ -1066,14 +1066,14 @@ pub struct DispatchFromDynCoercion<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_repr, code = "E0378")]
+#[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
 pub struct DispatchFromDynRepr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside_relevant, code = "E0390")]
+#[diag(hir_analysis_inherent_ty_outside_relevant, code = E0390)]
 #[help]
 pub struct InherentTyOutsideRelevant {
     #[primary_span]
@@ -1083,7 +1083,7 @@ pub struct InherentTyOutsideRelevant {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside_new, code = "E0116")]
+#[diag(hir_analysis_inherent_ty_outside_new, code = E0116)]
 #[note]
 pub struct InherentTyOutsideNew {
     #[primary_span]
@@ -1092,7 +1092,7 @@ pub struct InherentTyOutsideNew {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside_primitive, code = "E0390")]
+#[diag(hir_analysis_inherent_ty_outside_primitive, code = E0390)]
 #[help]
 pub struct InherentTyOutsidePrimitive {
     #[primary_span]
@@ -1102,7 +1102,7 @@ pub struct InherentTyOutsidePrimitive {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_primitive_ty, code = "E0390")]
+#[diag(hir_analysis_inherent_primitive_ty, code = E0390)]
 #[help]
 pub struct InherentPrimitiveTy<'a> {
     #[primary_span]
@@ -1118,7 +1118,7 @@ pub struct InherentPrimitiveTyNote<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_dyn, code = "E0785")]
+#[diag(hir_analysis_inherent_dyn, code = E0785)]
 #[note]
 pub struct InherentDyn {
     #[primary_span]
@@ -1127,7 +1127,7 @@ pub struct InherentDyn {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_nominal, code = "E0118")]
+#[diag(hir_analysis_inherent_nominal, code = E0118)]
 #[note]
 pub struct InherentNominal {
     #[primary_span]
@@ -1136,7 +1136,7 @@ pub struct InherentNominal {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_zst, code = "E0378")]
+#[diag(hir_analysis_dispatch_from_dyn_zst, code = E0378)]
 #[note]
 pub struct DispatchFromDynZST<'a> {
     #[primary_span]
@@ -1146,7 +1146,7 @@ pub struct DispatchFromDynZST<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
 pub struct DispatchFromDynSingle<'a> {
     #[primary_span]
     pub span: Span,
@@ -1156,7 +1156,7 @@ pub struct DispatchFromDynSingle<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_multi, code = "E0378")]
+#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
 #[note]
 pub struct DispatchFromDynMulti {
     #[primary_span]
@@ -1168,7 +1168,7 @@ pub struct DispatchFromDynMulti {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0376")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0376)]
 pub struct DispatchFromDynStruct<'a> {
     #[primary_span]
     pub span: Span,
@@ -1176,7 +1176,7 @@ pub struct DispatchFromDynStruct<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0377")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
 pub struct DispatchFromDynSame<'a> {
     #[primary_span]
     pub span: Span,
@@ -1188,7 +1188,7 @@ pub struct DispatchFromDynSame<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0374")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0374)]
 pub struct CoerceUnsizedOneField<'a> {
     #[primary_span]
     pub span: Span,
@@ -1198,7 +1198,7 @@ pub struct CoerceUnsizedOneField<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_multi, code = "E0375")]
+#[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
 #[note]
 pub struct CoerceUnsizedMulti {
     #[primary_span]
@@ -1211,7 +1211,7 @@ pub struct CoerceUnsizedMulti {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
 pub struct CoerceUnsizedMay<'a> {
     #[primary_span]
     pub span: Span,
@@ -1219,7 +1219,7 @@ pub struct CoerceUnsizedMay<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_trait_cannot_impl_for_ty, code = "E0204")]
+#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
 pub struct TraitCannotImplForTy {
     #[primary_span]
     pub span: Span,
@@ -1241,7 +1241,7 @@ pub struct ImplForTyRequires {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_traits_with_defualt_impl, code = "E0321")]
+#[diag(hir_analysis_traits_with_defualt_impl, code = E0321)]
 #[note]
 pub struct TraitsWithDefaultImpl<'a> {
     #[primary_span]
@@ -1252,7 +1252,7 @@ pub struct TraitsWithDefaultImpl<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cross_crate_traits, code = "E0321")]
+#[diag(hir_analysis_cross_crate_traits, code = E0321)]
 pub struct CrossCrateTraits<'a> {
     #[primary_span]
     #[label]
@@ -1262,7 +1262,7 @@ pub struct CrossCrateTraits<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cross_crate_traits_defined, code = "E0321")]
+#[diag(hir_analysis_cross_crate_traits_defined, code = E0321)]
 pub struct CrossCrateTraitsDefined {
     #[primary_span]
     #[label]
@@ -1271,7 +1271,7 @@ pub struct CrossCrateTraitsDefined {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_ty_param_first_local, code = "E0210")]
+#[diag(hir_analysis_ty_param_first_local, code = E0210)]
 #[note]
 pub struct TyParamFirstLocal<'a> {
     #[primary_span]
@@ -1284,7 +1284,7 @@ pub struct TyParamFirstLocal<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_ty_param_some, code = "E0210")]
+#[diag(hir_analysis_ty_param_some, code = E0210)]
 #[note]
 pub struct TyParamSome<'a> {
     #[primary_span]
@@ -1297,7 +1297,7 @@ pub struct TyParamSome<'a> {
 
 #[derive(Diagnostic)]
 pub enum OnlyCurrentTraits<'a> {
-    #[diag(hir_analysis_only_current_traits_outside, code = "E0117")]
+    #[diag(hir_analysis_only_current_traits_outside, code = E0117)]
     Outside {
         #[primary_span]
         #[label(hir_analysis_only_current_traits_label)]
@@ -1317,7 +1317,7 @@ pub enum OnlyCurrentTraits<'a> {
         #[subdiagnostic]
         sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
-    #[diag(hir_analysis_only_current_traits_primitive, code = "E0117")]
+    #[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
     Primitive {
         #[primary_span]
         #[label(hir_analysis_only_current_traits_label)]
@@ -1337,7 +1337,7 @@ pub enum OnlyCurrentTraits<'a> {
         #[subdiagnostic]
         sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
-    #[diag(hir_analysis_only_current_traits_arbitrary, code = "E0117")]
+    #[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
     Arbitrary {
         #[primary_span]
         #[label(hir_analysis_only_current_traits_label)]
@@ -1412,7 +1412,7 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_static_mut_ref, code = "E0796")]
+#[diag(hir_analysis_static_mut_ref, code = E0796)]
 #[note]
 pub struct StaticMutRef {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 2fe08ead72b..c072891e295 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -12,7 +12,7 @@ use crate::constrained_generic_params as cgp;
 use min_specialization::check_min_specialization;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index ad5b6664677..454cb97ac14 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -60,7 +60,6 @@ This API is completely unstable and subject to change.
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
-#![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(if_let_guard)]
 #![feature(is_sorted)]
@@ -71,8 +70,6 @@ This API is completely unstable and subject to change.
 #![feature(lazy_cell)]
 #![feature(slice_partition_dedup)]
 #![feature(try_blocks)]
-#![feature(type_alias_impl_trait)]
-#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs
index b061d637138..6846e4defe5 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors.rs
@@ -6,18 +6,18 @@ pub use self::{
     missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*,
 };
 
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder, ErrCode};
 use rustc_session::Session;
 
 pub trait StructuredDiagnostic<'tcx> {
     fn session(&self) -> &Session;
 
-    fn code(&self) -> String;
+    fn code(&self) -> ErrCode;
 
     fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
         let err = self.diagnostic_common();
 
-        if self.session().teach(&self.code()) {
+        if self.session().teach(self.code()) {
             self.diagnostic_extended(err)
         } else {
             self.diagnostic_regular(err)
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
index 6f4435db411..50b4ef623ac 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
@@ -1,5 +1,5 @@
 use crate::{errors, structured_errors::StructuredDiagnostic};
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode};
 use rustc_middle::ty::{Ty, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::Span;
@@ -16,8 +16,8 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
         self.sess
     }
 
-    fn code(&self) -> String {
-        rustc_errors::error_code!(E0617)
+    fn code(&self) -> ErrCode {
+        E0617
     }
 
     fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
index 19cac4a38aa..54d54a2af93 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
@@ -1,5 +1,5 @@
 use crate::{errors, structured_errors::StructuredDiagnostic};
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode};
 use rustc_middle::ty::{Ty, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::Span;
@@ -16,8 +16,8 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> {
         self.sess
     }
 
-    fn code(&self) -> String {
-        rustc_errors::error_code!(E0607)
+    fn code(&self) -> ErrCode {
+        E0607
     }
 
     fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index ba81e7f1f81..501915d2e7e 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -1,5 +1,7 @@
 use crate::structured_errors::StructuredDiagnostic;
-use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    codes::*, pluralize, Applicability, Diagnostic, DiagnosticBuilder, ErrCode, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
 use rustc_session::Session;
@@ -1105,8 +1107,8 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
         self.tcx.sess
     }
 
-    fn code(&self) -> String {
-        rustc_errors::error_code!(E0107)
+    fn code(&self) -> ErrCode {
+        E0107
     }
 
     fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index e76303bc6df..9d0c5cb0f32 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -956,7 +956,7 @@ impl<'a> State<'a> {
 
     fn print_array_length(&mut self, len: &hir::ArrayLen) {
         match len {
-            hir::ArrayLen::Infer(_, _) => self.word("_"),
+            hir::ArrayLen::Infer(..) => self.word("_"),
             hir::ArrayLen::Body(ct) => self.print_anon_const(ct),
         }
     }
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 4fd9391acc3..220da19a29d 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -96,9 +96,6 @@ hir_typeck_lossy_provenance_ptr2int =
 hir_typeck_method_call_on_unknown_raw_pointee =
     cannot call a method on a raw pointer with an unknown pointee type
 
-hir_typeck_missing_fn_lang_items = failed to find an overloaded call trait for closure call
-    .help = make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
 hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
 
 hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method ->
@@ -108,8 +105,6 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {
 
 hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
 
-hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters
-
 hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expected_ty}` to `{$expr_ty}`
 hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
 hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 9dc365526d4..b263c985534 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -77,6 +77,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     callee_expr,
                     Expectation::NoExpectation,
                     arg_exprs,
+                    Some(call_expr),
                 ),
             _ => self.check_expr(callee_expr),
         };
@@ -253,28 +254,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 adjusted_ty,
                 opt_input_type.as_ref().map(slice::from_ref),
             ) {
-                // Check for `self` receiver on the method, otherwise we can't use this as a `Fn*` trait.
-                if !self.tcx.associated_item(ok.value.def_id).fn_has_self_parameter {
-                    self.dcx().span_delayed_bug(
-                        call_expr.span,
-                        "input to overloaded call fn is not a self receiver",
-                    );
-                    return None;
-                }
-
                 let method = self.register_infer_ok_obligations(ok);
                 let mut autoref = None;
                 if borrow {
                     // Check for &self vs &mut self in the method signature. Since this is either
                     // the Fn or FnMut trait, it should be one of those.
                     let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else {
-                        // The `fn`/`fn_mut` lang item is ill-formed, which should have
-                        // caused an error elsewhere.
-                        self.dcx().span_delayed_bug(
-                            call_expr.span,
-                            "input to call/call_mut is not a ref",
-                        );
-                        return None;
+                        bug!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut")
                     };
 
                     // For initial two-phase borrow
@@ -948,9 +934,11 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> {
                 );
             }
             None => {
-                // This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
-                // lang items are not defined (issue #86238).
-                fcx.dcx().emit_err(errors::MissingFnLangItems { span: self.call_expr.span });
+                span_bug!(
+                    self.call_expr.span,
+                    "Expected to find a suitable `Fn`/`FnMut`/`FnOnce` implementation for `{}`",
+                    self.adjusted_ty
+                )
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index bd8a2024caa..a0ac839f3dd 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -33,7 +33,7 @@ use super::FnCtxt;
 use crate::errors;
 use crate::type_error_struct;
 use hir::ExprKind;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{codes::*, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::mir::Mutability;
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 4d9f5b831c1..aab78465f8c 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -72,7 +72,7 @@ pub(super) fn check_fn<'a, 'tcx>(
     let inputs_fn = fn_sig.inputs().iter().copied();
     for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
         // Check the pattern.
-        let ty: Option<&hir::Ty<'_>> = try { inputs_hir?.get(idx)? };
+        let ty: Option<&hir::Ty<'_>> = inputs_hir.and_then(|h| h.get(idx));
         let ty_span = ty.map(|ty| ty.span);
         fcx.check_pat_top(param.pat, param_ty, ty_span, None, None);
         if param.pat.is_never_pattern() {
@@ -152,26 +152,22 @@ pub(super) fn check_fn<'a, 'tcx>(
 }
 
 fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) {
+    let span = tcx.def_span(fn_id);
+
     let DefKind::Fn = tcx.def_kind(fn_id) else {
-        let span = tcx.def_span(fn_id);
         tcx.dcx().span_err(span, "should be a function");
         return;
     };
 
     let generic_counts = tcx.generics_of(fn_id).own_counts();
     if generic_counts.types != 0 {
-        let span = tcx.def_span(fn_id);
         tcx.dcx().span_err(span, "should have no type parameters");
     }
     if generic_counts.consts != 0 {
-        let span = tcx.def_span(fn_id);
         tcx.dcx().span_err(span, "should have no const parameters");
     }
 
-    let Some(panic_info_did) = tcx.lang_items().panic_info() else {
-        tcx.dcx().err("language item required, but not found: `panic_info`");
-        return;
-    };
+    let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
 
     // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
     let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
@@ -203,11 +199,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
 
     let _ = check_function_signature(
         tcx,
-        ObligationCause::new(
-            tcx.def_span(fn_id),
-            fn_id,
-            ObligationCauseCode::LangFunctionType(sym::panic_impl),
-        ),
+        ObligationCause::new(span, fn_id, ObligationCauseCode::LangFunctionType(sym::panic_impl)),
         fn_id.into(),
         expected_sig,
     );
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 858faf161f6..ca636ebcade 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -36,7 +36,9 @@
 //! ```
 
 use crate::FnCtxt;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 4f929068887..70afb042441 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -3,8 +3,8 @@ use std::borrow::Cow;
 
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg, MultiSpan,
-    SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg,
+    MultiSpan, SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
@@ -15,7 +15,7 @@ use rustc_span::{
 };
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_field_multiply_specified_in_initializer, code = "E0062")]
+#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
 pub struct FieldMultiplySpecifiedInInitializer {
     #[primary_span]
     #[label]
@@ -26,7 +26,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = "E0572")]
+#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)]
 pub struct ReturnStmtOutsideOfFnBody {
     #[primary_span]
     pub span: Span,
@@ -43,7 +43,7 @@ pub enum ReturnLikeStatementKind {
 }
 
 impl IntoDiagnosticArg for ReturnLikeStatementKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         let kind = match self {
             Self::Return => "return",
             Self::Become => "become",
@@ -62,14 +62,14 @@ pub struct RustCallIncorrectArgs {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = "E0627")]
+#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)]
 pub struct YieldExprOutsideOfCoroutine {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_struct_expr_non_exhaustive, code = "E0639")]
+#[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)]
 pub struct StructExprNonExhaustive {
     #[primary_span]
     pub span: Span,
@@ -77,29 +77,21 @@ pub struct StructExprNonExhaustive {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_method_call_on_unknown_raw_pointee, code = "E0699")]
+#[diag(hir_typeck_method_call_on_unknown_raw_pointee, code = E0699)]
 pub struct MethodCallOnUnknownRawPointee {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_missing_fn_lang_items)]
-#[help]
-pub struct MissingFnLangItems {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(hir_typeck_functional_record_update_on_non_struct, code = "E0436")]
+#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
 pub struct FunctionalRecordUpdateOnNonStruct {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_address_of_temporary_taken, code = "E0745")]
+#[diag(hir_typeck_address_of_temporary_taken, code = E0745)]
 pub struct AddressOfTemporaryTaken {
     #[primary_span]
     #[label]
@@ -145,7 +137,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_explicit_destructor, code = "E0040")]
+#[diag(hir_typeck_explicit_destructor, code = E0040)]
 pub struct ExplicitDestructorCall {
     #[primary_span]
     #[label]
@@ -168,7 +160,7 @@ pub enum ExplicitDestructorCallSugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_missing_parentheses_in_range, code = "E0689")]
+#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
 pub struct MissingParenthesesInRange {
     #[primary_span]
     #[label(hir_typeck_missing_parentheses_in_range)]
@@ -193,14 +185,6 @@ pub struct AddMissingParenthesesInRange {
     pub right: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(hir_typeck_op_trait_generic_params)]
-pub struct OpMethodGenericParams {
-    #[primary_span]
-    pub span: Span,
-    pub method_name: String,
-}
-
 pub struct TypeMismatchFruTypo {
     /// Span of the LHS of the range
     pub expr_span: Span,
@@ -321,7 +305,7 @@ impl HelpUseLatestEdition {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_invalid_callee, code = "E0618")]
+#[diag(hir_typeck_invalid_callee, code = E0618)]
 pub struct InvalidCallee {
     #[primary_span]
     pub span: Span,
@@ -329,7 +313,7 @@ pub struct InvalidCallee {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_int_to_fat, code = "E0606")]
+#[diag(hir_typeck_int_to_fat, code = E0606)]
 pub struct IntToWide<'tcx> {
     #[primary_span]
     #[label(hir_typeck_int_to_fat_label)]
@@ -510,7 +494,7 @@ pub struct TrivialCast<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_no_associated_item, code = "E0599")]
+#[diag(hir_typeck_no_associated_item, code = E0599)]
 pub struct NoAssociatedItem {
     #[primary_span]
     pub span: Span,
@@ -532,7 +516,7 @@ pub struct CandidateTraitNote {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_cannot_cast_to_bool, code = "E0054")]
+#[diag(hir_typeck_cannot_cast_to_bool, code = E0054)]
 pub struct CannotCastToBool<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -549,7 +533,7 @@ pub struct CastEnumDrop<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_cast_unknown_pointer, code = "E0641")]
+#[diag(hir_typeck_cast_unknown_pointer, code = E0641)]
 pub struct CastUnknownPointer {
     #[primary_span]
     pub span: Span,
@@ -600,7 +584,7 @@ pub enum CannotCastToBoolHelp {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_ctor_is_private, code = "E0603")]
+#[diag(hir_typeck_ctor_is_private, code = E0603)]
 pub struct CtorIsPrivate {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3bc259c17b7..2bbef11fa24 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -25,8 +25,8 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
-    ErrorGuaranteed, StashKey,
+    codes::*, pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic,
+    DiagnosticBuilder, ErrCode, ErrorGuaranteed, StashKey,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
-        self.check_expr_with_expectation_and_args(expr, expected, &[])
+        self.check_expr_with_expectation_and_args(expr, expected, &[], None)
     }
 
     /// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
@@ -187,6 +187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
         args: &'tcx [hir::Expr<'tcx>],
+        call: Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         if self.tcx().sess.verbose_internals() {
             // make this code only run with -Zverbose-internals because it is probably slow
@@ -233,7 +234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ty = ensure_sufficient_stack(|| match &expr.kind {
             hir::ExprKind::Path(
                 qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
-            ) => self.check_expr_path(qpath, expr, args),
+            ) => self.check_expr_path(qpath, expr, args, call),
             _ => self.check_expr_kind(expr, expected),
         });
         let ty = self.resolve_vars_if_possible(ty);
@@ -300,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ExprKind::Path(QPath::LangItem(lang_item, _)) => {
                 self.check_lang_item_path(lang_item, expr)
             }
-            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]),
+            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[], None),
             ExprKind::InlineAsm(asm) => {
                 // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
                 self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
@@ -320,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
             ExprKind::Become(call) => self.check_expr_become(call, expr),
-            ExprKind::Let(let_expr) => self.check_expr_let(let_expr),
+            ExprKind::Let(let_expr) => self.check_expr_let(let_expr, expr.hir_id),
             ExprKind::Loop(body, _, source, _) => {
                 self.check_expr_loop(body, source, expected, expr)
             }
@@ -514,6 +515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         qpath: &'tcx hir::QPath<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
         args: &'tcx [hir::Expr<'tcx>],
+        call: Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let (res, opt_ty, segs) =
@@ -527,10 +529,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Ty::new_error(tcx, e)
             }
             Res::Def(DefKind::Variant, _) => {
-                let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value");
+                let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, E0533, "value");
                 Ty::new_error(tcx, e)
             }
-            _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
+            _ => {
+                self.instantiate_value_path(
+                    segs,
+                    opt_ty,
+                    res,
+                    call.map_or(expr.span, |e| e.span),
+                    expr.span,
+                    expr.hir_id,
+                )
+                .0
+            }
         };
 
         if let ty::FnDef(did, _) = *ty.kind() {
@@ -585,7 +597,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 infer::BoundRegionConversionTime::FnCall,
                 fn_sig.output(),
             );
-            self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
+            self.require_type_is_sized_deferred(
+                output,
+                call.map_or(expr.span, |e| e.span),
+                traits::SizedCallReturnType,
+            );
         }
 
         // We always require that the type provided as the value for
@@ -939,7 +955,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn check_lhs_assignable(
         &self,
         lhs: &'tcx hir::Expr<'tcx>,
-        err_code: &'static str,
+        code: ErrCode,
         op_span: Span,
         adjust_err: impl FnOnce(&mut Diagnostic),
     ) {
@@ -948,7 +964,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let mut err = self.dcx().struct_span_err(op_span, "invalid left-hand side of assignment");
-        err.code(err_code.into());
+        err.code(code);
         err.span_label(lhs.span, "cannot assign to this expression");
 
         self.comes_from_while_condition(lhs.hir_id, |expr| {
@@ -1244,7 +1260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             diag.emit();
         }
 
-        self.check_lhs_assignable(lhs, "E0070", span, |err| {
+        self.check_lhs_assignable(lhs, E0070, span, |err| {
             if let Some(rhs_ty) = self.typeck_results.borrow().expr_ty_opt(rhs) {
                 suggest_deref_binop(err, rhs_ty);
             }
@@ -1259,12 +1275,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>) -> Ty<'tcx> {
+    pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>, hir_id: HirId) -> Ty<'tcx> {
         // for let statements, this is done in check_stmt
         let init = let_expr.init;
         self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression");
         // otherwise check exactly as a let statement
-        self.check_decl(let_expr.into());
+        self.check_decl((let_expr, hir_id).into());
         // but return a bool, for this is a boolean expression
         if let Some(error_guaranteed) = let_expr.is_recovered {
             self.set_tainted_by_errors(error_guaranteed);
@@ -1950,6 +1966,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let len = remaining_fields.len();
 
+        #[allow(rustc::potential_query_instability)]
         let mut displayable_field_names: Vec<&str> =
             remaining_fields.keys().map(|ident| ident.as_str()).collect();
         // sorting &str primitives here, sort_unstable is ok
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index c6b9197d0e9..60eb40bd8fe 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -405,7 +405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> {
         match length {
-            &hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span),
+            hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
             hir::ArrayLen::Body(anon_const) => {
                 let span = self.tcx.def_span(anon_const.def_id);
                 let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id);
@@ -1073,6 +1073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self_ty: Option<LoweredTy<'tcx>>,
         res: Res,
         span: Span,
+        path_span: Span,
         hir_id: hir::HirId,
     ) -> (Ty<'tcx>, Res) {
         let tcx = self.tcx;
@@ -1106,7 +1107,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 match container {
                     ty::TraitContainer => callee::check_legal_trait_for_method_call(
                         tcx,
-                        span,
+                        path_span,
                         None,
                         span,
                         container_id,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 6a77450f075..d30c7a4fb38 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -12,7 +12,9 @@ use crate::{
 use itertools::Itertools;
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{pluralize, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
+use rustc_errors::{
+    codes::*, pluralize, Applicability, Diagnostic, ErrCode, ErrorGuaranteed, MultiSpan, StashKey,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -177,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
         }
 
-        let mut err_code = "E0061";
+        let mut err_code = E0061;
 
         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
         let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
@@ -187,7 +189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ty::Tuple(arg_types) => {
                     // Argument length differs
                     if arg_types.len() != provided_args.len() {
-                        err_code = "E0057";
+                        err_code = E0057;
                     }
                     let expected_input_tys = match expected_input_tys {
                         Some(expected_input_tys) => match expected_input_tys.get(0) {
@@ -358,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         if c_variadic && provided_arg_count < minimum_input_count {
-            err_code = "E0060";
+            err_code = E0060;
         }
 
         for arg in provided_args.iter().skip(minimum_input_count) {
@@ -424,7 +426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .map(|vars| self.resolve_vars_if_possible(vars)),
             );
 
-            self.report_arg_errors(
+            self.set_tainted_by_errors(self.report_arg_errors(
                 compatibility_diagonal,
                 formal_and_expected_inputs,
                 provided_args,
@@ -433,7 +435,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 fn_def_id,
                 call_span,
                 call_expr,
-            );
+            ));
         }
     }
 
@@ -443,11 +445,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
         provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
         c_variadic: bool,
-        err_code: &str,
+        err_code: ErrCode,
         fn_def_id: Option<DefId>,
         call_span: Span,
         call_expr: &'tcx hir::Expr<'tcx>,
-    ) {
+    ) -> ErrorGuaranteed {
         // Next, let's construct the error
         let (error_span, full_call_span, call_name, is_method) = match &call_expr.kind {
             hir::ExprKind::Call(
@@ -486,10 +488,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let tcx = self.tcx;
-        // FIXME: taint after emitting errors and pass through an `ErrorGuaranteed`
-        self.set_tainted_by_errors(
-            tcx.dcx().span_delayed_bug(call_span, "no errors reported for args"),
-        );
 
         // Get the argument span in the context of the call span so that
         // suggestions and labels are (more) correct when an arg is a
@@ -696,8 +694,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         Some(mismatch_idx),
                         is_method,
                     );
-                    err.emit();
-                    return;
+                    return err.emit();
                 }
             }
         }
@@ -721,11 +718,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if cfg!(debug_assertions) {
                 span_bug!(error_span, "expected errors from argument matrix");
             } else {
-                tcx.dcx().emit_err(errors::ArgMismatchIndeterminate { span: error_span });
+                return tcx.dcx().emit_err(errors::ArgMismatchIndeterminate { span: error_span });
             }
-            return;
         }
 
+        let mut reported = None;
         errors.retain(|error| {
             let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) =
                 error
@@ -736,16 +733,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let trace =
                 mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
             if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) {
-                self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
+                reported = Some(self.err_ctxt().report_and_explain_type_error(trace, *e).emit());
                 return false;
             }
             true
         });
 
         // We're done if we found errors, but we already emitted them.
-        if errors.is_empty() {
-            return;
+        if let Some(reported) = reported {
+            assert!(errors.is_empty());
+            return reported;
         }
+        assert!(!errors.is_empty());
 
         // Okay, now that we've emitted the special errors separately, we
         // are only left missing/extra/swapped and mismatched arguments, both
@@ -802,8 +801,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(expected_idx.as_usize()),
                 is_method,
             );
-            err.emit();
-            return;
+            return err.emit();
         }
 
         let mut err = if formal_and_expected_inputs.len() == provided_args.len() {
@@ -1251,7 +1249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        err.emit();
+        err.emit()
     }
 
     fn suggest_ptr_null_mut(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 18f547be2a7..ad4546c09b5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -45,14 +45,6 @@ pub struct FnCtxt<'a, 'tcx> {
     /// eventually).
     pub(super) param_env: ty::ParamEnv<'tcx>,
 
-    /// Number of errors that had been reported when we started
-    /// checking this function. On exit, if we find that *more* errors
-    /// have been reported, we will skip regionck and other work that
-    /// expects the types within the function to be consistent.
-    // FIXME(matthewjasper) This should not exist, and it's not correct
-    // if type checking is run in parallel.
-    err_count_on_creation: usize,
-
     /// If `Some`, this stores coercion information for returned
     /// expressions. If `None`, this is in a context where return is
     /// inappropriate, such as a const expression.
@@ -126,7 +118,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         FnCtxt {
             body_id,
             param_env,
-            err_count_on_creation: inh.tcx.dcx().err_count(),
             ret_coercion: None,
             ret_coercion_span: Cell::new(None),
             coroutine_types: None,
@@ -195,10 +186,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }),
         }
     }
-
-    pub fn errors_reported_since_creation(&self) -> bool {
-        self.dcx().err_count() > self.err_count_on_creation
-    }
 }
 
 impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
@@ -369,6 +356,14 @@ pub struct LoweredTy<'tcx> {
 
 impl<'tcx> LoweredTy<'tcx> {
     pub fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> {
-        LoweredTy { raw, normalized: fcx.normalize(span, raw) }
+        // FIXME(-Znext-solver): We're still figuring out how to best handle
+        // normalization and this doesn't feel too great. We should look at this
+        // code again before stabilizing it.
+        let normalized = if fcx.next_trait_solver() {
+            fcx.try_structurally_resolve_type(span, raw)
+        } else {
+            fcx.normalize(span, raw)
+        };
+        LoweredTy { raw, normalized }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 7780ceda1c1..95c1139e43e 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2040,7 +2040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let field_is_local = sole_field.did.is_local();
                     let field_is_accessible =
                         sole_field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx)
-                        // Skip suggestions for unstable public fields (for example `Pin::pointer`)
+                        // Skip suggestions for unstable public fields (for example `Pin::__pointer`)
                         && matches!(self.tcx.eval_stability(sole_field.did, None, expr.span, None), EvalResult::Allow | EvalResult::Unmarked);
 
                     if !field_is_local && !field_is_accessible {
@@ -2140,46 +2140,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr_ty: Ty<'tcx>,
     ) -> bool {
         let tcx = self.tcx;
-        let (adt, unwrap) = match expected.kind() {
+        let (adt, substs, unwrap) = match expected.kind() {
             // In case Option<NonZero*> is wanted, but * is provided, suggest calling new
-            ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
-                // Unwrap option
-                let ty::Adt(adt, _) = args.type_at(0).kind() else {
+            ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
+                let nonzero_type = substs.type_at(0); // Unwrap option type.
+                let ty::Adt(adt, substs) = nonzero_type.kind() else {
                     return false;
                 };
-
-                (adt, "")
+                (adt, substs, "")
             }
-            // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
-            ty::Adt(adt, _) => (adt, ".unwrap()"),
+            // In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
+            ty::Adt(adt, substs) => (adt, substs, ".unwrap()"),
             _ => return false,
         };
 
-        let map = [
-            (sym::NonZeroU8, tcx.types.u8),
-            (sym::NonZeroU16, tcx.types.u16),
-            (sym::NonZeroU32, tcx.types.u32),
-            (sym::NonZeroU64, tcx.types.u64),
-            (sym::NonZeroU128, tcx.types.u128),
-            (sym::NonZeroI8, tcx.types.i8),
-            (sym::NonZeroI16, tcx.types.i16),
-            (sym::NonZeroI32, tcx.types.i32),
-            (sym::NonZeroI64, tcx.types.i64),
-            (sym::NonZeroI128, tcx.types.i128),
+        if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
+            return false;
+        }
+
+        // FIXME: This can be simplified once `NonZero<T>` is stable.
+        let coercable_types = [
+            ("NonZeroU8", tcx.types.u8),
+            ("NonZeroU16", tcx.types.u16),
+            ("NonZeroU32", tcx.types.u32),
+            ("NonZeroU64", tcx.types.u64),
+            ("NonZeroU128", tcx.types.u128),
+            ("NonZeroI8", tcx.types.i8),
+            ("NonZeroI16", tcx.types.i16),
+            ("NonZeroI32", tcx.types.i32),
+            ("NonZeroI64", tcx.types.i64),
+            ("NonZeroI128", tcx.types.i128),
         ];
 
-        let Some((s, _)) = map.iter().find(|&&(s, t)| {
-            self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t)
+        let int_type = substs.type_at(0);
+
+        let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
+            if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }
         }) else {
             return false;
         };
 
-        let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);
-
         err.multipart_suggestion(
-            format!("consider calling `{s}::new`"),
+            format!("consider calling `{nonzero_alias}::new`"),
             vec![
-                (expr.span.shrink_to_lo(), format!("{path}::new(")),
+                (expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")),
                 (expr.span.shrink_to_hi(), format!("){unwrap}")),
             ],
             Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index 52dc1e85916..f9af357f0e7 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -48,9 +48,9 @@ impl<'a> From<&'a hir::Local<'a>> for Declaration<'a> {
     }
 }
 
-impl<'a> From<&'a hir::Let<'a>> for Declaration<'a> {
-    fn from(let_expr: &'a hir::Let<'a>) -> Self {
-        let hir::Let { hir_id, pat, ty, span, init, is_recovered: _ } = *let_expr;
+impl<'a> From<(&'a hir::Let<'a>, hir::HirId)> for Declaration<'a> {
+    fn from((let_expr, hir_id): (&'a hir::Let<'a>, hir::HirId)) -> Self {
+        let hir::Let { pat, ty, span, init, is_recovered: _ } = *let_expr;
         Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr }
     }
 }
@@ -125,9 +125,11 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
         intravisit::walk_local(self, local)
     }
 
-    fn visit_let_expr(&mut self, let_expr: &'tcx hir::Let<'tcx>) {
-        self.declare(let_expr.into());
-        intravisit::walk_let_expr(self, let_expr);
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
+        if let hir::ExprKind::Let(let_expr) = expr.kind {
+            self.declare((let_expr, expr.hir_id).into());
+        }
+        intravisit::walk_expr(self, expr)
     }
 
     fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index e087733130e..2dee5093e87 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -1,5 +1,5 @@
 use hir::HirId;
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_index::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index bdd7c382903..deb3ad2edc7 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -5,7 +5,6 @@
 #![feature(box_patterns)]
 #![feature(min_specialization)]
 #![feature(control_flow_enum)]
-#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate tracing;
@@ -52,7 +51,7 @@ use crate::expectation::Expectation;
 use crate::fn_ctxt::LoweredTy;
 use crate::gather_locals::GatherLocalsVisitor;
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
+use rustc_errors::{codes::*, struct_span_code_err, ErrCode, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::Visitor;
@@ -72,7 +71,7 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 #[macro_export]
 macro_rules! type_error_struct {
-    ($dcx:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
+    ($dcx:expr, $span:expr, $typ:expr, $code:expr, $($message:tt)*) => ({
         let mut err = rustc_errors::struct_span_code_err!($dcx, $span, $code, $($message)*);
 
         if $typ.references_error() {
@@ -376,7 +375,7 @@ fn report_unexpected_variant_res(
     res: Res,
     qpath: &hir::QPath<'_>,
     span: Span,
-    err_code: &str,
+    err_code: ErrCode,
     expected: &str,
 ) -> ErrorGuaranteed {
     let res_descr = match res {
@@ -387,9 +386,9 @@ fn report_unexpected_variant_res(
     let err = tcx
         .dcx()
         .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`"))
-        .with_code(err_code.into());
+        .with_code(err_code);
     match res {
-        Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => {
+        Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == E0164 => {
             let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
             err.with_span_label(span, "`fn` calls are not allowed in patterns")
                 .with_help(format!("for more information, visit {patterns_url}"))
@@ -445,15 +444,6 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
     diag.emit()
 }
 
-/// `expected` here is the expected number of explicit generic arguments on the trait.
-fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
-    let generics = tcx.generics_of(trait_did);
-    generics.count()
-        == expected
-            + if generics.has_self { 1 } else { 0 }
-            + if generics.host_effect_index.is_some() { 1 } else { 0 }
-}
-
 pub fn provide(providers: &mut Providers) {
     method::provide(providers);
     *providers = Providers {
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index af172b59a14..804d6ff2cb5 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -10,7 +10,6 @@ mod suggest;
 pub use self::suggest::SelfSource;
 pub use self::MethodError::*;
 
-use crate::errors::OpMethodGenericParams;
 use crate::FnCtxt;
 use rustc_errors::{Applicability, Diagnostic, SubdiagnosticMessage};
 use rustc_hir as hir;
@@ -385,26 +384,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // type parameters or early-bound regions.
         let tcx = self.tcx;
         let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
-            tcx.dcx().span_delayed_bug(
-                obligation.cause.span,
-                "operator trait does not have corresponding operator method",
-            );
-            return None;
+            bug!("expected associated item for operator trait")
         };
 
-        if method_item.kind != ty::AssocKind::Fn {
-            self.dcx().span_delayed_bug(tcx.def_span(method_item.def_id), "not a method");
-            return None;
-        }
-
         let def_id = method_item.def_id;
-        let generics = tcx.generics_of(def_id);
-
-        if generics.params.len() != 0 {
-            tcx.dcx().emit_fatal(OpMethodGenericParams {
-                span: tcx.def_span(method_item.def_id),
-                method_name: m_name.to_string(),
-            });
+        if method_item.kind != ty::AssocKind::Fn {
+            span_bug!(tcx.def_span(def_id), "expected `{m_name}` to be an associated function");
         }
 
         debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 0b8a25eedaf..6c9501e93fa 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3,17 +3,17 @@
 
 // ignore-tidy-filelength
 
-use crate::errors;
-use crate::errors::{CandidateTraitNote, NoAssociatedItem};
+use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
 use crate::Expectation;
 use crate::FnCtxt;
 use rustc_ast::ast::Mutability;
 use rustc_attr::parse_confusables;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
+use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::StashKey;
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    MultiSpan, StashKey,
 };
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
@@ -459,22 +459,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        let ty_span = match rcvr_ty.kind() {
+        let mut ty_span = match rcvr_ty.kind() {
             ty::Param(param_type) => {
                 Some(param_type.span_from_generics(self.tcx, self.body_id.to_def_id()))
             }
             ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
             _ => None,
         };
-        if let Some(span) = ty_span {
-            err.span_label(
-                span,
-                format!(
-                    "{item_kind} `{item_name}` not found for this {}",
-                    rcvr_ty.prefix_string(self.tcx)
-                ),
-            );
-        }
 
         if let SelfSource::MethodCall(rcvr_expr) = source {
             self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
@@ -547,7 +538,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        let mut bound_spans = vec![];
+        let mut bound_spans: SortedMap<Span, Vec<String>> = Default::default();
         let mut restrict_type_params = false;
         let mut unsatisfied_bounds = false;
         if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
@@ -642,19 +633,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     false
                 };
             let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
-                let msg = format!(
-                    "doesn't satisfy `{}`",
-                    if obligation.len() > 50 { quiet } else { obligation }
-                );
+                let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
                 match &self_ty.kind() {
                     // Point at the type that couldn't satisfy the bound.
-                    ty::Adt(def, _) => bound_spans.push((self.tcx.def_span(def.did()), msg)),
+                    ty::Adt(def, _) => {
+                        bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
+                    }
                     // Point at the trait object that couldn't satisfy the bound.
                     ty::Dynamic(preds, _, _) => {
                         for pred in preds.iter() {
                             match pred.skip_binder() {
                                 ty::ExistentialPredicate::Trait(tr) => {
-                                    bound_spans.push((self.tcx.def_span(tr.def_id), msg.clone()))
+                                    bound_spans
+                                        .get_mut_or_insert_default(tcx.def_span(tr.def_id))
+                                        .push(msg.clone());
                                 }
                                 ty::ExistentialPredicate::Projection(_)
                                 | ty::ExistentialPredicate::AutoTrait(_) => {}
@@ -662,8 +654,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     // Point at the closure that couldn't satisfy the bound.
-                    ty::Closure(def_id, _) => bound_spans
-                        .push((tcx.def_span(*def_id), format!("doesn't satisfy `{quiet}`"))),
+                    ty::Closure(def_id, _) => {
+                        bound_spans
+                            .get_mut_or_insert_default(tcx.def_span(*def_id))
+                            .push(format!("`{quiet}`"));
+                    }
                     _ => {}
                 }
             };
@@ -1170,11 +1165,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
 
-        bound_spans.sort();
-        bound_spans.dedup();
-        for (span, msg) in bound_spans.into_iter() {
+        for (span, mut bounds) in bound_spans {
+            if !tcx.sess.source_map().is_span_accessible(span) {
+                continue;
+            }
+            bounds.sort();
+            bounds.dedup();
+            let pre = if Some(span) == ty_span {
+                ty_span.take();
+                format!(
+                    "{item_kind} `{item_name}` not found for this {} because it ",
+                    rcvr_ty.prefix_string(self.tcx)
+                )
+            } else {
+                String::new()
+            };
+            let msg = match &bounds[..] {
+                [bound] => format!("{pre}doesn't satisfy {bound}"),
+                bounds if bounds.len() > 4 => format!("doesn't satisfy {} bounds", bounds.len()),
+                [bounds @ .., last] => {
+                    format!("{pre}doesn't satisfy {} or {last}", bounds.join(", "))
+                }
+                [] => unreachable!(),
+            };
             err.span_label(span, msg);
         }
+        if let Some(span) = ty_span {
+            err.span_label(
+                span,
+                format!(
+                    "{item_kind} `{item_name}` not found for this {}",
+                    rcvr_ty.prefix_string(self.tcx)
+                ),
+            );
+        }
 
         if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params {
         } else {
@@ -1601,23 +1625,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.ty_to_value_string(rcvr_ty.peel_refs())
         };
         if let SelfSource::MethodCall(_) = source {
-            let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0)
-                && let Some(assoc) = self.associated_value(*impl_did, item_name)
-                && assoc.kind == ty::AssocKind::Fn
-            {
+            let first_arg = static_candidates.get(0).and_then(|candidate_source| {
+                let (assoc_did, self_ty) = match candidate_source {
+                    CandidateSource::Impl(impl_did) => {
+                        (*impl_did, self.tcx.type_of(*impl_did).instantiate_identity())
+                    }
+                    CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty),
+                };
+
+                let assoc = self.associated_value(assoc_did, item_name)?;
+                if assoc.kind != ty::AssocKind::Fn {
+                    return None;
+                }
+
+                // for CandidateSource::Impl, `Self` will be instantiated to a concrete type
+                // but for CandidateSource::Trait, `Self` is still `Self`
                 let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity();
                 sig.inputs().skip_binder().get(0).and_then(|first| {
-                    let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity();
                     // if the type of first arg is the same as the current impl type, we should take the first arg into assoc function
-                    if first.peel_refs() == impl_ty {
+                    let first_ty = first.peel_refs();
+                    if first_ty == self_ty || first_ty == self.tcx.types.self_param {
                         Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()))
                     } else {
                         None
                     }
                 })
-            } else {
-                None
-            };
+            });
+
             let mut applicability = Applicability::MachineApplicable;
             let args = if let SelfSource::MethodCall(receiver) = source
                 && let Some(args) = args
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index ff82e2d653c..9ce61898561 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -1,11 +1,11 @@
 //! Code related to processing overloaded binary and unary operators.
 
 use super::method::MethodCallee;
-use super::{has_expected_num_generic_args, FnCtxt};
+use super::FnCtxt;
 use crate::Expectation;
 use rustc_ast as ast;
 use rustc_data_structures::packed::Pu128;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::traits::ObligationCauseCode;
@@ -44,7 +44,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return_ty
             };
 
-        self.check_lhs_assignable(lhs, "E0067", op.span, |err| {
+        self.check_lhs_assignable(lhs, E0067, op.span, |err| {
             if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
                 if self
                     .lookup_op_method(
@@ -887,25 +887,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             lhs_ty, op, opname, trait_did
         );
 
-        // Catches cases like #83893, where a lang item is declared with the
-        // wrong number of generic arguments. Should have yielded an error
-        // elsewhere by now, but we have to catch it here so that we do not
-        // index `other_tys` out of bounds (if the lang item has too many
-        // generic arguments, `other_tys` is too short).
-        if !has_expected_num_generic_args(
-            self.tcx,
-            trait_did,
-            match op {
-                // Binary ops have a generic right-hand side, unary ops don't
-                Op::Binary(..) => 1,
-                Op::Unary(..) => 0,
-            },
-        ) {
-            self.dcx()
-                .span_delayed_bug(span, "operator didn't have the right number of generic args");
-            return Err(vec![]);
-        }
-
         let opname = Ident::with_dummy_span(opname);
         let (opt_rhs_expr, opt_rhs_ty) = opt_rhs.unzip();
         let input_types = opt_rhs_ty.as_slice();
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index e31eeab4c4a..b7f28ef958a 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -3,8 +3,8 @@ use crate::{errors, FnCtxt, LoweredTy};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    MultiSpan,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed, MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -576,7 +576,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if (lhs, rhs).references_error() {
             err.downgrade_to_delayed_bug();
         }
-        if self.tcx.sess.teach(&err.get_code().unwrap()) {
+        if self.tcx.sess.teach(err.get_code().unwrap()) {
             err.note(
                 "In a match expression, only numbers and characters can be matched \
                     against a range. This is because the compiler checks that the range \
@@ -847,7 +847,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 type_str
             );
             err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
-            if self.tcx.sess.teach(&err.get_code().unwrap()) {
+            if self.tcx.sess.teach(err.get_code().unwrap()) {
                 err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
             }
             return Err(err.emit());
@@ -907,7 +907,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => {
                 let expected = "unit struct, unit variant or constant";
-                let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected);
+                let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, E0533, expected);
                 return Ty::new_error(tcx, e);
             }
             Res::SelfCtor(..)
@@ -923,7 +923,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Type-check the path.
         let (pat_ty, pat_res) =
-            self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
+            self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id);
         if let Some(err) =
             self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
         {
@@ -1061,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         let report_unexpected_res = |res: Res| {
             let expected = "tuple struct or tuple variant";
-            let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0164", expected);
+            let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, E0164, expected);
             on_error(e);
             e
         };
@@ -1078,7 +1078,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Type-check the path.
         let (pat_ty, res) =
-            self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
+            self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id);
         if !pat_ty.is_fn() {
             let e = report_unexpected_res(res);
             return Ty::new_error(tcx, e);
@@ -1669,7 +1669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
         }
-        if tcx.sess.teach(&err.get_code().unwrap()) {
+        if tcx.sess.teach(err.get_code().unwrap()) {
             err.note(
                 "This error indicates that a struct pattern attempted to \
                  extract a nonexistent field from a struct. Struct fields \
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index d6261763772..1eaaf30043b 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -1,5 +1,5 @@
 use crate::method::MethodCallee;
-use crate::{has_expected_num_generic_args, FnCtxt, PlaceOp};
+use crate::{FnCtxt, PlaceOp};
 use rustc_ast as ast;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -209,20 +209,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        // If the lang item was declared incorrectly, stop here so that we don't
-        // run into an ICE (#83893). The error is reported where the lang item is
-        // declared.
-        if !has_expected_num_generic_args(
-            self.tcx,
-            imm_tr,
-            match op {
-                PlaceOp::Deref => 0,
-                PlaceOp::Index => 1,
-            },
-        ) {
-            return None;
-        }
-
         self.lookup_method_in_trait(
             self.misc(span),
             Ident::with_dummy_span(imm_op),
@@ -249,20 +235,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        // If the lang item was declared incorrectly, stop here so that we don't
-        // run into an ICE (#83893). The error is reported where the lang item is
-        // declared.
-        if !has_expected_num_generic_args(
-            self.tcx,
-            mut_tr,
-            match op {
-                PlaceOp::Deref => 0,
-                PlaceOp::Index => 1,
-            },
-        ) {
-            return None;
-        }
-
         self.lookup_method_in_trait(
             self.misc(span),
             Ident::with_dummy_span(mut_op),
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 367a15e1443..82f02b7d47a 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -5,7 +5,6 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs
index d3cf267dc9d..0c1180b3e98 100644
--- a/compiler/rustc_index/src/interval.rs
+++ b/compiler/rustc_index/src/interval.rs
@@ -236,6 +236,12 @@ impl<I: Idx> IntervalSet<I> {
         I: Step,
     {
         assert_eq!(self.domain, other.domain);
+        if self.map.len() < other.map.len() {
+            let backup = self.clone();
+            self.map.clone_from(&other.map);
+            return self.union(&backup);
+        }
+
         let mut did_insert = false;
         for range in other.iter_intervals() {
             did_insert |= self.insert_range(range);
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 185e0c7d698..854841206b8 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -2,16 +2,9 @@
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![cfg_attr(
     feature = "nightly",
-    feature(
-        allow_internal_unstable,
-        extend_one,
-        min_specialization,
-        new_uninit,
-        step_trait,
-        stmt_expr_attributes,
-        test
-    )
+    feature(extend_one, min_specialization, new_uninit, step_trait, test)
 )]
+#![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))]
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 
 pub mod bit_set;
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index 66c5cc774b2..d876174e620 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -12,10 +12,13 @@ use std::vec;
 use crate::{Idx, IndexSlice};
 
 /// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`.
+/// Its purpose is to avoid mixing indexes.
 ///
 /// While it's possible to use `u32` or `usize` directly for `I`,
 /// you almost certainly want to use a [`newtype_index!`]-generated type instead.
 ///
+/// This allows to index the IndexVec with the new index type.
+///
 /// [`newtype_index!`]: ../macro.newtype_index.html
 #[derive(Clone, PartialEq, Eq, Hash)]
 #[repr(transparent)]
@@ -25,11 +28,13 @@ pub struct IndexVec<I: Idx, T> {
 }
 
 impl<I: Idx, T> IndexVec<I, T> {
+    /// Constructs a new, empty `IndexVec<I, T>`.
     #[inline]
     pub const fn new() -> Self {
         IndexVec::from_raw(Vec::new())
     }
 
+    /// Constructs a new `IndexVec<I, T>` from a `Vec<T>`.
     #[inline]
     pub const fn from_raw(raw: Vec<T>) -> Self {
         IndexVec { raw, _marker: PhantomData }
@@ -59,6 +64,7 @@ impl<I: Idx, T> IndexVec<I, T> {
         IndexVec::from_raw(vec![elem; universe.len()])
     }
 
+    /// Creates a new IndexVec with n copies of the `elem`.
     #[inline]
     pub fn from_elem_n(elem: T, n: usize) -> Self
     where
@@ -85,6 +91,7 @@ impl<I: Idx, T> IndexVec<I, T> {
         IndexSlice::from_raw_mut(&mut self.raw)
     }
 
+    /// Pushes an element to the array returning the index where it was pushed to.
     #[inline]
     pub fn push(&mut self, d: T) -> I {
         let idx = self.next_index();
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index aee99063e03..0a128218c92 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -1,7 +1,7 @@
 use hir::GenericParamKind;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
-    IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage,
+    DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
 };
 use rustc_hir as hir;
 use rustc_hir::FnRetTy;
@@ -33,7 +33,7 @@ pub struct OpaqueHiddenTypeDiag {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_type_annotations_needed, code = "E0282")]
+#[diag(infer_type_annotations_needed, code = E0282)]
 pub struct AnnotationRequired<'a> {
     #[primary_span]
     pub span: Span,
@@ -51,7 +51,7 @@ pub struct AnnotationRequired<'a> {
 
 // Copy of `AnnotationRequired` for E0283
 #[derive(Diagnostic)]
-#[diag(infer_type_annotations_needed, code = "E0283")]
+#[diag(infer_type_annotations_needed, code = E0283)]
 pub struct AmbiguousImpl<'a> {
     #[primary_span]
     pub span: Span,
@@ -69,7 +69,7 @@ pub struct AmbiguousImpl<'a> {
 
 // Copy of `AnnotationRequired` for E0284
 #[derive(Diagnostic)]
-#[diag(infer_type_annotations_needed, code = "E0284")]
+#[diag(infer_type_annotations_needed, code = E0284)]
 pub struct AmbiguousReturn<'a> {
     #[primary_span]
     pub span: Span,
@@ -421,7 +421,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_lifetime_mismatch, code = "E0623")]
+#[diag(infer_lifetime_mismatch, code = E0623)]
 pub struct LifetimeMismatch<'a> {
     #[primary_span]
     pub span: Span,
@@ -495,7 +495,7 @@ pub struct MismatchedStaticLifetime<'a> {
 
 #[derive(Diagnostic)]
 pub enum ExplicitLifetimeRequired<'a> {
-    #[diag(infer_explicit_lifetime_required_with_ident, code = "E0621")]
+    #[diag(infer_explicit_lifetime_required_with_ident, code = E0621)]
     WithIdent {
         #[primary_span]
         #[label]
@@ -511,7 +511,7 @@ pub enum ExplicitLifetimeRequired<'a> {
         #[skip_arg]
         new_ty: Ty<'a>,
     },
-    #[diag(infer_explicit_lifetime_required_with_param_type, code = "E0621")]
+    #[diag(infer_explicit_lifetime_required_with_param_type, code = E0621)]
     WithParamType {
         #[primary_span]
         #[label]
@@ -534,7 +534,7 @@ pub enum TyOrSig<'tcx> {
 }
 
 impl IntoDiagnosticArg for TyOrSig<'_> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         match self {
             TyOrSig::Ty(ty) => ty.into_diagnostic_arg(),
             TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(),
@@ -819,7 +819,7 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_but_calling_introduces, code = "E0772")]
+#[diag(infer_but_calling_introduces, code = E0772)]
 pub struct ButCallingIntroduces {
     #[label(infer_label1)]
     pub param_ty_span: Span,
@@ -871,14 +871,14 @@ impl AddToDiagnostic for MoreTargeted {
     where
         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
     {
-        diag.code(rustc_errors::error_code!(E0772));
+        diag.code(E0772);
         diag.primary_message(fluent::infer_more_targeted);
         diag.arg("ident", self.ident);
     }
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_but_needs_to_satisfy, code = "E0759")]
+#[diag(infer_but_needs_to_satisfy, code = E0759)]
 pub struct ButNeedsToSatisfy {
     #[primary_span]
     pub sp: Span,
@@ -904,7 +904,7 @@ pub struct ButNeedsToSatisfy {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_outlives_content, code = "E0312")]
+#[diag(infer_outlives_content, code = E0312)]
 pub struct OutlivesContent<'a> {
     #[primary_span]
     pub span: Span,
@@ -913,7 +913,7 @@ pub struct OutlivesContent<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_outlives_bound, code = "E0476")]
+#[diag(infer_outlives_bound, code = E0476)]
 pub struct OutlivesBound<'a> {
     #[primary_span]
     pub span: Span,
@@ -922,7 +922,7 @@ pub struct OutlivesBound<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_fulfill_req_lifetime, code = "E0477")]
+#[diag(infer_fulfill_req_lifetime, code = E0477)]
 pub struct FulfillReqLifetime<'a> {
     #[primary_span]
     pub span: Span,
@@ -932,7 +932,7 @@ pub struct FulfillReqLifetime<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_lf_bound_not_satisfied, code = "E0478")]
+#[diag(infer_lf_bound_not_satisfied, code = E0478)]
 pub struct LfBoundNotSatisfied<'a> {
     #[primary_span]
     pub span: Span,
@@ -941,7 +941,7 @@ pub struct LfBoundNotSatisfied<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_ref_longer_than_data, code = "E0491")]
+#[diag(infer_ref_longer_than_data, code = E0491)]
 pub struct RefLongerThanData<'a> {
     #[primary_span]
     pub span: Span,
@@ -1117,7 +1117,7 @@ pub enum PlaceholderRelationLfNotSatisfied {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_opaque_captures_lifetime, code = "E0700")]
+#[diag(infer_opaque_captures_lifetime, code = E0700)]
 pub struct OpaqueCapturesLifetime<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -1378,73 +1378,73 @@ pub enum TypeErrorAdditionalDiags {
 
 #[derive(Diagnostic)]
 pub enum ObligationCauseFailureCode {
-    #[diag(infer_oc_method_compat, code = "E0308")]
+    #[diag(infer_oc_method_compat, code = E0308)]
     MethodCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_type_compat, code = "E0308")]
+    #[diag(infer_oc_type_compat, code = E0308)]
     TypeCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_const_compat, code = "E0308")]
+    #[diag(infer_oc_const_compat, code = E0308)]
     ConstCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_try_compat, code = "E0308")]
+    #[diag(infer_oc_try_compat, code = E0308)]
     TryCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_match_compat, code = "E0308")]
+    #[diag(infer_oc_match_compat, code = E0308)]
     MatchCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_if_else_different, code = "E0308")]
+    #[diag(infer_oc_if_else_different, code = E0308)]
     IfElseDifferent {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_no_else, code = "E0317")]
+    #[diag(infer_oc_no_else, code = E0317)]
     NoElse {
         #[primary_span]
         span: Span,
     },
-    #[diag(infer_oc_no_diverge, code = "E0308")]
+    #[diag(infer_oc_no_diverge, code = E0308)]
     NoDiverge {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_fn_main_correct_type, code = "E0580")]
+    #[diag(infer_oc_fn_main_correct_type, code = E0580)]
     FnMainCorrectType {
         #[primary_span]
         span: Span,
     },
-    #[diag(infer_oc_fn_start_correct_type, code = "E0308")]
+    #[diag(infer_oc_fn_start_correct_type, code = E0308)]
     FnStartCorrectType {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_fn_lang_correct_type, code = "E0308")]
+    #[diag(infer_oc_fn_lang_correct_type, code = E0308)]
     FnLangCorrectType {
         #[primary_span]
         span: Span,
@@ -1452,33 +1452,33 @@ pub enum ObligationCauseFailureCode {
         subdiags: Vec<TypeErrorAdditionalDiags>,
         lang_item_name: Symbol,
     },
-    #[diag(infer_oc_intrinsic_correct_type, code = "E0308")]
+    #[diag(infer_oc_intrinsic_correct_type, code = E0308)]
     IntrinsicCorrectType {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_method_correct_type, code = "E0308")]
+    #[diag(infer_oc_method_correct_type, code = E0308)]
     MethodCorrectType {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_closure_selfref, code = "E0644")]
+    #[diag(infer_oc_closure_selfref, code = E0644)]
     ClosureSelfref {
         #[primary_span]
         span: Span,
     },
-    #[diag(infer_oc_cant_coerce, code = "E0308")]
+    #[diag(infer_oc_cant_coerce, code = E0308)]
     CantCoerce {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_generic, code = "E0308")]
+    #[diag(infer_oc_generic, code = E0308)]
     Generic {
         #[primary_span]
         span: Span,
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index 8e45cc6d80e..331e3633e90 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -108,7 +108,7 @@ pub enum SuffixKind {
 }
 
 impl IntoDiagnosticArg for PrefixKind {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         let kind = match self {
             Self::Empty => "empty",
             Self::RefValidFor => "ref_valid_for",
@@ -130,7 +130,7 @@ impl IntoDiagnosticArg for PrefixKind {
 }
 
 impl IntoDiagnosticArg for SuffixKind {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         let kind = match self {
             Self::Empty => "empty",
             Self::Continues => "continues",
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 7882e761a0c..006638b740e 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -60,7 +60,7 @@ use crate::traits::{
 
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::{
-    error_code, pluralize, struct_span_code_err, Applicability, DiagCtxt, Diagnostic,
+    codes::*, pluralize, struct_span_code_err, Applicability, DiagCtxt, Diagnostic,
     DiagnosticBuilder, DiagnosticStyledString, ErrorGuaranteed, IntoDiagnosticArg,
 };
 use rustc_hir as hir;
@@ -518,6 +518,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
                         self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
                     }
+
+                    RegionResolutionError::CannotNormalize(ty, origin) => {
+                        self.tcx
+                            .dcx()
+                            .struct_span_err(origin.span(), format!("cannot normalize `{ty}`"))
+                            .emit();
+                    }
                 }
             }
         }
@@ -559,7 +566,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             RegionResolutionError::GenericBoundFailure(..) => true,
             RegionResolutionError::ConcreteFailure(..)
             | RegionResolutionError::SubSupConflict(..)
-            | RegionResolutionError::UpperBoundUniverseConflict(..) => false,
+            | RegionResolutionError::UpperBoundUniverseConflict(..)
+            | RegionResolutionError::CannotNormalize(..) => false,
         };
 
         let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
@@ -574,6 +582,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(),
             RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(),
             RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(),
+            RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(),
         });
         errors
     }
@@ -2362,9 +2371,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             .dcx()
             .struct_span_err(span, format!("{labeled_user_string} may not live long enough"));
         err.code(match sub.kind() {
-            ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => error_code!(E0309),
-            ty::ReStatic => error_code!(E0310),
-            _ => error_code!(E0311),
+            ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => E0309,
+            ty::ReStatic => E0310,
+            _ => E0311,
         });
 
         '_explain: {
@@ -2914,7 +2923,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
 pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>);
 
 impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         use crate::traits::ObligationCauseCode::*;
         let kind = match self.0.code() {
             CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat",
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 03c8e08aa01..7287fc26053 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
@@ -5,7 +5,7 @@ use crate::errors::{
 use crate::infer::error_reporting::TypeErrCtxt;
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxt;
-use rustc_errors::{DiagnosticBuilder, IntoDiagnosticArg};
+use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode, IntoDiagnosticArg};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def::{CtorOf, DefKind, Namespace};
@@ -43,12 +43,12 @@ pub enum TypeAnnotationNeeded {
     E0284,
 }
 
-impl Into<String> for TypeAnnotationNeeded {
-    fn into(self) -> String {
+impl Into<ErrCode> for TypeAnnotationNeeded {
+    fn into(self) -> ErrCode {
         match self {
-            Self::E0282 => rustc_errors::error_code!(E0282),
-            Self::E0283 => rustc_errors::error_code!(E0283),
-            Self::E0284 => rustc_errors::error_code!(E0284),
+            Self::E0282 => E0282,
+            Self::E0283 => E0283,
+            Self::E0284 => E0284,
         }
     }
 }
@@ -134,7 +134,7 @@ impl InferenceDiagnosticsParentData {
 }
 
 impl IntoDiagnosticArg for UnderspecifiedArgKind {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         let kind = match self {
             Self::Type { .. } => "type",
             Self::Const { is_parameter: true } => "const_with_param",
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index e1a83c86318..b3b83c8ab95 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -30,7 +30,7 @@ impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T>
 where
     T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>,
 {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         rustc_errors::DiagnosticArgValue::Str(self.to_string().into())
     }
 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 21ea48c6c83..0e7c641e0e0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -195,7 +195,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             }
                         }
                         diag.help("type parameters must be constrained to match other types");
-                        if tcx.sess.teach(&diag.get_code().unwrap()) {
+                        if tcx.sess.teach(diag.get_code().unwrap()) {
                             diag.help(
                                 "given a type parameter `T` and a method `foo`:
 ```
@@ -678,7 +678,7 @@ impl<T> Trait<T> for X {
                  https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
             );
         }
-        if tcx.sess.teach(&diag.get_code().unwrap()) {
+        if tcx.sess.teach(diag.get_code().unwrap()) {
             diag.help(
                 "given an associated type `T` and a method `foo`:
 ```
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 0562c6ccfcf..4a1169e68e0 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -98,6 +98,8 @@ pub enum RegionResolutionError<'tcx> {
         SubregionOrigin<'tcx>, // cause of the constraint
         Region<'tcx>,          // the placeholder `'b`
     ),
+
+    CannotNormalize(Ty<'tcx>, SubregionOrigin<'tcx>),
 }
 
 impl<'tcx> RegionResolutionError<'tcx> {
@@ -106,7 +108,8 @@ impl<'tcx> RegionResolutionError<'tcx> {
             RegionResolutionError::ConcreteFailure(origin, _, _)
             | RegionResolutionError::GenericBoundFailure(origin, _, _)
             | RegionResolutionError::SubSupConflict(_, _, origin, _, _, _, _)
-            | RegionResolutionError::UpperBoundUniverseConflict(_, _, _, origin, _) => origin,
+            | RegionResolutionError::UpperBoundUniverseConflict(_, _, _, origin, _)
+            | RegionResolutionError::CannotNormalize(_, origin) => origin,
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 1eab8575fc0..0a39fe007fd 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -278,7 +278,8 @@ pub struct InferCtxt<'tcx> {
 
     /// The set of predicates on which errors have been reported, to
     /// avoid reporting the same error twice.
-    pub reported_trait_errors: RefCell<FxIndexMap<Span, Vec<ty::Predicate<'tcx>>>>,
+    pub reported_trait_errors:
+        RefCell<FxIndexMap<Span, (Vec<ty::Predicate<'tcx>>, ErrorGuaranteed)>>,
 
     pub reported_signature_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
 
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 6379f84aa25..926e198b219 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -1,11 +1,11 @@
 //! Various code related to computing outlives relations.
 use self::env::OutlivesEnvironment;
 use super::region_constraints::RegionConstraintData;
-use super::{InferCtxt, RegionResolutionError};
+use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
 use crate::infer::free_regions::RegionRelations;
 use crate::infer::lexical_region_resolve;
 use rustc_middle::traits::query::OutlivesBound;
-use rustc_middle::ty;
+use rustc_middle::ty::{self, Ty};
 
 pub mod components;
 pub mod env;
@@ -41,12 +41,22 @@ impl<'tcx> InferCtxt<'tcx> {
     /// result. After this, no more unification operations should be
     /// done -- or the compiler will panic -- but it is legal to use
     /// `resolve_vars_if_possible` as well as `fully_resolve`.
+    ///
+    /// If you are in a crate that has access to `rustc_trait_selection`,
+    /// then it's probably better to use `resolve_regions`,
+    /// which knows how to normalize registered region obligations.
     #[must_use]
-    pub fn resolve_regions(
+    pub fn resolve_regions_with_normalize(
         &self,
         outlives_env: &OutlivesEnvironment<'tcx>,
+        deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
     ) -> Vec<RegionResolutionError<'tcx>> {
-        self.process_registered_region_obligations(outlives_env);
+        match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
+            Ok(()) => {}
+            Err((ty, origin)) => {
+                return vec![RegionResolutionError::CannotNormalize(ty, origin)];
+            }
+        };
 
         let (var_infos, data) = {
             let mut inner = self.inner.borrow_mut();
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index d7a3bfcbc41..b10bf98e8b5 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -70,6 +70,7 @@ use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::GenericArgKind;
 use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
+use rustc_span::DUMMY_SP;
 use smallvec::smallvec;
 
 use super::env::OutlivesEnvironment;
@@ -123,26 +124,54 @@ impl<'tcx> InferCtxt<'tcx> {
     /// flow of the inferencer. The key point is that it is
     /// invoked after all type-inference variables have been bound --
     /// right before lexical region resolution.
-    #[instrument(level = "debug", skip(self, outlives_env))]
-    pub fn process_registered_region_obligations(&self, outlives_env: &OutlivesEnvironment<'tcx>) {
+    #[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
+    pub fn process_registered_region_obligations<E>(
+        &self,
+        outlives_env: &OutlivesEnvironment<'tcx>,
+        mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
+    ) -> Result<(), (E, SubregionOrigin<'tcx>)> {
         assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
 
+        let normalized_caller_bounds: Vec<_> = outlives_env
+            .param_env
+            .caller_bounds()
+            .iter()
+            .filter_map(|clause| {
+                let bound_clause = clause.kind();
+                let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
+                    return None;
+                };
+                Some(
+                    deeply_normalize_ty(
+                        outlives.0,
+                        SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
+                    )
+                    .map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
+                )
+            })
+            // FIXME(-Znext-solver): How do we accurately report an error here :(
+            .try_collect()
+            .map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
+
         let my_region_obligations = self.take_registered_region_obligations();
 
         for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
+            let sup_type =
+                deeply_normalize_ty(sup_type, origin.clone()).map_err(|e| (e, origin.clone()))?;
             debug!(?sup_type, ?sub_region, ?origin);
-            let sup_type = self.resolve_vars_if_possible(sup_type);
 
             let outlives = &mut TypeOutlives::new(
                 self,
                 self.tcx,
                 outlives_env.region_bound_pairs(),
                 None,
-                outlives_env.param_env,
+                &normalized_caller_bounds,
             );
             let category = origin.to_constraint_category();
             outlives.type_must_outlive(origin, sup_type, sub_region, category);
         }
+
+        Ok(())
     }
 }
 
@@ -190,7 +219,7 @@ where
         tcx: TyCtxt<'tcx>,
         region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
         implicit_region_bound: Option<ty::Region<'tcx>>,
-        param_env: ty::ParamEnv<'tcx>,
+        caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
     ) -> Self {
         Self {
             delegate,
@@ -199,7 +228,7 @@ where
                 tcx,
                 region_bound_pairs,
                 implicit_region_bound,
-                param_env,
+                caller_bounds,
             ),
         }
     }
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 7a85268492b..5d2f51c689b 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -23,7 +23,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
     /// Outside of borrowck the only way to prove `T: '?0` is by
     /// setting  `'?0` to `'empty`.
     implicit_region_bound: Option<ty::Region<'tcx>>,
-    param_env: ty::ParamEnv<'tcx>,
+    caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
 }
 
 impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
@@ -31,9 +31,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         tcx: TyCtxt<'tcx>,
         region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
         implicit_region_bound: Option<ty::Region<'tcx>>,
-        param_env: ty::ParamEnv<'tcx>,
+        caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
     ) -> Self {
-        Self { tcx, region_bound_pairs, implicit_region_bound, param_env }
+        Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds }
     }
 
     #[instrument(level = "debug", skip(self))]
@@ -219,8 +219,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // To start, collect bounds from user environment. Note that
         // parameter environments are already elaborated, so we don't
         // have to worry about that.
-        let c_b = self.param_env.caller_bounds();
-        let param_bounds = self.collect_outlives_from_clause_list(erased_ty, c_b.into_iter());
+        let param_bounds = self.caller_bounds.iter().copied().filter(move |outlives_predicate| {
+            super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
+        });
 
         // Next, collect regions we scraped from the well-formedness
         // constraints in the fn signature. To do that, we walk the list
@@ -307,22 +308,4 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
             .filter_map(|p| p.no_bound_vars())
             .map(|OutlivesPredicate(_, r)| r)
     }
-
-    /// Searches through a predicate list for a predicate `T: 'a`.
-    ///
-    /// Careful: does not elaborate predicates, and just uses `==`
-    /// when comparing `ty` for equality, so `ty` must be something
-    /// that does not involve inference variables and where you
-    /// otherwise want a precise match.
-    fn collect_outlives_from_clause_list(
-        &self,
-        erased_ty: Ty<'tcx>,
-        clauses: impl Iterator<Item = ty::Clause<'tcx>>,
-    ) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>>
-    {
-        let tcx = self.tcx;
-        clauses.filter_map(|p| p.as_type_outlives_clause()).filter(move |outlives_predicate| {
-            super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
-        })
-    }
 }
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 221b78048cb..e2dd4b49e1a 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -18,12 +18,11 @@
 #![allow(internal_features)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
-#![feature(control_flow_enum)]
 #![feature(extend_one)]
 #![feature(let_chains)]
 #![feature(if_let_guard)]
+#![feature(iterator_try_collect)]
 #![feature(min_specialization)]
-#![feature(never_type)]
 #![feature(try_blocks)]
 #![recursion_limit = "512"] // For rustdoc
 
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index 6f218019dee..eabc1b953af 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -2,7 +2,7 @@ use super::ObjectSafetyViolation;
 
 use crate::infer::InferCtxt;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Map;
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 764306ce6ec..69414a13795 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,12 +1,9 @@
-#![feature(box_patterns)]
 #![feature(decl_macro)]
 #![feature(error_iter)]
-#![feature(internal_output_capture)]
 #![feature(lazy_cell)]
 #![feature(let_chains)]
 #![feature(thread_spawn_unchecked)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs
index 0a632c4d12a..03d178eb266 100644
--- a/compiler/rustc_lexer/src/unescape.rs
+++ b/compiler/rustc_lexer/src/unescape.rs
@@ -80,12 +80,12 @@ impl EscapeError {
     }
 }
 
-/// Takes a contents of a literal (without quotes) and produces a sequence of
-/// escaped characters or errors.
+/// Takes the contents of a unicode-only (non-mixed-utf8) literal (without
+/// quotes) and produces a sequence of escaped characters or errors.
 ///
 /// Values are returned by invoking `callback`. For `Char` and `Byte` modes,
 /// the callback will be called exactly once.
-pub fn unescape_literal<F>(src: &str, mode: Mode, callback: &mut F)
+pub fn unescape_unicode<F>(src: &str, mode: Mode, callback: &mut F)
 where
     F: FnMut(Range<usize>, Result<char, EscapeError>),
 {
@@ -97,50 +97,63 @@ where
         }
         Str | ByteStr => unescape_non_raw_common(src, mode, callback),
         RawStr | RawByteStr => check_raw_common(src, mode, callback),
-        CStr | RawCStr => unreachable!(),
+        RawCStr => check_raw_common(src, mode, &mut |r, mut result| {
+            if let Ok('\0') = result {
+                result = Err(EscapeError::NulInCStr);
+            }
+            callback(r, result)
+        }),
+        CStr => unreachable!(),
     }
 }
 
-/// A unit within CStr. Must not be a nul character.
-pub enum CStrUnit {
-    Byte(u8),
+/// Used for mixed utf8 string literals, i.e. those that allow both unicode
+/// chars and high bytes.
+pub enum MixedUnit {
+    /// Used for ASCII chars (written directly or via `\x00`..`\x7f` escapes)
+    /// and Unicode chars (written directly or via `\u` escapes).
+    ///
+    /// For example, if '¥' appears in a string it is represented here as
+    /// `MixedUnit::Char('¥')`, and it will be appended to the relevant byte
+    /// string as the two-byte UTF-8 sequence `[0xc2, 0xa5]`
     Char(char),
+
+    /// Used for high bytes (`\x80`..`\xff`).
+    ///
+    /// For example, if `\xa5` appears in a string it is represented here as
+    /// `MixedUnit::HighByte(0xa5)`, and it will be appended to the relevant
+    /// byte string as the single byte `0xa5`.
+    HighByte(u8),
 }
 
-impl From<u8> for CStrUnit {
-    fn from(value: u8) -> Self {
-        CStrUnit::Byte(value)
+impl From<char> for MixedUnit {
+    fn from(c: char) -> Self {
+        MixedUnit::Char(c)
     }
 }
 
-impl From<char> for CStrUnit {
-    fn from(value: char) -> Self {
-        CStrUnit::Char(value)
+impl From<u8> for MixedUnit {
+    fn from(n: u8) -> Self {
+        if n.is_ascii() { MixedUnit::Char(n as char) } else { MixedUnit::HighByte(n) }
     }
 }
 
-pub fn unescape_c_string<F>(src: &str, mode: Mode, callback: &mut F)
+/// Takes the contents of a mixed-utf8 literal (without quotes) and produces
+/// a sequence of escaped characters or errors.
+///
+/// Values are returned by invoking `callback`.
+pub fn unescape_mixed<F>(src: &str, mode: Mode, callback: &mut F)
 where
-    F: FnMut(Range<usize>, Result<CStrUnit, EscapeError>),
+    F: FnMut(Range<usize>, Result<MixedUnit, EscapeError>),
 {
     match mode {
-        CStr => {
-            unescape_non_raw_common(src, mode, &mut |r, mut result| {
-                if let Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) = result {
-                    result = Err(EscapeError::NulInCStr);
-                }
-                callback(r, result)
-            });
-        }
-        RawCStr => {
-            check_raw_common(src, mode, &mut |r, mut result| {
-                if let Ok('\0') = result {
-                    result = Err(EscapeError::NulInCStr);
-                }
-                callback(r, result.map(CStrUnit::Char))
-            });
-        }
-        Char | Byte | Str | RawStr | ByteStr | RawByteStr => unreachable!(),
+        CStr => unescape_non_raw_common(src, mode, &mut |r, mut result| {
+            if let Ok(MixedUnit::Char('\0')) = result {
+                result = Err(EscapeError::NulInCStr);
+            }
+            callback(r, result)
+        }),
+        Char | Byte | Str | RawStr | ByteStr | RawByteStr | RawCStr => unreachable!(),
     }
 }
 
@@ -181,29 +194,29 @@ impl Mode {
         }
     }
 
-    /// Non-byte literals should have `\xXX` escapes that are within the ASCII range.
-    fn ascii_escapes_should_be_ascii(self) -> bool {
+    /// Are `\x80`..`\xff` allowed?
+    fn allow_high_bytes(self) -> bool {
         match self {
-            Char | Str => true,
-            Byte | ByteStr | CStr => false,
+            Char | Str => false,
+            Byte | ByteStr | CStr => true,
             RawStr | RawByteStr | RawCStr => unreachable!(),
         }
     }
 
-    /// Whether characters within the literal must be within the ASCII range.
+    /// Are unicode (non-ASCII) chars allowed?
     #[inline]
-    fn chars_should_be_ascii(self) -> bool {
+    fn allow_unicode_chars(self) -> bool {
         match self {
-            Byte | ByteStr | RawByteStr => true,
-            Char | Str | RawStr | CStr | RawCStr => false,
+            Byte | ByteStr | RawByteStr => false,
+            Char | Str | RawStr | CStr | RawCStr => true,
         }
     }
 
-    /// Byte literals do not allow unicode escape.
-    fn is_unicode_escape_disallowed(self) -> bool {
+    /// Are unicode escapes (`\u`) allowed?
+    fn allow_unicode_escapes(self) -> bool {
         match self {
-            Byte | ByteStr => true,
-            Char | Str | CStr => false,
+            Byte | ByteStr => false,
+            Char | Str | CStr => true,
             RawByteStr | RawStr | RawCStr => unreachable!(),
         }
     }
@@ -217,20 +230,19 @@ impl Mode {
     }
 }
 
-fn scan_escape<T: From<u8> + From<char>>(
+fn scan_escape<T: From<char> + From<u8>>(
     chars: &mut Chars<'_>,
     mode: Mode,
 ) -> Result<T, EscapeError> {
     // Previous character was '\\', unescape what follows.
-    let res = match chars.next().ok_or(EscapeError::LoneSlash)? {
-        '"' => b'"',
-        'n' => b'\n',
-        'r' => b'\r',
-        't' => b'\t',
-        '\\' => b'\\',
-        '\'' => b'\'',
-        '0' => b'\0',
-
+    let res: char = match chars.next().ok_or(EscapeError::LoneSlash)? {
+        '"' => '"',
+        'n' => '\n',
+        'r' => '\r',
+        't' => '\t',
+        '\\' => '\\',
+        '\'' => '\'',
+        '0' => '\0',
         'x' => {
             // Parse hexadecimal character code.
 
@@ -240,25 +252,23 @@ fn scan_escape<T: From<u8> + From<char>>(
             let lo = chars.next().ok_or(EscapeError::TooShortHexEscape)?;
             let lo = lo.to_digit(16).ok_or(EscapeError::InvalidCharInHexEscape)?;
 
-            let value = hi * 16 + lo;
-
-            if mode.ascii_escapes_should_be_ascii() && !is_ascii(value) {
-                return Err(EscapeError::OutOfRangeHexEscape);
-            }
+            let value = (hi * 16 + lo) as u8;
 
-            value as u8
+            return if !mode.allow_high_bytes() && !value.is_ascii() {
+                Err(EscapeError::OutOfRangeHexEscape)
+            } else {
+                // This may be a high byte, but that will only happen if `T` is
+                // `MixedUnit`, because of the `allow_high_bytes` check above.
+                Ok(T::from(value as u8))
+            };
         }
-
-        'u' => return scan_unicode(chars, mode.is_unicode_escape_disallowed()).map(Into::into),
+        'u' => return scan_unicode(chars, mode.allow_unicode_escapes()).map(T::from),
         _ => return Err(EscapeError::InvalidEscape),
     };
-    Ok(res.into())
+    Ok(T::from(res))
 }
 
-fn scan_unicode(
-    chars: &mut Chars<'_>,
-    is_unicode_escape_disallowed: bool,
-) -> Result<char, EscapeError> {
+fn scan_unicode(chars: &mut Chars<'_>, allow_unicode_escapes: bool) -> Result<char, EscapeError> {
     // We've parsed '\u', now we have to parse '{..}'.
 
     if chars.next() != Some('{') {
@@ -286,7 +296,7 @@ fn scan_unicode(
 
                 // Incorrect syntax has higher priority for error reporting
                 // than unallowed value for a literal.
-                if is_unicode_escape_disallowed {
+                if !allow_unicode_escapes {
                     return Err(EscapeError::UnicodeEscapeInByte);
                 }
 
@@ -312,12 +322,8 @@ fn scan_unicode(
 }
 
 #[inline]
-fn ascii_check(c: char, chars_should_be_ascii: bool) -> Result<char, EscapeError> {
-    if chars_should_be_ascii && !c.is_ascii() {
-        Err(EscapeError::NonAsciiCharInByte)
-    } else {
-        Ok(c)
-    }
+fn ascii_check(c: char, allow_unicode_chars: bool) -> Result<char, EscapeError> {
+    if allow_unicode_chars || c.is_ascii() { Ok(c) } else { Err(EscapeError::NonAsciiCharInByte) }
 }
 
 fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result<char, EscapeError> {
@@ -326,7 +332,7 @@ fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result<char, Esca
         '\\' => scan_escape(chars, mode),
         '\n' | '\t' | '\'' => Err(EscapeError::EscapeOnlyChar),
         '\r' => Err(EscapeError::BareCarriageReturn),
-        _ => ascii_check(c, mode.chars_should_be_ascii()),
+        _ => ascii_check(c, mode.allow_unicode_chars()),
     }?;
     if chars.next().is_some() {
         return Err(EscapeError::MoreThanOneChar);
@@ -336,12 +342,12 @@ fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result<char, Esca
 
 /// Takes a contents of a string literal (without quotes) and produces a
 /// sequence of escaped characters or errors.
-fn unescape_non_raw_common<F, T: From<u8> + From<char>>(src: &str, mode: Mode, callback: &mut F)
+fn unescape_non_raw_common<F, T: From<char> + From<u8>>(src: &str, mode: Mode, callback: &mut F)
 where
     F: FnMut(Range<usize>, Result<T, EscapeError>),
 {
     let mut chars = src.chars();
-    let chars_should_be_ascii = mode.chars_should_be_ascii(); // get this outside the loop
+    let allow_unicode_chars = mode.allow_unicode_chars(); // get this outside the loop
 
     // The `start` and `end` computation here is complicated because
     // `skip_ascii_whitespace` makes us to skip over chars without counting
@@ -366,7 +372,7 @@ where
             }
             '"' => Err(EscapeError::EscapeOnlyChar),
             '\r' => Err(EscapeError::BareCarriageReturn),
-            _ => ascii_check(c, chars_should_be_ascii).map(Into::into),
+            _ => ascii_check(c, allow_unicode_chars).map(T::from),
         };
         let end = src.len() - chars.as_str().len();
         callback(start..end, res);
@@ -408,7 +414,7 @@ where
     F: FnMut(Range<usize>, Result<char, EscapeError>),
 {
     let mut chars = src.chars();
-    let chars_should_be_ascii = mode.chars_should_be_ascii(); // get this outside the loop
+    let allow_unicode_chars = mode.allow_unicode_chars(); // get this outside the loop
 
     // The `start` and `end` computation here matches the one in
     // `unescape_non_raw_common` for consistency, even though this function
@@ -417,7 +423,7 @@ where
         let start = src.len() - chars.as_str().len() - c.len_utf8();
         let res = match c {
             '\r' => Err(EscapeError::BareCarriageReturnInRawString),
-            _ => ascii_check(c, chars_should_be_ascii),
+            _ => ascii_check(c, allow_unicode_chars),
         };
         let end = src.len() - chars.as_str().len();
         callback(start..end, res);
@@ -430,7 +436,3 @@ pub fn byte_from_char(c: char) -> u8 {
     debug_assert!(res <= u8::MAX as u32, "guaranteed because of ByteStr");
     res as u8
 }
-
-fn is_ascii(x: u32) -> bool {
-    x <= 0x7F
-}
diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs
index 1c25b03fdb2..5b99495f475 100644
--- a/compiler/rustc_lexer/src/unescape/tests.rs
+++ b/compiler/rustc_lexer/src/unescape/tests.rs
@@ -100,7 +100,7 @@ fn test_unescape_char_good() {
 fn test_unescape_str_warn() {
     fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
         let mut unescaped = Vec::with_capacity(literal.len());
-        unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
+        unescape_unicode(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
         assert_eq!(unescaped, expected);
     }
 
@@ -124,7 +124,7 @@ fn test_unescape_str_warn() {
 fn test_unescape_str_good() {
     fn check(literal_text: &str, expected: &str) {
         let mut buf = Ok(String::with_capacity(literal_text.len()));
-        unescape_literal(literal_text, Mode::Str, &mut |range, c| {
+        unescape_unicode(literal_text, Mode::Str, &mut |range, c| {
             if let Ok(b) = &mut buf {
                 match c {
                     Ok(c) => b.push(c),
@@ -241,7 +241,7 @@ fn test_unescape_byte_good() {
 fn test_unescape_byte_str_good() {
     fn check(literal_text: &str, expected: &[u8]) {
         let mut buf = Ok(Vec::with_capacity(literal_text.len()));
-        unescape_literal(literal_text, Mode::ByteStr, &mut |range, c| {
+        unescape_unicode(literal_text, Mode::ByteStr, &mut |range, c| {
             if let Ok(b) = &mut buf {
                 match c {
                     Ok(c) => b.push(byte_from_char(c)),
@@ -264,7 +264,7 @@ fn test_unescape_byte_str_good() {
 fn test_unescape_raw_str() {
     fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
         let mut unescaped = Vec::with_capacity(literal.len());
-        unescape_literal(literal, Mode::RawStr, &mut |range, res| unescaped.push((range, res)));
+        unescape_unicode(literal, Mode::RawStr, &mut |range, res| unescaped.push((range, res)));
         assert_eq!(unescaped, expected);
     }
 
@@ -276,7 +276,7 @@ fn test_unescape_raw_str() {
 fn test_unescape_raw_byte_str() {
     fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
         let mut unescaped = Vec::with_capacity(literal.len());
-        unescape_literal(literal, Mode::RawByteStr, &mut |range, res| unescaped.push((range, res)));
+        unescape_unicode(literal, Mode::RawByteStr, &mut |range, res| unescaped.push((range, res)));
         assert_eq!(unescaped, expected);
     }
 
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 04201a38c35..1c480ec8f53 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -326,11 +326,9 @@ impl LintStore {
 
     /// True if this symbol represents a lint group name.
     pub fn is_lint_group(&self, lint_name: Symbol) -> bool {
-        debug!(
-            "is_lint_group(lint_name={:?}, lint_groups={:?})",
-            lint_name,
-            self.lint_groups.keys().collect::<Vec<_>>()
-        );
+        #[allow(rustc::potential_query_instability)]
+        let lint_groups = self.lint_groups.keys().collect::<Vec<_>>();
+        debug!("is_lint_group(lint_name={:?}, lint_groups={:?})", lint_name, lint_groups);
         let lint_name_str = lint_name.as_str();
         self.lint_groups.contains_key(lint_name_str) || {
             let warnings_name_str = crate::WARNINGS.name_lower();
@@ -374,8 +372,12 @@ impl LintStore {
                     None => {
                         // 1. The tool is currently running, so this lint really doesn't exist.
                         // FIXME: should this handle tools that never register a lint, like rustfmt?
-                        debug!("lints={:?}", self.by_name.keys().collect::<Vec<_>>());
+                        #[allow(rustc::potential_query_instability)]
+                        let lints = self.by_name.keys().collect::<Vec<_>>();
+                        debug!("lints={:?}", lints);
                         let tool_prefix = format!("{tool_name}::");
+
+                        #[allow(rustc::potential_query_instability)]
                         return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
                             self.no_lint_suggestion(&complete_name, tool_name.as_str())
                         } else {
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 312874db3f5..eb42730f69a 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -185,6 +185,7 @@ pub(super) fn builtin(
             db.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");
         }
         BuiltinLintDiagnostics::UnexpectedCfgName((name, name_span), value) => {
+            #[allow(rustc::potential_query_instability)]
             let possibilities: Vec<Symbol> =
                 sess.parse_sess.check_config.expecteds.keys().copied().collect();
             let is_from_cargo = std::env::var_os("CARGO").is_some();
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
index 841d282a099..3bd0c1b8031 100644
--- a/compiler/rustc_lint/src/errors.rs
+++ b/compiler/rustc_lint/src/errors.rs
@@ -1,11 +1,11 @@
 use crate::fluent_generated as fluent;
-use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
+use rustc_errors::{codes::*, AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::lint::Level;
 use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
-#[diag(lint_overruled_attribute, code = "E0453")]
+#[diag(lint_overruled_attribute, code = E0453)]
 pub struct OverruledAttribute<'a> {
     #[primary_span]
     pub span: Span,
@@ -48,7 +48,7 @@ impl AddToDiagnostic for OverruledAttributeSub {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_malformed_attribute, code = "E0452")]
+#[diag(lint_malformed_attribute, code = E0452)]
 pub struct MalformedAttribute {
     #[primary_span]
     pub span: Span,
@@ -67,7 +67,7 @@ pub enum MalformedAttributeSub {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_unknown_tool_in_scoped_lint, code = "E0710")]
+#[diag(lint_unknown_tool_in_scoped_lint, code = E0710)]
 pub struct UnknownToolInScopedLint {
     #[primary_span]
     pub span: Option<Span>,
@@ -78,7 +78,7 @@ pub struct UnknownToolInScopedLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = "E0783")]
+#[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = E0783)]
 pub struct BuiltinEllipsisInclusiveRangePatterns {
     #[primary_span]
     pub span: Span,
@@ -95,13 +95,13 @@ pub struct RequestedLevel<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_unsupported_group, code = "E0602")]
+#[diag(lint_unsupported_group, code = E0602)]
 pub struct UnsupportedGroup {
     pub lint_group: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_check_name_unknown_tool, code = "E0602")]
+#[diag(lint_check_name_unknown_tool, code = E0602)]
 pub struct CheckNameUnknownTool<'a> {
     pub tool_name: Symbol,
     #[subdiagnostic]
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index b5798af7553..1d9ce10bcaf 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -32,14 +32,11 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(if_let_guard)]
-#![feature(iter_intersperse)]
 #![feature(iter_order_by)]
 #![feature(let_chains)]
 #![cfg_attr(not(bootstrap), feature(trait_upcasting))]
 #![feature(min_specialization)]
-#![feature(never_type)]
 #![feature(rustc_attrs)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index e19bb1cb62f..f916deb4a46 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -5,8 +5,8 @@ use std::num::NonZeroU32;
 use crate::errors::RequestedLevel;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
-    DiagnosticStyledString, SubdiagnosticMessage, SuggestionStyle,
+    codes::*, AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder,
+    DiagnosticMessage, DiagnosticStyledString, SubdiagnosticMessage, SuggestionStyle,
 };
 use rustc_hir::def_id::DefId;
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
@@ -1065,7 +1065,7 @@ pub enum UnknownLintSuggestion {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_unknown_lint, code = "E0602")]
+#[diag(lint_unknown_lint, code = E0602)]
 pub struct UnknownLintFromCommandLine<'a> {
     pub name: String,
     #[subdiagnostic]
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index f64509fe8bc..bed5d3c80c0 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -4,7 +4,7 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{
     self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable,
 };
-use rustc_span::Span;
+use rustc_span::{symbol::kw, Span};
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 
@@ -96,6 +96,17 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
                 continue;
             }
 
+            // HACK: `async fn() -> Self` in traits is "ok"...
+            // This is not really that great, but it's similar to why the `-> Self`
+            // return type is well-formed in traits even when `Self` isn't sized.
+            if let ty::Param(param_ty) = *proj_term.kind()
+                && param_ty.name == kw::SelfUpper
+                && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(_))
+                && opaque.in_trait
+            {
+                continue;
+            }
+
             let proj_ty =
                 Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.args);
             // For every instance of the projection type in the bounds,
diff --git a/compiler/rustc_macros/build.rs b/compiler/rustc_macros/build.rs
new file mode 100644
index 00000000000..717f8a92245
--- /dev/null
+++ b/compiler/rustc_macros/build.rs
@@ -0,0 +1,16 @@
+fn main() {
+    println!("cargo:rerun-if-changed=build.rs");
+    println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
+    if !std::env::var("RUSTC_BOOTSTRAP").is_ok() {
+        eprintln!(
+            "error: you are attempting to build the compiler without going through bootstrap"
+        );
+        eprintln!(
+            "help: see https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html for how to build the compiler"
+        );
+        eprintln!(
+            "help: if you know what you're doing, set the RUSTC_BOOTSTRAP environment variable to any value"
+        );
+        panic!("wrong command used for building");
+    }
+}
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 0b7ecff8148..85bb9584a05 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -209,9 +209,9 @@ impl DiagnosticDeriveVariantBuilder {
                 if path.is_ident("code") {
                     self.code.set_once((), path.span().unwrap());
 
-                    let code = nested.parse::<syn::LitStr>()?;
+                    let code = nested.parse::<syn::Expr>()?;
                     tokens.extend(quote! {
-                        diag.code(#code.to_string());
+                        diag.code(#code);
                     });
                 } else {
                     span_err(path.span().unwrap(), "unknown argument")
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 135b9e32fe7..33dffe6998a 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -20,7 +20,7 @@ use synstructure::Structure;
 /// # extern crate rust_middle;
 /// # use rustc_middle::ty::Ty;
 /// #[derive(Diagnostic)]
-/// #[diag(borrowck_move_out_of_borrow, code = "E0505")]
+/// #[diag(borrowck_move_out_of_borrow, code = E0505)]
 /// pub struct MoveOutOfBorrowError<'tcx> {
 ///     pub name: Ident,
 ///     pub ty: Ty<'tcx>,
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index f5d942b924e..9e85a59b5b9 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -9,7 +9,6 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
-#![recursion_limit = "128"]
 
 use synstructure::decl_derive;
 
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 27c26d31781..d17bf0cf708 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -4,7 +4,7 @@ use std::{
 };
 
 use rustc_errors::{
-    error_code, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
+    codes::*, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_macros::Diagnostic;
 use rustc_session::config;
@@ -122,7 +122,7 @@ pub struct WasmImportForm {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_empty_link_name, code = "E0454")]
+#[diag(metadata_empty_link_name, code = E0454)]
 pub struct EmptyLinkName {
     #[primary_span]
     #[label]
@@ -130,21 +130,21 @@ pub struct EmptyLinkName {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_link_framework_apple, code = "E0455")]
+#[diag(metadata_link_framework_apple, code = E0455)]
 pub struct LinkFrameworkApple {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_framework_only_windows, code = "E0455")]
+#[diag(metadata_framework_only_windows, code = E0455)]
 pub struct FrameworkOnlyWindows {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_unknown_link_kind, code = "E0458")]
+#[diag(metadata_unknown_link_kind, code = E0458)]
 pub struct UnknownLinkKind<'a> {
     #[primary_span]
     #[label]
@@ -239,7 +239,7 @@ pub struct IncompatibleWasmLink {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_link_requires_name, code = "E0459")]
+#[diag(metadata_link_requires_name, code = E0459)]
 pub struct LinkRequiresName {
     #[primary_span]
     #[label]
@@ -502,7 +502,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_multiple_candidates);
         diag.arg("crate_name", self.crate_name);
         diag.arg("flavor", self.flavor);
-        diag.code(error_code!(E0464));
+        diag.code(E0464);
         diag.span(self.span);
         for (i, candidate) in self.candidates.iter().enumerate() {
             diag.note(format!("candidate #{}: {}", i + 1, candidate.display()));
@@ -512,7 +512,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_symbol_conflicts_current, code = "E0519")]
+#[diag(metadata_symbol_conflicts_current, code = E0519)]
 pub struct SymbolConflictsCurrent {
     #[primary_span]
     pub span: Span,
@@ -537,7 +537,7 @@ pub struct DlError {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_newer_crate_version, code = "E0460")]
+#[diag(metadata_newer_crate_version, code = E0460)]
 #[note]
 #[note(metadata_found_crate_versions)]
 pub struct NewerCrateVersion {
@@ -549,7 +549,7 @@ pub struct NewerCrateVersion {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_no_crate_with_triple, code = "E0461")]
+#[diag(metadata_no_crate_with_triple, code = E0461)]
 #[note(metadata_found_crate_versions)]
 pub struct NoCrateWithTriple<'a> {
     #[primary_span]
@@ -561,7 +561,7 @@ pub struct NoCrateWithTriple<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_found_staticlib, code = "E0462")]
+#[diag(metadata_found_staticlib, code = E0462)]
 #[note(metadata_found_crate_versions)]
 #[help]
 pub struct FoundStaticlib {
@@ -573,7 +573,7 @@ pub struct FoundStaticlib {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_incompatible_rustc, code = "E0514")]
+#[diag(metadata_incompatible_rustc, code = E0514)]
 #[note(metadata_found_crate_versions)]
 #[help]
 pub struct IncompatibleRustc {
@@ -598,7 +598,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for InvalidMetadataFiles {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_invalid_meta_files);
         diag.arg("crate_name", self.crate_name);
         diag.arg("add_info", self.add_info);
-        diag.code(error_code!(E0786));
+        diag.code(E0786);
         diag.span(self.span);
         for crate_rejection in self.crate_rejections {
             diag.note(crate_rejection);
@@ -627,7 +627,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for CannotFindCrate {
         diag.arg("current_crate", self.current_crate);
         diag.arg("add_info", self.add_info);
         diag.arg("locator_triple", self.locator_triple.triple());
-        diag.code(error_code!(E0463));
+        diag.code(E0463);
         diag.span(self.span);
         if (self.crate_name == sym::std || self.crate_name == sym::core)
             && self.locator_triple != TargetTriple::from_triple(config::host_triple())
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 6c6c60af063..471425e8017 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -11,11 +11,9 @@
 #![feature(proc_macro_internals)]
 #![feature(macro_metavar_expr)]
 #![feature(min_specialization)]
-#![feature(slice_as_chunks)]
 #![feature(trusted_len)]
 #![feature(try_blocks)]
 #![feature(never_type)]
-#![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 2376d953341..1ab965e2876 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -291,7 +291,7 @@ impl fmt::Display for CrateFlavor {
 }
 
 impl IntoDiagnosticArg for CrateFlavor {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         match self {
             CrateFlavor::Rlib => DiagnosticArgValue::Str(Cow::Borrowed("rlib")),
             CrateFlavor::Rmeta => DiagnosticArgValue::Str(Cow::Borrowed("rmeta")),
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index 3c553657087..211da800202 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -1,14 +1,14 @@
 use std::borrow::Cow;
 use std::fmt;
 
-use rustc_errors::{DiagnosticArgValue, DiagnosticMessage};
+use rustc_errors::{codes::*, DiagnosticArgValue, DiagnosticMessage};
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
 
 use crate::ty::Ty;
 
 #[derive(Diagnostic)]
-#[diag(middle_drop_check_overflow, code = "E0320")]
+#[diag(middle_drop_check_overflow, code = E0320)]
 #[note]
 pub struct DropCheckOverflow<'tcx> {
     #[primary_span]
@@ -95,17 +95,14 @@ pub(super) struct ConstNotUsedTraitAlias {
 
 pub struct CustomSubdiagnostic<'a> {
     pub msg: fn() -> DiagnosticMessage,
-    pub add_args:
-        Box<dyn FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>)) + 'a>,
+    pub add_args: Box<dyn FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue)) + 'a>,
 }
 
 impl<'a> CustomSubdiagnostic<'a> {
     pub fn label(x: fn() -> DiagnosticMessage) -> Self {
         Self::label_and_then(x, |_| {})
     }
-    pub fn label_and_then<
-        F: FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>)) + 'a,
-    >(
+    pub fn label_and_then<F: FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue)) + 'a>(
         msg: fn() -> DiagnosticMessage,
         f: F,
     ) -> Self {
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index dec3419819f..ddfb2ece39f 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -33,7 +33,6 @@
 #![feature(discriminant_kind)]
 #![feature(exhaustive_patterns)]
 #![feature(coroutines)]
-#![feature(get_mut_unchecked)]
 #![feature(if_let_guard)]
 #![feature(inline_const)]
 #![feature(iter_from_coroutine)]
@@ -50,19 +49,14 @@
 #![feature(rustc_attrs)]
 #![feature(control_flow_enum)]
 #![cfg_attr(not(bootstrap), feature(trait_upcasting))]
-#![feature(trusted_step)]
 #![feature(try_blocks)]
-#![feature(try_reserve_kind)]
-#![feature(nonzero_ops)]
 #![feature(decl_macro)]
 #![feature(extract_if)]
 #![feature(intra_doc_pointers)]
 #![feature(yeet_expr)]
 #![feature(const_option)]
-#![feature(trait_alias)]
 #![feature(ptr_alignment_type)]
 #![feature(macro_metavar_expr)]
-#![recursion_limit = "512"]
 #![allow(rustc::potential_query_instability)]
 #![allow(internal_features)]
 
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 5d6a7f75df8..b9914f6cb7a 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -221,9 +221,6 @@ pub struct ScopeTree {
     /// variable is declared.
     var_map: FxIndexMap<hir::ItemLocalId, Scope>,
 
-    /// Maps from a `NodeId` to the associated destruction scope (if any).
-    destruction_scopes: FxIndexMap<hir::ItemLocalId, Scope>,
-
     /// Identifies expressions which, if captured into a temporary, ought to
     /// have a temporary whose lifetime extends to the end of the enclosing *block*,
     /// and not the enclosing *statement*. Expressions that are not present in this
@@ -336,11 +333,6 @@ impl ScopeTree {
             let prev = self.parent_map.insert(child, p);
             assert!(prev.is_none());
         }
-
-        // Record the destruction scopes for later so we can query them.
-        if let ScopeData::Destruction = child.data {
-            self.destruction_scopes.insert(child.item_local_id(), child);
-        }
     }
 
     pub fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) {
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 7a1df495451..95574aee499 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -233,7 +233,7 @@ pub enum InvalidMetaKind {
 }
 
 impl IntoDiagnosticArg for InvalidMetaKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(match self {
             InvalidMetaKind::SliceTooBig => "slice_too_big",
             InvalidMetaKind::TooBig => "too_big",
@@ -267,7 +267,7 @@ pub struct Misalignment {
 macro_rules! impl_into_diagnostic_arg_through_debug {
     ($($ty:ty),*$(,)?) => {$(
         impl IntoDiagnosticArg for $ty {
-            fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+            fn into_diagnostic_arg(self) -> DiagnosticArgValue {
                 DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
             }
         }
@@ -367,7 +367,7 @@ pub enum PointerKind {
 }
 
 impl IntoDiagnosticArg for PointerKind {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(
             match self {
                 Self::Ref => "ref",
@@ -485,10 +485,7 @@ pub trait MachineStopType: Any + fmt::Debug + Send {
     fn diagnostic_message(&self) -> DiagnosticMessage;
     /// Add diagnostic arguments by passing name and value pairs to `adder`, which are passed to
     /// fluent for formatting the translated diagnostic message.
-    fn add_args(
-        self: Box<Self>,
-        adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>),
-    );
+    fn add_args(self: Box<Self>, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue));
 }
 
 impl dyn MachineStopType {
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index a5c229879a7..a4b6c4f9c3f 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1074,6 +1074,8 @@ pub enum ProjectionElem<V, T> {
     /// "Downcast" to a variant of an enum or a coroutine.
     ///
     /// The included Symbol is the name of the variant, used for printing MIR.
+    ///
+    /// This operation itself is never UB, all it does is change the type of the place.
     Downcast(Option<Symbol>, VariantIdx),
 
     /// Like an explicit cast from an opaque type to a concrete type, but without
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index fdbbf468ece..0fe33e441f4 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -292,7 +292,7 @@ impl<O> AssertKind<O> {
         }
     }
 
-    pub fn add_args(self, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue<'static>))
+    pub fn add_args(self, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue))
     where
         O: fmt::Debug,
     {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 1122f571fff..b383a6f5e52 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -109,7 +109,7 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
 // as they will raise an fatal error on query cycles instead.
 rustc_queries! {
     /// This exists purely for testing the interactions between span_delayed_bug and incremental.
-    query trigger_span_delayed_bug(key: DefId) -> () {
+    query trigger_span_delayed_bug(key: DefId) {
         desc { "triggering a span delayed bug for testing incremental" }
     }
 
@@ -119,7 +119,7 @@ rustc_queries! {
         desc { "compute registered tools for crate" }
     }
 
-    query early_lint_checks(_: ()) -> () {
+    query early_lint_checks(_: ()) {
         desc { "perform lints prior to macro expansion" }
     }
 
@@ -299,7 +299,7 @@ rustc_queries! {
     /// name. This is useful for cases were not all linting code from rustc
     /// was called. With the default `None` all registered lints will also
     /// be checked for expectation fulfillment.
-    query check_expectations(key: Option<Symbol>) -> () {
+    query check_expectations(key: Option<Symbol>) {
         eval_always
         desc { "checking lint expectations (RFC 2383)" }
     }
@@ -906,39 +906,39 @@ rustc_queries! {
     }
 
     /// Performs lint checking for the module.
-    query lint_mod(key: LocalModDefId) -> () {
+    query lint_mod(key: LocalModDefId) {
         desc { |tcx| "linting {}", describe_as_module(key, tcx) }
     }
 
-    query check_unused_traits(_: ()) -> () {
+    query check_unused_traits(_: ()) {
         desc { "checking unused trait imports in crate" }
     }
 
     /// Checks the attributes in the module.
-    query check_mod_attrs(key: LocalModDefId) -> () {
+    query check_mod_attrs(key: LocalModDefId) {
         desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) }
     }
 
     /// Checks for uses of unstable APIs in the module.
-    query check_mod_unstable_api_usage(key: LocalModDefId) -> () {
+    query check_mod_unstable_api_usage(key: LocalModDefId) {
         desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
     }
 
     /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`).
-    query check_mod_const_bodies(key: LocalModDefId) -> () {
+    query check_mod_const_bodies(key: LocalModDefId) {
         desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) }
     }
 
     /// Checks the loops in the module.
-    query check_mod_loops(key: LocalModDefId) -> () {
+    query check_mod_loops(key: LocalModDefId) {
         desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_naked_functions(key: LocalModDefId) -> () {
+    query check_mod_naked_functions(key: LocalModDefId) {
         desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_privacy(key: LocalModDefId) -> () {
+    query check_mod_privacy(key: LocalModDefId) {
         desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
     }
 
@@ -958,7 +958,7 @@ rustc_queries! {
         desc { "finding live symbols in crate" }
     }
 
-    query check_mod_deathness(key: LocalModDefId) -> () {
+    query check_mod_deathness(key: LocalModDefId) {
         desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
     }
 
@@ -972,7 +972,7 @@ rustc_queries! {
         ensure_forwards_result_if_red
     }
 
-    query collect_mod_item_types(key: LocalModDefId) -> () {
+    query collect_mod_item_types(key: LocalModDefId) {
         desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
     }
 
@@ -1121,7 +1121,7 @@ rustc_queries! {
         eval_always
         desc { "checking effective visibilities" }
     }
-    query check_private_in_public(_: ()) -> () {
+    query check_private_in_public(_: ()) {
         eval_always
         desc { "checking for private elements in public interfaces" }
     }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index b4b8387c262..0fed4ccc62a 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -674,7 +674,7 @@ impl<'tcx> Pat<'tcx> {
 }
 
 impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         format!("{self}").into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 135680b9349..894acf3c2aa 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -292,6 +292,8 @@ pub enum ObligationCauseCode<'tcx> {
     SizedArgumentType(Option<hir::HirId>),
     /// Return type must be `Sized`.
     SizedReturnType,
+    /// Return type of a call expression must be `Sized`.
+    SizedCallReturnType,
     /// Yield type must be `Sized`.
     SizedYieldType,
     /// Inline asm operand type must be `Sized`.
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 310cf113b11..f7c33960fdd 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -117,7 +117,7 @@ impl std::fmt::Debug for ConstInt {
 impl IntoDiagnosticArg for ConstInt {
     // FIXME this simply uses the Debug impl, but we could probably do better by converting both
     // to an inherent method that returns `Cow`.
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(format!("{self:?}").into())
     }
 }
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 16e7b16a0bf..603d7f46aab 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -15,7 +15,7 @@ pub struct UnevaluatedConst<'tcx> {
 }
 
 impl rustc_errors::IntoDiagnosticArg for UnevaluatedConst<'_> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         format!("{self:?}").into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index c1e2479defd..8678f388298 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -20,7 +20,7 @@ use rustc_span::{BytePos, Span};
 use rustc_type_ir::TyKind::*;
 
 impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 5a4b86eeffd..69ad6810c6f 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -56,7 +56,7 @@ unsafe impl<'tcx> Sync for GenericArg<'tcx> where
 }
 
 impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 25473f52c03..f07a4ac29e9 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -269,7 +269,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
 }
 
 impl<'tcx> IntoDiagnosticArg for LayoutError<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index dac60ae58a0..dabd50a32b9 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -583,13 +583,13 @@ impl<'tcx> Predicate<'tcx> {
 }
 
 impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string()))
     }
 }
 
 impl rustc_errors::IntoDiagnosticArg for Clause<'_> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string()))
     }
 }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 73052be30ae..bac5068a69b 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2632,7 +2632,7 @@ where
 pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
 
 impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintOnlyTraitPath<'tcx> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
@@ -2649,7 +2649,7 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
 pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>);
 
 impl<'tcx> rustc_errors::IntoDiagnosticArg for TraitRefPrintSugared<'tcx> {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index b089f4a9e78..43a6281481f 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -862,7 +862,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
 }
 
 impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
@@ -908,7 +908,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
 }
 
 impl<'tcx> IntoDiagnosticArg for ExistentialTraitRef<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
@@ -1149,7 +1149,7 @@ impl<'tcx, T> IntoDiagnosticArg for Binder<'tcx, T>
 where
     T: IntoDiagnosticArg,
 {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.value.into_diagnostic_arg()
     }
 }
@@ -1359,7 +1359,7 @@ impl<'tcx> FnSig<'tcx> {
 }
 
 impl<'tcx> IntoDiagnosticArg for FnSig<'tcx> {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 6a03bf243eb..27b48f46e75 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -1,7 +1,7 @@
 use crate::dep_graph::dep_kinds;
 use crate::query::plumbing::CyclePlaceholder;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_middle::ty::Representability;
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index a7f6f4873e3..065c93e86a8 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -15,7 +15,9 @@
 use crate::build::expr::as_place::PlaceBuilder;
 use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
 use crate::build::Builder;
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::thir::{self, *};
+use rustc_middle::ty;
 
 use std::mem;
 
@@ -149,7 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 ref subpattern,
                 ascription: thir::Ascription { ref annotation, variance },
             } => {
-                // Apply the type ascription to the value at `match_pair.place`, which is the
+                // Apply the type ascription to the value at `match_pair.place`
                 if let Some(source) = match_pair.place.try_to_place(self) {
                     candidate.ascriptions.push(Ascription {
                         annotation: annotation.clone(),
@@ -205,7 +207,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 Err(match_pair)
             }
 
-            PatKind::InlineConstant { subpattern: ref pattern, def: _ } => {
+            PatKind::InlineConstant { subpattern: ref pattern, def } => {
+                // Apply a type ascription for the inline constant to the value at `match_pair.place`
+                if let Some(source) = match_pair.place.try_to_place(self) {
+                    let span = match_pair.pattern.span;
+                    let parent_id = self.tcx.typeck_root_def_id(self.def_id.to_def_id());
+                    let args = ty::InlineConstArgs::new(
+                        self.tcx,
+                        ty::InlineConstArgsParts {
+                            parent_args: ty::GenericArgs::identity_for_item(self.tcx, parent_id),
+                            ty: self.infcx.next_ty_var(TypeVariableOrigin {
+                                kind: TypeVariableOriginKind::MiscVariable,
+                                span,
+                            }),
+                        },
+                    )
+                    .args;
+                    let user_ty =
+                        self.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
+                            def.to_def_id(),
+                            ty::UserArgs { args, user_self_ty: None },
+                        ));
+                    let annotation = ty::CanonicalUserTypeAnnotation {
+                        inferred_ty: pattern.ty,
+                        span,
+                        user_ty: Box::new(user_ty),
+                    };
+                    candidate.ascriptions.push(Ascription {
+                        annotation,
+                        source,
+                        variance: ty::Contravariant,
+                    });
+                }
                 candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
 
                 Ok(())
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index ac147afaab3..422549755d1 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -605,7 +605,7 @@ impl UnsafeOpKind {
                 span,
                 UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
                     span,
-                    function: &with_no_trimmed_paths!(tcx.def_path_str(*did)),
+                    function: with_no_trimmed_paths!(tcx.def_path_str(*did)),
                     unsafe_not_inherited_note,
                 },
             ),
@@ -696,14 +696,17 @@ impl UnsafeOpKind {
                 span,
                 UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
                     span,
-                    function: &with_no_trimmed_paths!(tcx.def_path_str(*function)),
+                    function: with_no_trimmed_paths!(tcx.def_path_str(*function)),
                     missing_target_features: DiagnosticArgValue::StrListSepByAnd(
-                        missing.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
                     ),
                     missing_target_features_count: missing.len(),
                     note: if build_enabled.is_empty() { None } else { Some(()) },
                     build_target_features: DiagnosticArgValue::StrListSepByAnd(
-                        build_enabled.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        build_enabled
+                            .iter()
+                            .map(|feature| Cow::from(feature.to_string()))
+                            .collect(),
                     ),
                     build_target_features_count: build_enabled.len(),
                     unsafe_not_inherited_note,
@@ -747,14 +750,14 @@ impl UnsafeOpKind {
                 dcx.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
                     unsafe_not_inherited_note,
-                    function: &tcx.def_path_str(*did),
+                    function: tcx.def_path_str(*did),
                 });
             }
             CallToUnsafeFunction(Some(did)) => {
                 dcx.emit_err(CallToUnsafeFunctionRequiresUnsafe {
                     span,
                     unsafe_not_inherited_note,
-                    function: &tcx.def_path_str(*did),
+                    function: tcx.def_path_str(*did),
                 });
             }
             CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => {
@@ -860,32 +863,38 @@ impl UnsafeOpKind {
                 dcx.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
                     span,
                     missing_target_features: DiagnosticArgValue::StrListSepByAnd(
-                        missing.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
                     ),
                     missing_target_features_count: missing.len(),
                     note: if build_enabled.is_empty() { None } else { Some(()) },
                     build_target_features: DiagnosticArgValue::StrListSepByAnd(
-                        build_enabled.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        build_enabled
+                            .iter()
+                            .map(|feature| Cow::from(feature.to_string()))
+                            .collect(),
                     ),
                     build_target_features_count: build_enabled.len(),
                     unsafe_not_inherited_note,
-                    function: &tcx.def_path_str(*function),
+                    function: tcx.def_path_str(*function),
                 });
             }
             CallToFunctionWith { function, missing, build_enabled } => {
                 dcx.emit_err(CallToFunctionWithRequiresUnsafe {
                     span,
                     missing_target_features: DiagnosticArgValue::StrListSepByAnd(
-                        missing.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
                     ),
                     missing_target_features_count: missing.len(),
                     note: if build_enabled.is_empty() { None } else { Some(()) },
                     build_target_features: DiagnosticArgValue::StrListSepByAnd(
-                        build_enabled.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        build_enabled
+                            .iter()
+                            .map(|feature| Cow::from(feature.to_string()))
+                            .collect(),
                     ),
                     build_target_features_count: build_enabled.len(),
                     unsafe_not_inherited_note,
-                    function: &tcx.def_path_str(*function),
+                    function: tcx.def_path_str(*function),
                 });
             }
         }
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index e1b998b2471..3c1ba26a503 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1,7 +1,7 @@
 use crate::fluent_generated as fluent;
 use rustc_errors::DiagnosticArgValue;
 use rustc_errors::{
-    error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
     IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -23,10 +23,10 @@ pub struct UnconditionalRecursion {
 #[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
 #[note]
-pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> {
+pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
     #[label]
     pub span: Span,
-    pub function: &'a str,
+    pub function: String,
     #[subdiagnostic]
     pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
 }
@@ -123,34 +123,34 @@ pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
 #[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
 #[help]
-pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
+pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
     #[label]
     pub span: Span,
-    pub function: &'a str,
-    pub missing_target_features: DiagnosticArgValue<'a>,
+    pub function: String,
+    pub missing_target_features: DiagnosticArgValue,
     pub missing_target_features_count: usize,
     #[note]
     pub note: Option<()>,
-    pub build_target_features: DiagnosticArgValue<'a>,
+    pub build_target_features: DiagnosticArgValue,
     pub build_target_features_count: usize,
     #[subdiagnostic]
     pub unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = "E0133")]
+#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)]
 #[note]
-pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
+pub struct CallToUnsafeFunctionRequiresUnsafe {
     #[primary_span]
     #[label]
     pub span: Span,
-    pub function: &'a str,
+    pub function: String,
     #[subdiagnostic]
     pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")]
+#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)]
 #[note]
 pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
     #[primary_span]
@@ -161,13 +161,13 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
-pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
+pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
     #[label]
     pub span: Span,
-    pub function: &'a str,
+    pub function: String,
     #[subdiagnostic]
     pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
 }
@@ -175,7 +175,7 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
@@ -187,7 +187,7 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_inline_assembly_requires_unsafe, code = "E0133")]
+#[diag(mir_build_inline_assembly_requires_unsafe, code = E0133)]
 #[note]
 pub struct UseOfInlineAssemblyRequiresUnsafe {
     #[primary_span]
@@ -198,7 +198,7 @@ pub struct UseOfInlineAssemblyRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -209,7 +209,7 @@ pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_initializing_type_with_requires_unsafe, code = "E0133")]
+#[diag(mir_build_initializing_type_with_requires_unsafe, code = E0133)]
 #[note]
 pub struct InitializingTypeWithRequiresUnsafe {
     #[primary_span]
@@ -222,7 +222,7 @@ pub struct InitializingTypeWithRequiresUnsafe {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
@@ -234,7 +234,7 @@ pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_mutable_static_requires_unsafe, code = "E0133")]
+#[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub struct UseOfMutableStaticRequiresUnsafe {
     #[primary_span]
@@ -245,7 +245,7 @@ pub struct UseOfMutableStaticRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -256,7 +256,7 @@ pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_extern_static_requires_unsafe, code = "E0133")]
+#[diag(mir_build_extern_static_requires_unsafe, code = E0133)]
 #[note]
 pub struct UseOfExternStaticRequiresUnsafe {
     #[primary_span]
@@ -267,7 +267,7 @@ pub struct UseOfExternStaticRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -278,7 +278,7 @@ pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = "E0133")]
+#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)]
 #[note]
 pub struct DerefOfRawPointerRequiresUnsafe {
     #[primary_span]
@@ -289,7 +289,7 @@ pub struct DerefOfRawPointerRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -300,7 +300,7 @@ pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_union_field_requires_unsafe, code = "E0133")]
+#[diag(mir_build_union_field_requires_unsafe, code = E0133)]
 #[note]
 pub struct AccessToUnionFieldRequiresUnsafe {
     #[primary_span]
@@ -311,7 +311,7 @@ pub struct AccessToUnionFieldRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -322,7 +322,7 @@ pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")]
+#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = E0133)]
 #[note]
 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
     #[primary_span]
@@ -335,7 +335,7 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
@@ -347,7 +347,7 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllow
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")]
+#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = E0133)]
 #[note]
 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
     #[primary_span]
@@ -360,7 +360,7 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
@@ -372,36 +372,36 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_fn_with_requires_unsafe, code = "E0133")]
+#[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)]
 #[help]
-pub struct CallToFunctionWithRequiresUnsafe<'a> {
+pub struct CallToFunctionWithRequiresUnsafe {
     #[primary_span]
     #[label]
     pub span: Span,
-    pub function: &'a str,
-    pub missing_target_features: DiagnosticArgValue<'a>,
+    pub function: String,
+    pub missing_target_features: DiagnosticArgValue,
     pub missing_target_features_count: usize,
     #[note]
     pub note: Option<()>,
-    pub build_target_features: DiagnosticArgValue<'a>,
+    pub build_target_features: DiagnosticArgValue,
     pub build_target_features_count: usize,
     #[subdiagnostic]
     pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[help]
-pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
+pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
     #[label]
     pub span: Span,
-    pub function: &'a str,
-    pub missing_target_features: DiagnosticArgValue<'a>,
+    pub function: String,
+    pub missing_target_features: DiagnosticArgValue,
     pub missing_target_features_count: usize,
     #[note]
     pub note: Option<()>,
-    pub build_target_features: DiagnosticArgValue<'a>,
+    pub build_target_features: DiagnosticArgValue,
     pub build_target_features_count: usize,
     #[subdiagnostic]
     pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
@@ -468,7 +468,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
             fluent::mir_build_non_exhaustive_patterns_type_not_empty,
         );
         diag.span(self.span);
-        diag.code(error_code!(E0004));
+        diag.code(E0004);
         let peeled_ty = self.ty.peel_refs();
         diag.arg("ty", self.ty);
         diag.arg("peeled_ty", peeled_ty);
@@ -539,28 +539,28 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
 pub struct NonExhaustiveMatchAllArmsGuarded;
 
 #[derive(Diagnostic)]
-#[diag(mir_build_static_in_pattern, code = "E0158")]
+#[diag(mir_build_static_in_pattern, code = E0158)]
 pub struct StaticInPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_assoc_const_in_pattern, code = "E0158")]
+#[diag(mir_build_assoc_const_in_pattern, code = E0158)]
 pub struct AssocConstInPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_const_param_in_pattern, code = "E0158")]
+#[diag(mir_build_const_param_in_pattern, code = E0158)]
 pub struct ConstParamInPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_non_const_path, code = "E0080")]
+#[diag(mir_build_non_const_path, code = E0080)]
 pub struct NonConstPath {
     #[primary_span]
     pub span: Span,
@@ -590,7 +590,7 @@ pub struct CouldNotEvalConstPattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")]
+#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = E0030)]
 pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
     #[primary_span]
     #[label]
@@ -611,7 +611,7 @@ pub struct LiteralOutOfRange<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")]
+#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = E0579)]
 pub struct LowerRangeBoundMustBeLessThanUpper {
     #[primary_span]
     pub span: Span,
@@ -634,7 +634,7 @@ pub struct TrailingIrrefutableLetPatterns {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(mir_build_bindings_with_variant_name, code = "E0170")]
+#[diag(mir_build_bindings_with_variant_name, code = E0170)]
 pub struct BindingsWithVariantName {
     #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")]
     pub suggestion: Option<Span>,
@@ -821,7 +821,7 @@ pub struct NonPartialEqMatch<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_pattern_not_covered, code = "E0005")]
+#[diag(mir_build_pattern_not_covered, code = E0005)]
 pub(crate) struct PatternNotCovered<'s, 'tcx> {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 430c4ee3da7..a3d88b12696 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -8,7 +8,6 @@
 #![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate tracing;
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 ce75a2831a5..caf7f4227db 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -11,7 +11,7 @@ use rustc_ast::Mutability;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
+    codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::*;
@@ -47,9 +47,18 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
     };
     visitor.visit_expr(&thir[expr]);
 
+    let origin = match tcx.def_kind(def_id) {
+        DefKind::AssocFn | DefKind::Fn => "function argument",
+        DefKind::Closure => "closure argument",
+        // other types of MIR don't have function parameters, and we don't need to
+        // categorize those for the irrefutable check.
+        _ if thir.params.is_empty() => "",
+        kind => bug!("unexpected function parameters in THIR: {kind:?} {def_id:?}"),
+    };
+
     for param in thir.params.iter() {
         if let Some(box ref pattern) = param.pat {
-            visitor.check_binding_is_irrefutable(pattern, "function argument", None, None);
+            visitor.check_binding_is_irrefutable(pattern, origin, None, None);
         }
     }
     visitor.error
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index ff7e985bdfd..2190ad14b55 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -8,7 +8,7 @@ pub(crate) use self::check_match::check_match;
 use crate::errors::*;
 use crate::thir::util::UserAnnotatedTyHelpers;
 
-use rustc_errors::error_code;
+use rustc_errors::codes::*;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
@@ -209,7 +209,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     RangeEnd::Included => {
                         self.tcx.dcx().emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper {
                             span,
-                            teach: self.tcx.sess.teach(&error_code!(E0030)).then_some(()),
+                            teach: self.tcx.sess.teach(E0030).then_some(()),
                         })
                     }
                     RangeEnd::Excluded => {
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index 815f2045942..1bd9167be12 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -185,8 +185,8 @@ where
         debug_assert_eq!(target.block, self.pos.block);
 
         let block_data = &self.body[target.block];
+        #[rustfmt::skip]
         let next_effect = if A::Direction::IS_FORWARD {
-            #[rustfmt::skip]
             self.pos.curr_effect_index.map_or_else(
                 || Effect::Before.at_index(0),
                 EffectIndex::next_in_forward_order,
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 8d189babee8..23111cc3199 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -3,9 +3,7 @@
 #![feature(exact_size_is_empty)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
-#![feature(stmt_expr_attributes)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 8b9e507c8c7..c49f92f4f85 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -34,7 +34,7 @@ pub(crate) macro throw_machine_stop_str($($tt:tt)*) {{
 
         fn add_args(
             self: Box<Self>,
-            _: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue<'static>),
+            _: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue),
         ) {}
     }
     throw_machine_stop!(Zst)
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index d5f22b2cdbc..ad12bce9b02 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -403,12 +403,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
             operand,
             &mut |elem, op| match elem {
                 TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).ok(),
-                TrackElem::Variant(idx) => {
-                    if op.layout.for_variant(&self.ecx, idx).abi.is_uninhabited() {
-                        return None;
-                    }
-                    self.ecx.project_downcast(op, idx).ok()
-                }
+                TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(),
                 TrackElem::Discriminant => {
                     let variant = self.ecx.read_discriminant(op).ok()?;
                     let discr_value =
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 4574cb4d28d..30de40e226c 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -1,7 +1,7 @@
 use std::borrow::Cow;
 
 use rustc_errors::{
-    Applicability, DecorateLint, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder,
+    codes::*, Applicability, DecorateLint, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder,
     DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -33,7 +33,7 @@ pub(crate) enum ConstMutate {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_transform_unaligned_packed_ref, code = "E0793")]
+#[diag(mir_transform_unaligned_packed_ref, code = E0793)]
 #[note]
 #[note(mir_transform_note_ub)]
 #[help]
@@ -66,7 +66,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for RequiresUnsafe {
     #[track_caller]
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::mir_transform_requires_unsafe);
-        diag.code("E0133".to_string());
+        diag.code(E0133);
         diag.span(self.span);
         diag.span_label(self.span, self.details.label());
         let desc = dcx.eagerly_translate_to_string(self.details.label(), [].into_iter());
@@ -125,7 +125,7 @@ impl RequiresUnsafeDetail {
                 diag.arg(
                     "missing_target_features",
                     DiagnosticArgValue::StrListSepByAnd(
-                        missing.iter().map(|feature| Cow::from(feature.as_str())).collect(),
+                        missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
                     ),
                 );
                 diag.arg("missing_target_features_count", missing.len());
@@ -136,7 +136,7 @@ impl RequiresUnsafeDetail {
                         DiagnosticArgValue::StrListSepByAnd(
                             build_enabled
                                 .iter()
-                                .map(|feature| Cow::from(feature.as_str()))
+                                .map(|feature| Cow::from(feature.to_string()))
                                 .collect(),
                         ),
                     );
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index a78a3fd594d..69f93fa3a0e 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -14,11 +14,9 @@
 #![feature(never_type)]
 #![feature(option_get_or_insert_default)]
 #![feature(round_char_boundary)]
-#![feature(trusted_step)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
 #![feature(if_let_guard)]
-#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index 3fa40db3c80..b0cfa3568ca 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,6 +1,5 @@
 #![feature(array_windows)]
 #![feature(is_sorted)]
-#![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index f904e0c44ea..aac8c0b3103 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -772,6 +772,20 @@ parse_unexpected_const_param_declaration = unexpected `const` parameter declarat
 parse_unexpected_default_value_for_lifetime_in_generic_parameters = unexpected default lifetime parameter
     .label = lifetime parameters cannot have default values
 
+parse_unexpected_expr_in_pat =
+    expected {$is_bound ->
+        [true] a pattern range bound
+       *[false] a pattern
+    }, found {$is_method_call ->
+        [true] a method call
+       *[false] an expression
+    }
+
+    .label = {$is_method_call ->
+        [true] method calls
+       *[false] arbitrary expressions
+    } are not allowed in patterns
+
 parse_unexpected_if_with_if = unexpected `if` in the condition expression
     .suggestion = remove the `if`
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 40852048293..4e4bf9bdad9 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -3,7 +3,7 @@ use std::borrow::Cow;
 use rustc_ast::token::Token;
 use rustc_ast::{Path, Visibility};
 use rustc_errors::{
-    AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
     SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
@@ -25,7 +25,7 @@ pub(crate) struct AmbiguousPlus {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_maybe_recover_from_bad_type_plus, code = "E0178")]
+#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
 pub(crate) struct BadTypePlus {
     pub ty: String,
     #[primary_span]
@@ -807,7 +807,7 @@ pub(crate) struct InclusiveRangeMatchArrow {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_inclusive_range_no_end, code = "E0586")]
+#[diag(parse_inclusive_range_no_end, code = E0586)]
 #[note]
 pub(crate) struct InclusiveRangeNoEnd {
     #[primary_span]
@@ -901,7 +901,7 @@ pub(crate) struct MismatchedClosingDelimiter {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_incorrect_visibility_restriction, code = "E0704")]
+#[diag(parse_incorrect_visibility_restriction, code = E0704)]
 #[help]
 pub(crate) struct IncorrectVisibilityRestriction {
     #[primary_span]
@@ -925,7 +925,7 @@ pub(crate) struct ExpectedStatementAfterOuterAttr {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_doc_comment_does_not_document_anything, code = "E0585")]
+#[diag(parse_doc_comment_does_not_document_anything, code = E0585)]
 #[help]
 pub(crate) struct DocCommentDoesNotDocumentAnything {
     #[primary_span]
@@ -1357,7 +1357,7 @@ pub(crate) struct AttributeOnParamType {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_pattern_method_param_without_body, code = "E0642")]
+#[diag(parse_pattern_method_param_without_body, code = E0642)]
 pub(crate) struct PatternMethodParamWithoutBody {
     #[primary_span]
     #[suggestion(code = "_", applicability = "machine-applicable")]
@@ -1565,7 +1565,7 @@ pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_async_fn_in_2015, code = "E0670")]
+#[diag(parse_async_fn_in_2015, code = E0670)]
 pub(crate) struct AsyncFnIn2015 {
     #[primary_span]
     #[label]
@@ -1929,7 +1929,7 @@ pub struct CrDocComment {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_no_digits_literal, code = "E0768")]
+#[diag(parse_no_digits_literal, code = E0768)]
 pub struct NoDigitsLiteral {
     #[primary_span]
     pub span: Span,
@@ -2416,6 +2416,18 @@ pub(crate) struct ExpectedCommaAfterPatternField {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_unexpected_expr_in_pat)]
+pub(crate) struct UnexpectedExpressionInPattern {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    /// Was a `RangePatternBound` expected?
+    pub is_bound: bool,
+    /// Was the unexpected expression a `MethodCallExpression`?
+    pub is_method_call: bool,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_unexpected_paren_in_range_pat)]
 pub(crate) struct UnexpectedParenInRangePat {
     #[primary_span]
@@ -2499,7 +2511,7 @@ pub(crate) struct FnPointerCannotBeAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_nested_c_variadic_type, code = "E0743")]
+#[diag(parse_nested_c_variadic_type, code = E0743)]
 pub(crate) struct NestedCVariadicType {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index d7ecf577ed6..31552452676 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -7,7 +7,7 @@ use rustc_ast::ast::{self, AttrStyle};
 use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::util::unicode::contains_text_flow_control_chars;
-use rustc_errors::{error_code, Applicability, DiagCtxt, DiagnosticBuilder, StashKey};
+use rustc_errors::{codes::*, Applicability, DiagCtxt, DiagnosticBuilder, StashKey};
 use rustc_lexer::unescape::{self, EscapeError, Mode};
 use rustc_lexer::{Base, DocStyle, RawStrError};
 use rustc_lexer::{Cursor, LiteralKind};
@@ -397,10 +397,10 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 if !terminated {
                     self.dcx()
                         .struct_span_fatal(self.mk_sp(start, end), "unterminated character literal")
-                        .with_code(error_code!(E0762))
+                        .with_code(E0762)
                         .emit()
                 }
-                self.cook_quoted(token::Char, Mode::Char, start, end, 1, 1) // ' '
+                self.cook_unicode(token::Char, Mode::Char, start, end, 1, 1) // ' '
             }
             rustc_lexer::LiteralKind::Byte { terminated } => {
                 if !terminated {
@@ -409,10 +409,10 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start + BytePos(1), end),
                             "unterminated byte constant",
                         )
-                        .with_code(error_code!(E0763))
+                        .with_code(E0763)
                         .emit()
                 }
-                self.cook_quoted(token::Byte, Mode::Byte, start, end, 2, 1) // b' '
+                self.cook_unicode(token::Byte, Mode::Byte, start, end, 2, 1) // b' '
             }
             rustc_lexer::LiteralKind::Str { terminated } => {
                 if !terminated {
@@ -421,10 +421,10 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start, end),
                             "unterminated double quote string",
                         )
-                        .with_code(error_code!(E0765))
+                        .with_code(E0765)
                         .emit()
                 }
-                self.cook_quoted(token::Str, Mode::Str, start, end, 1, 1) // " "
+                self.cook_unicode(token::Str, Mode::Str, start, end, 1, 1) // " "
             }
             rustc_lexer::LiteralKind::ByteStr { terminated } => {
                 if !terminated {
@@ -433,10 +433,10 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start + BytePos(1), end),
                             "unterminated double quote byte string",
                         )
-                        .with_code(error_code!(E0766))
+                        .with_code(E0766)
                         .emit()
                 }
-                self.cook_quoted(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" "
+                self.cook_unicode(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" "
             }
             rustc_lexer::LiteralKind::CStr { terminated } => {
                 if !terminated {
@@ -445,16 +445,16 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start + BytePos(1), end),
                             "unterminated C string",
                         )
-                        .with_code(error_code!(E0767))
+                        .with_code(E0767)
                         .emit()
                 }
-                self.cook_c_string(token::CStr, Mode::CStr, start, end, 2, 1) // c" "
+                self.cook_mixed(token::CStr, Mode::CStr, start, end, 2, 1) // c" "
             }
             rustc_lexer::LiteralKind::RawStr { n_hashes } => {
                 if let Some(n_hashes) = n_hashes {
                     let n = u32::from(n_hashes);
                     let kind = token::StrRaw(n_hashes);
-                    self.cook_quoted(kind, Mode::RawStr, start, end, 2 + n, 1 + n) // r##" "##
+                    self.cook_unicode(kind, Mode::RawStr, start, end, 2 + n, 1 + n) // r##" "##
                 } else {
                     self.report_raw_str_error(start, 1);
                 }
@@ -463,7 +463,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 if let Some(n_hashes) = n_hashes {
                     let n = u32::from(n_hashes);
                     let kind = token::ByteStrRaw(n_hashes);
-                    self.cook_quoted(kind, Mode::RawByteStr, start, end, 3 + n, 1 + n) // br##" "##
+                    self.cook_unicode(kind, Mode::RawByteStr, start, end, 3 + n, 1 + n) // br##" "##
                 } else {
                     self.report_raw_str_error(start, 2);
                 }
@@ -472,7 +472,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 if let Some(n_hashes) = n_hashes {
                     let n = u32::from(n_hashes);
                     let kind = token::CStrRaw(n_hashes);
-                    self.cook_c_string(kind, Mode::RawCStr, start, end, 3 + n, 1 + n) // cr##" "##
+                    self.cook_unicode(kind, Mode::RawCStr, start, end, 3 + n, 1 + n) // cr##" "##
                 } else {
                     self.report_raw_str_error(start, 2);
                 }
@@ -582,7 +582,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
     ) -> ! {
         let mut err =
             self.dcx().struct_span_fatal(self.mk_sp(start, start), "unterminated raw string");
-        err.code(error_code!(E0748));
+        err.code(E0748);
         err.span_label(self.mk_sp(start, start), "unterminated raw string");
 
         if n_hashes > 0 {
@@ -614,7 +614,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
         };
         let last_bpos = self.pos;
         let mut err = self.dcx().struct_span_fatal(self.mk_sp(start, last_bpos), msg);
-        err.code(error_code!(E0758));
+        err.code(E0758);
         let mut nested_block_comment_open_idxs = vec![];
         let mut last_nested_block_comment_idxs = None;
         let mut content_chars = self.str_from(start).char_indices().peekable();
@@ -735,7 +735,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
         }
     }
 
-    fn cook_quoted(
+    fn cook_unicode(
         &self,
         kind: token::LitKind,
         mode: Mode,
@@ -745,13 +745,13 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
         postfix_len: u32,
     ) -> (token::LitKind, Symbol) {
         self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| {
-            unescape::unescape_literal(src, mode, &mut |span, result| {
+            unescape::unescape_unicode(src, mode, &mut |span, result| {
                 callback(span, result.map(drop))
             })
         })
     }
 
-    fn cook_c_string(
+    fn cook_mixed(
         &self,
         kind: token::LitKind,
         mode: Mode,
@@ -761,7 +761,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
         postfix_len: u32,
     ) -> (token::LitKind, Symbol) {
         self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| {
-            unescape::unescape_c_string(src, mode, &mut |span, result| {
+            unescape::unescape_mixed(src, mode, &mut |span, result| {
                 callback(span, result.map(drop))
             })
         })
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index c00e318f227..49e036c3801 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -5,9 +5,6 @@
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![feature(never_type)]
-#![feature(rustc_attrs)]
-#![recursion_limit = "256"]
 #![allow(internal_features)]
 
 #[macro_use]
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index a92609c2c2f..98e062dd784 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -8,7 +8,7 @@ use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle
 use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::token::{self, Delimiter, Nonterminal};
-use rustc_errors::{error_code, Diagnostic, PResult};
+use rustc_errors::{codes::*, Diagnostic, PResult};
 use rustc_span::{sym, BytePos, Span};
 use thin_vec::ThinVec;
 use tracing::debug;
@@ -61,7 +61,7 @@ impl<'a> Parser<'a> {
                     let mut err = self
                         .dcx()
                         .struct_span_err(span, fluent::parse_inner_doc_comment_not_permitted);
-                    err.code(error_code!(E0753));
+                    err.code(E0753);
                     if let Some(replacement_span) = self.annotate_following_item_if_applicable(
                         &mut err,
                         span,
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 720a610fdf5..7a24b819b5f 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -23,7 +23,7 @@ use crate::parser;
 use crate::parser::attr::InnerAttrPolicy;
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
+use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind};
 use rustc_ast::tokenstream::AttrTokenTree;
 use rustc_ast::util::parser::AssocOp;
 use rustc_ast::{
@@ -448,12 +448,11 @@ impl<'a> Parser<'a> {
             })
         }
 
-        let mut expected = edible
+        self.expected_tokens.extend(edible.iter().chain(inedible).cloned().map(TokenType::Token));
+        let mut expected = self
+            .expected_tokens
             .iter()
-            .chain(inedible)
             .cloned()
-            .map(TokenType::Token)
-            .chain(self.expected_tokens.iter().cloned())
             .filter(|token| {
                 // Filter out suggestions that suggest the same token which was found and deemed incorrect.
                 fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
@@ -792,13 +791,28 @@ impl<'a> Parser<'a> {
                 && let [segment] = &attr_kind.item.path.segments[..]
                 && segment.ident.name == sym::cfg
                 && let Some(args_span) = attr_kind.item.args.span()
-                && let Ok(next_attr) = snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
+                && let next_attr = match snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
+                {
+                    Ok(next_attr) => next_attr,
+                    Err(inner_err) => {
+                        err.cancel();
+                        inner_err.cancel();
+                        return;
+                    }
+                }
                 && let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
                 && let Some(next_attr_args_span) = next_attr_kind.item.args.span()
                 && let [next_segment] = &next_attr_kind.item.path.segments[..]
                 && segment.ident.name == sym::cfg
-                && let Ok(next_expr) = snapshot.parse_expr()
             {
+                let next_expr = match snapshot.parse_expr() {
+                    Ok(next_expr) => next_expr,
+                    Err(inner_err) => {
+                        err.cancel();
+                        inner_err.cancel();
+                        return;
+                    }
+                };
                 // We have for sure
                 // #[cfg(..)]
                 // expr
@@ -2927,6 +2941,22 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
+    /// Check for exclusive ranges written as `..<`
+    pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> {
+        if maybe_lt == token::Lt
+            && (self.expected_tokens.contains(&TokenType::Token(token::Gt))
+                || matches!(self.token.kind, token::Literal(..)))
+        {
+            err.span_suggestion(
+                maybe_lt.span,
+                "remove the `<` to write an exclusive range",
+                "",
+                Applicability::MachineApplicable,
+            );
+        }
+        err
+    }
+
     pub fn is_diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> bool {
         (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind))
             && self.look_ahead(3, |tok| tok == short_kind)
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ae3661a530b..9f748e2a3fe 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -28,6 +28,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
     AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey,
 };
+use rustc_lexer::unescape::unescape_char;
 use rustc_macros::Subdiagnostic;
 use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
 use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
@@ -444,6 +445,19 @@ impl<'a> Parser<'a> {
             ) if self.restrictions.contains(Restrictions::CONST_EXPR) => {
                 return None;
             }
+            // When recovering patterns as expressions, stop parsing when encountering an assignment `=`, an alternative `|`, or a range `..`.
+            (
+                Some(
+                    AssocOp::Assign
+                    | AssocOp::AssignOp(_)
+                    | AssocOp::BitOr
+                    | AssocOp::DotDot
+                    | AssocOp::DotDotEq,
+                ),
+                _,
+            ) if self.restrictions.contains(Restrictions::IS_PAT) => {
+                return None;
+            }
             (Some(op), _) => (op, self.token.span),
             (None, Some((Ident { name: sym::and, span }, false))) if self.may_recover() => {
                 self.dcx().emit_err(errors::InvalidLogicalOperator {
@@ -482,7 +496,11 @@ impl<'a> Parser<'a> {
         cur_op_span: Span,
     ) -> PResult<'a, P<Expr>> {
         let rhs = if self.is_at_start_of_range_notation_rhs() {
-            Some(self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)?)
+            let maybe_lt = self.token.clone();
+            Some(
+                self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)
+                    .map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
+            )
         } else {
             None
         };
@@ -531,11 +549,13 @@ impl<'a> Parser<'a> {
         let attrs = self.parse_or_use_outer_attributes(attrs)?;
         self.collect_tokens_for_expr(attrs, |this, attrs| {
             let lo = this.token.span;
+            let maybe_lt = this.look_ahead(1, |t| t.clone());
             this.bump();
             let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
                 // RHS must be parsed with more associativity than the dots.
                 this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
-                    .map(|x| (lo.to(x.span), Some(x)))?
+                    .map(|x| (lo.to(x.span), Some(x)))
+                    .map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
             } else {
                 (lo, None)
             };
@@ -1646,6 +1666,7 @@ impl<'a> Parser<'a> {
             && self.may_recover()
             && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma)
                 || self.token.is_punct())
+            && could_be_unclosed_char_literal(label_.ident)
         {
             let (lit, _) =
                 self.recover_unclosed_char(label_.ident, Parser::mk_token_lit_char, |self_| {
@@ -1731,16 +1752,17 @@ impl<'a> Parser<'a> {
         Ok(expr)
     }
 
-    /// Emit an error when a char is parsed as a lifetime because of a missing quote.
+    /// Emit an error when a char is parsed as a lifetime or label because of a missing quote.
     pub(super) fn recover_unclosed_char<L>(
         &self,
-        lifetime: Ident,
+        ident: Ident,
         mk_lit_char: impl FnOnce(Symbol, Span) -> L,
         err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>,
     ) -> L {
-        if let Some(diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) {
+        assert!(could_be_unclosed_char_literal(ident));
+        if let Some(diag) = self.dcx().steal_diagnostic(ident.span, StashKey::LifetimeIsChar) {
             diag.with_span_suggestion_verbose(
-                lifetime.span.shrink_to_hi(),
+                ident.span.shrink_to_hi(),
                 "add `'` to close the char literal",
                 "'",
                 Applicability::MaybeIncorrect,
@@ -1749,15 +1771,15 @@ impl<'a> Parser<'a> {
         } else {
             err(self)
                 .with_span_suggestion_verbose(
-                    lifetime.span.shrink_to_hi(),
+                    ident.span.shrink_to_hi(),
                     "add `'` to close the char literal",
                     "'",
                     Applicability::MaybeIncorrect,
                 )
                 .emit();
         }
-        let name = lifetime.without_first_quote().name;
-        mk_lit_char(name, lifetime.span)
+        let name = ident.without_first_quote().name;
+        mk_lit_char(name, ident.span)
     }
 
     /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
@@ -2028,8 +2050,11 @@ impl<'a> Parser<'a> {
             let msg = format!("unexpected token: {}", super::token_descr(&token));
             self_.dcx().struct_span_err(token.span, msg)
         };
-        // On an error path, eagerly consider a lifetime to be an unclosed character lit
-        if self.token.is_lifetime() {
+        // On an error path, eagerly consider a lifetime to be an unclosed character lit, if that
+        // makes sense.
+        if let Some(ident) = self.token.lifetime()
+            && could_be_unclosed_char_literal(ident)
+        {
             let lt = self.expect_lifetime();
             Ok(self.recover_unclosed_char(lt.ident, mk_lit_char, err))
         } else {
@@ -3757,6 +3782,13 @@ impl<'a> Parser<'a> {
     }
 }
 
+/// Could this lifetime/label be an unclosed char literal? For example, `'a`
+/// could be, but `'abc` could not.
+pub(crate) fn could_be_unclosed_char_literal(ident: Ident) -> bool {
+    ident.name.as_str().starts_with('\'')
+        && unescape_char(ident.without_first_quote().name.as_str()).is_ok()
+}
+
 /// Used to forbid `let` expressions in certain syntactic locations.
 #[derive(Clone, Copy, Subdiagnostic)]
 pub(crate) enum ForbiddenLetReason {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 3bd8ae02586..9a77643f951 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -10,7 +10,7 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_ast::util::case::Case;
 use rustc_ast::{self as ast};
 use rustc_ast_pretty::pprust;
-use rustc_errors::{struct_span_code_err, Applicability, PResult, StashKey};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, PResult, StashKey};
 use rustc_span::edit_distance::edit_distance;
 use rustc_span::edition::Edition;
 use rustc_span::source_map;
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index ff2fb6271a8..623407eb380 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -53,6 +53,7 @@ bitflags::bitflags! {
         const CONST_EXPR        = 1 << 2;
         const ALLOW_LET         = 1 << 3;
         const IN_IF_GUARD       = 1 << 4;
+        const IS_PAT            = 1 << 5;
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 7918e03750c..12260ec95a5 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,4 +1,4 @@
-use super::{ForceCollect, Parser, PathStyle, TrailingToken};
+use super::{ForceCollect, Parser, PathStyle, Restrictions, TrailingToken};
 use crate::errors::{
     self, AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed,
     DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt,
@@ -6,14 +6,15 @@ use crate::errors::{
     InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern,
     PatternOnWrongSideOfAt, RefMutOrderIncorrect, RemoveLet, RepeatedMutInPattern,
     SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg,
-    TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat,
-    UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam,
-    UnexpectedVertVertInPattern,
+    TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedLifetimeInPattern,
+    UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
+    UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern,
 };
+use crate::parser::expr::could_be_unclosed_char_literal;
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter};
+use rustc_ast::token::{self, BinOpToken, Delimiter, Token};
 use rustc_ast::{
     self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
     PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
@@ -23,7 +24,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use thin_vec::{thin_vec, ThinVec};
 
 #[derive(PartialEq, Copy, Clone)]
@@ -336,6 +337,95 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Ensures that the last parsed pattern (or pattern range bound) is not followed by a method call or an operator.
+    ///
+    /// `is_end_bound` indicates whether the last parsed thing was the end bound of a range pattern (see [`parse_pat_range_end`](Self::parse_pat_range_end))
+    /// in order to say "expected a pattern range bound" instead of "expected a pattern";
+    /// ```text
+    /// 0..=1 + 2
+    ///     ^^^^^
+    /// ```
+    /// Only the end bound is spanned, and this function have no idea if there were a `..=` before `pat_span`, hence the parameter.
+    #[must_use = "the pattern must be discarded as `PatKind::Err` if this function returns Some"]
+    fn maybe_recover_trailing_expr(
+        &mut self,
+        pat_span: Span,
+        is_end_bound: bool,
+    ) -> Option<ErrorGuaranteed> {
+        if self.prev_token.is_keyword(kw::Underscore) || !self.may_recover() {
+            // Don't recover anything after an `_` or if recovery is disabled.
+            return None;
+        }
+
+        // Check for `.hello()`, but allow `.Hello()` to be recovered as `, Hello()` in `parse_seq_to_before_tokens()`.
+        let has_trailing_method = self.check_noexpect(&token::Dot)
+            && self.look_ahead(1, |tok| {
+                tok.ident()
+                    .and_then(|(ident, _)| ident.name.as_str().chars().next())
+                    .is_some_and(char::is_lowercase)
+            })
+            && self.look_ahead(2, |tok| tok.kind == token::OpenDelim(Delimiter::Parenthesis));
+
+        // Check for operators.
+        // `|` is excluded as it is used in pattern alternatives and lambdas,
+        // `?` is included for error propagation,
+        // `[` is included for indexing operations,
+        // `[]` is excluded as `a[]` isn't an expression and should be recovered as `a, []` (cf. `tests/ui/parser/pat-lt-bracket-7.rs`)
+        let has_trailing_operator = matches!(self.token.kind, token::BinOp(op) if op != BinOpToken::Or)
+            || self.token.kind == token::Question
+            || (self.token.kind == token::OpenDelim(Delimiter::Bracket)
+                && self.look_ahead(1, |tok| tok.kind != token::CloseDelim(Delimiter::Bracket)));
+
+        if !has_trailing_method && !has_trailing_operator {
+            // Nothing to recover here.
+            return None;
+        }
+
+        // Let's try to parse an expression to emit a better diagnostic.
+        let mut snapshot = self.create_snapshot_for_diagnostic();
+        snapshot.restrictions.insert(Restrictions::IS_PAT);
+
+        // Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten.
+        if let Ok(expr) = snapshot
+            .parse_expr_dot_or_call_with(
+                self.mk_expr_err(pat_span), // equivalent to transforming the parsed pattern into an `Expr`
+                pat_span,
+                AttrVec::new(),
+            )
+            .map_err(|err| err.cancel())
+        {
+            let non_assoc_span = expr.span;
+
+            // Parse an associative expression such as `+ expr`, `% expr`, ...
+            // Assignements, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
+            if let Ok(expr) =
+                snapshot.parse_expr_assoc_with(0, expr.into()).map_err(|err| err.cancel())
+            {
+                // We got a valid expression.
+                self.restore_snapshot(snapshot);
+                self.restrictions.remove(Restrictions::IS_PAT);
+
+                let is_bound = is_end_bound
+                    // is_start_bound: either `..` or `)..`
+                    || self.token.is_range_separator()
+                    || self.token.kind == token::CloseDelim(Delimiter::Parenthesis)
+                        && self.look_ahead(1, Token::is_range_separator);
+
+                // Check that `parse_expr_assoc_with` didn't eat a rhs.
+                let is_method_call = has_trailing_method && non_assoc_span == expr.span;
+
+                return Some(self.dcx().emit_err(UnexpectedExpressionInPattern {
+                    span: expr.span,
+                    is_bound,
+                    is_method_call,
+                }));
+            }
+        }
+
+        // We got a trailing method/operator, but we couldn't parse an expression.
+        None
+    }
+
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
     /// allowed).
     fn parse_pat_with_range_pat(
@@ -441,13 +531,17 @@ impl<'a> Parser<'a> {
             } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
                 self.parse_pat_tuple_struct(qself, path)?
             } else {
-                PatKind::Path(qself, path)
+                match self.maybe_recover_trailing_expr(span, false) {
+                    Some(guar) => PatKind::Err(guar),
+                    None => PatKind::Path(qself, path),
+                }
             }
-        } else if matches!(self.token.kind, token::Lifetime(_))
+        } else if let token::Lifetime(lt) = self.token.kind
             // In pattern position, we're totally fine with using "next token isn't colon"
             // as a heuristic. We could probably just always try to recover if it's a lifetime,
             // because we never have `'a: label {}` in a pattern position anyways, but it does
             // keep us from suggesting something like `let 'a: Ty = ..` => `let 'a': Ty = ..`
+            && could_be_unclosed_char_literal(Ident::with_dummy_span(lt))
             && !self.look_ahead(1, |token| matches!(token.kind, token::Colon))
         {
             // Recover a `'a` as a `'a'` literal
@@ -470,10 +564,17 @@ impl<'a> Parser<'a> {
         } else {
             // Try to parse everything else as literal with optional minus
             match self.parse_literal_maybe_minus() {
-                Ok(begin) => match self.parse_range_end() {
-                    Some(form) => self.parse_pat_range_begin_with(begin, form)?,
-                    None => PatKind::Lit(begin),
-                },
+                Ok(begin) => {
+                    let begin = match self.maybe_recover_trailing_expr(begin.span, false) {
+                        Some(_) => self.mk_expr_err(begin.span),
+                        None => begin,
+                    };
+
+                    match self.parse_range_end() {
+                        Some(form) => self.parse_pat_range_begin_with(begin, form)?,
+                        None => PatKind::Lit(begin),
+                    }
+                }
                 Err(err) => return self.fatal_unexpected_non_pat(err, expected),
             }
         };
@@ -615,6 +716,21 @@ impl<'a> Parser<'a> {
 
                     self.parse_pat_range_begin_with(begin.clone(), form)?
                 }
+                // recover ranges with parentheses around the `(start)..`
+                PatKind::Err(_)
+                    if self.may_recover()
+                        && let Some(form) = self.parse_range_end() =>
+                {
+                    self.dcx().emit_err(UnexpectedParenInRangePat {
+                        span: vec![open_paren, close_paren],
+                        sugg: UnexpectedParenInRangePatSugg {
+                            start_span: open_paren,
+                            end_span: close_paren,
+                        },
+                    });
+
+                    self.parse_pat_range_begin_with(self.mk_expr(pat.span, ExprKind::Err), form)?
+                }
 
                 // (pat) with optional parentheses
                 _ => PatKind::Paren(pat),
@@ -853,6 +969,8 @@ impl<'a> Parser<'a> {
             self.parse_literal_maybe_minus()
         }?;
 
+        let recovered = self.maybe_recover_trailing_expr(bound.span, true);
+
         // recover trailing `)`
         if let Some(open_paren) = open_paren {
             self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
@@ -866,7 +984,10 @@ impl<'a> Parser<'a> {
             });
         }
 
-        Ok(bound)
+        Ok(match recovered {
+            Some(_) => self.mk_expr_err(bound.span),
+            None => bound,
+        })
     }
 
     /// Is this the start of a pattern beginning with a path?
@@ -929,7 +1050,17 @@ impl<'a> Parser<'a> {
                 .create_err(EnumPatternInsteadOfIdentifier { span: self.prev_token.span }));
         }
 
-        Ok(PatKind::Ident(binding_annotation, ident, sub))
+        // Check for method calls after the `ident`,
+        // but not `ident @ subpat` as `subpat` was already checked and `ident` continues with `@`.
+
+        let pat = if sub.is_none()
+            && let Some(guar) = self.maybe_recover_trailing_expr(ident.span, false)
+        {
+            PatKind::Err(guar)
+        } else {
+            PatKind::Ident(binding_annotation, ident, sub)
+        };
+        Ok(pat)
     }
 
     /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 625764876a6..d76ee161da6 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -1056,7 +1056,7 @@ fn find_width_map_from_snippet(
 fn unescape_string(string: &str) -> Option<string::String> {
     let mut buf = string::String::new();
     let mut ok = true;
-    unescape::unescape_literal(string, unescape::Mode::Str, &mut |_, unescaped_char| {
+    unescape::unescape_unicode(string, unescape::Mode::Str, &mut |_, unescaped_char| {
         match unescaped_char {
             Ok(c) => buf.push(c),
             Err(_) => ok = false,
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 9d9741bbe89..0f0027db01d 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -5,8 +5,10 @@
 //! item.
 
 use crate::{errors, fluent_generated as fluent};
-use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
+use rustc_ast::{ast, AttrKind, AttrStyle, Attribute, LitKind};
+use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_errors::StashKey;
 use rustc_errors::{Applicability, DiagCtxt, IntoDiagnosticArg, MultiSpan};
 use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir as hir;
@@ -78,7 +80,7 @@ pub(crate) enum ProcMacroKind {
 }
 
 impl IntoDiagnosticArg for ProcMacroKind {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         match self {
             ProcMacroKind::Attribute => "attribute proc macro",
             ProcMacroKind::Derive => "derive proc macro",
@@ -2530,6 +2532,14 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
         if attr.style == AttrStyle::Inner {
             for attr_to_check in ATTRS_TO_CHECK {
                 if attr.has_name(*attr_to_check) {
+                    if let AttrKind::Normal(ref p) = attr.kind
+                        && let Some(diag) = tcx.dcx().steal_diagnostic(
+                            p.item.path.span,
+                            StashKey::UndeterminedMacroResolution,
+                        )
+                    {
+                        diag.cancel();
+                    }
                     let item = tcx
                         .hir()
                         .items()
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d3909ce3a1c..9be28674435 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -917,7 +917,7 @@ impl<'tcx> DeadVisitor<'tcx> {
             return;
         }
         dead_codes.sort_by_key(|v| v.level);
-        for group in dead_codes[..].group_by(|a, b| a.level == b.level) {
+        for group in dead_codes[..].chunk_by(|a, b| a.level == b.level) {
             self.lint_at_single_level(&group, participle, Some(def_id), report_on);
         }
     }
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 25ca685cbfa..97c70e327f0 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,6 +1,6 @@
 use rustc_ast::attr;
 use rustc_ast::entry::EntryPointType;
-use rustc_errors::error_code;
+use rustc_errors::codes::*;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{ItemId, Node, CRATE_HIR_ID};
@@ -180,8 +180,8 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
         Default::default()
     });
     let main_def_opt = tcx.resolutions(()).main_def;
-    let code = error_code!(E0601);
-    let add_teach_note = tcx.sess.teach(&code);
+    let code = E0601;
+    let add_teach_note = tcx.sess.teach(code);
     // The file may be empty, which leads to the diagnostic machinery not emitting this
     // note. This is a relatively simple way to detect that case and emit a span-less
     // note instead.
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index cf3c7cc4ace..77bfe57e370 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -6,7 +6,7 @@ use std::{
 use crate::fluent_generated as fluent;
 use rustc_ast::Label;
 use rustc_errors::{
-    error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
     DiagnosticSymbolList, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan,
 };
 use rustc_hir::{self as hir, ExprKind, Target};
@@ -55,7 +55,7 @@ pub struct IgnoredInlineAttrFnProto;
 pub struct IgnoredInlineAttrConstants;
 
 #[derive(Diagnostic)]
-#[diag(passes_inline_not_fn_or_closure, code = "E0518")]
+#[diag(passes_inline_not_fn_or_closure, code = E0518)]
 pub struct InlineNotFnOrClosure {
     #[primary_span]
     pub attr_span: Span,
@@ -76,7 +76,7 @@ pub struct IgnoredCoveragePropagate;
 pub struct IgnoredCoverageFnDefn;
 
 #[derive(Diagnostic)]
-#[diag(passes_coverage_not_coverable, code = "E0788")]
+#[diag(passes_coverage_not_coverable, code = E0788)]
 pub struct IgnoredCoverageNotCoverable {
     #[primary_span]
     pub attr_span: Span,
@@ -95,14 +95,14 @@ pub struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_tracked_caller, code = "E0736")]
+#[diag(passes_naked_tracked_caller, code = E0736)]
 pub struct NakedTrackedCaller {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_fn, code = "E0739")]
+#[diag(passes_should_be_applied_to_fn, code = E0739)]
 pub struct TrackedCallerWrongLocation {
     #[primary_span]
     pub attr_span: Span,
@@ -112,7 +112,7 @@ pub struct TrackedCallerWrongLocation {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_struct_enum, code = "E0701")]
+#[diag(passes_should_be_applied_to_struct_enum, code = E0701)]
 pub struct NonExhaustiveWrongLocation {
     #[primary_span]
     pub attr_span: Span,
@@ -370,28 +370,28 @@ pub struct HasIncoherentInherentImpl {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_both_ffi_const_and_pure, code = "E0757")]
+#[diag(passes_both_ffi_const_and_pure, code = E0757)]
 pub struct BothFfiConstAndPure {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_ffi_pure_invalid_target, code = "E0755")]
+#[diag(passes_ffi_pure_invalid_target, code = E0755)]
 pub struct FfiPureInvalidTarget {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_ffi_const_invalid_target, code = "E0756")]
+#[diag(passes_ffi_const_invalid_target, code = E0756)]
 pub struct FfiConstInvalidTarget {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_ffi_returns_twice_invalid_target, code = "E0724")]
+#[diag(passes_ffi_returns_twice_invalid_target, code = E0724)]
 pub struct FfiReturnsTwiceInvalidTarget {
     #[primary_span]
     pub attr_span: Span,
@@ -552,21 +552,21 @@ pub struct NoMangle {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_repr_ident, code = "E0565")]
+#[diag(passes_repr_ident, code = E0565)]
 pub struct ReprIdent {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_repr_conflicting, code = "E0566")]
+#[diag(passes_repr_conflicting, code = E0566)]
 pub struct ReprConflicting {
     #[primary_span]
     pub hint_spans: Vec<Span>,
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_repr_conflicting, code = "E0566")]
+#[diag(passes_repr_conflicting, code = E0566)]
 pub struct ReprConflictingLint;
 
 #[derive(Diagnostic)]
@@ -667,7 +667,7 @@ pub(crate) struct EmptyConfusables {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_incorrect_meta_item, code = "E0539")]
+#[diag(passes_incorrect_meta_item, code = E0539)]
 pub(crate) struct IncorrectMetaItem {
     #[primary_span]
     pub span: Span,
@@ -737,7 +737,7 @@ pub struct Unused {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_non_exported_macro_invalid_attrs, code = "E0518")]
+#[diag(passes_non_exported_macro_invalid_attrs, code = E0518)]
 pub struct NonExportedMacroInvalidAttrs {
     #[primary_span]
     #[label]
@@ -801,7 +801,7 @@ pub struct DeprecatedAnnotationHasNoEffect {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unknown_external_lang_item, code = "E0264")]
+#[diag(passes_unknown_external_lang_item, code = E0264)]
 pub struct UnknownExternLangItem {
     #[primary_span]
     pub span: Span,
@@ -837,7 +837,7 @@ pub struct LangItemWithTargetFeature {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_lang_item_on_incorrect_target, code = "E0718")]
+#[diag(passes_lang_item_on_incorrect_target, code = E0718)]
 pub struct LangItemOnIncorrectTarget {
     #[primary_span]
     #[label]
@@ -848,7 +848,7 @@ pub struct LangItemOnIncorrectTarget {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unknown_lang_item, code = "E0522")]
+#[diag(passes_unknown_lang_item, code = E0522)]
 pub struct UnknownLangItem {
     #[primary_span]
     #[label]
@@ -990,7 +990,7 @@ pub struct UnrecognizedField {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_feature_stable_twice, code = "E0711")]
+#[diag(passes_feature_stable_twice, code = E0711)]
 pub struct FeatureStableTwice {
     #[primary_span]
     pub span: Span,
@@ -1000,7 +1000,7 @@ pub struct FeatureStableTwice {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_feature_previously_declared, code = "E0711")]
+#[diag(passes_feature_previously_declared, code = E0711)]
 pub struct FeaturePreviouslyDeclared<'a, 'b> {
     #[primary_span]
     pub span: Span,
@@ -1025,7 +1025,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> {
     fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_break_non_loop);
         diag.span(self.span);
-        diag.code(error_code!(E0571));
+        diag.code(E0571);
         diag.arg("kind", self.kind);
         diag.span_label(self.span, fluent::passes_label);
         if let Some(head) = self.head {
@@ -1063,7 +1063,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_continue_labeled_block, code = "E0696")]
+#[diag(passes_continue_labeled_block, code = E0696)]
 pub struct ContinueLabeledBlock {
     #[primary_span]
     #[label]
@@ -1073,7 +1073,7 @@ pub struct ContinueLabeledBlock {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_break_inside_closure, code = "E0267")]
+#[diag(passes_break_inside_closure, code = E0267)]
 pub struct BreakInsideClosure<'a> {
     #[primary_span]
     #[label]
@@ -1084,7 +1084,7 @@ pub struct BreakInsideClosure<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_break_inside_async_block, code = "E0267")]
+#[diag(passes_break_inside_async_block, code = E0267)]
 pub struct BreakInsideAsyncBlock<'a> {
     #[primary_span]
     #[label]
@@ -1095,7 +1095,7 @@ pub struct BreakInsideAsyncBlock<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_outside_loop, code = "E0268")]
+#[diag(passes_outside_loop, code = E0268)]
 pub struct OutsideLoop<'a> {
     #[primary_span]
     #[label]
@@ -1115,7 +1115,7 @@ pub struct OutsideLoopSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unlabeled_in_labeled_block, code = "E0695")]
+#[diag(passes_unlabeled_in_labeled_block, code = E0695)]
 pub struct UnlabeledInLabeledBlock<'a> {
     #[primary_span]
     #[label]
@@ -1124,7 +1124,7 @@ pub struct UnlabeledInLabeledBlock<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unlabeled_cf_in_while_condition, code = "E0590")]
+#[diag(passes_unlabeled_cf_in_while_condition, code = E0590)]
 pub struct UnlabeledCfInWhileCondition<'a> {
     #[primary_span]
     #[label]
@@ -1169,7 +1169,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for NakedFunctionsAsmBlock {
     fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_naked_functions_asm_block);
         diag.span(self.span);
-        diag.code(error_code!(E0787));
+        diag.code(E0787);
         for span in self.multiple_asms.iter() {
             diag.span_label(*span, fluent::passes_label_multiple_asm);
         }
@@ -1181,14 +1181,14 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for NakedFunctionsAsmBlock {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_operands, code = "E0787")]
+#[diag(passes_naked_functions_operands, code = E0787)]
 pub struct NakedFunctionsOperands {
     #[primary_span]
     pub unsupported_operands: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_asm_options, code = "E0787")]
+#[diag(passes_naked_functions_asm_options, code = E0787)]
 pub struct NakedFunctionsAsmOptions {
     #[primary_span]
     pub span: Span,
@@ -1196,7 +1196,7 @@ pub struct NakedFunctionsAsmOptions {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_must_use_noreturn, code = "E0787")]
+#[diag(passes_naked_functions_must_use_noreturn, code = E0787)]
 pub struct NakedFunctionsMustUseNoreturn {
     #[primary_span]
     pub span: Span,
@@ -1229,7 +1229,7 @@ pub struct AttrOnlyInFunctions {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_multiple_rustc_main, code = "E0137")]
+#[diag(passes_multiple_rustc_main, code = E0137)]
 pub struct MultipleRustcMain {
     #[primary_span]
     pub span: Span,
@@ -1240,7 +1240,7 @@ pub struct MultipleRustcMain {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_multiple_start_functions, code = "E0138")]
+#[diag(passes_multiple_start_functions, code = E0138)]
 pub struct MultipleStartFunctions {
     #[primary_span]
     pub span: Span,
@@ -1280,7 +1280,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for NoMainErr {
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_no_main_function);
         diag.span(DUMMY_SP);
-        diag.code(error_code!(E0601));
+        diag.code(E0601);
         diag.arg("crate_name", self.crate_name);
         diag.arg("filename", self.filename);
         diag.arg("has_filename", self.has_filename);
@@ -1345,7 +1345,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for DuplicateLangItem {
                 Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends,
             },
         );
-        diag.code(error_code!(E0152));
+        diag.code(E0152);
         diag.arg("lang_item_name", self.lang_item_name);
         diag.arg("crate_name", self.crate_name);
         diag.arg("dependency_of", self.dependency_of);
@@ -1382,7 +1382,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for DuplicateLangItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_incorrect_target, code = "E0718")]
+#[diag(passes_incorrect_target, code = E0718)]
 pub struct IncorrectTarget<'a> {
     #[primary_span]
     pub span: Span,
@@ -1418,7 +1418,7 @@ pub struct ObjectLifetimeErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unrecognized_repr_hint, code = "E0552")]
+#[diag(passes_unrecognized_repr_hint, code = E0552)]
 #[help]
 pub struct UnrecognizedReprHint {
     #[primary_span]
@@ -1427,35 +1427,35 @@ pub struct UnrecognizedReprHint {
 
 #[derive(Diagnostic)]
 pub enum AttrApplication {
-    #[diag(passes_attr_application_enum, code = "E0517")]
+    #[diag(passes_attr_application_enum, code = E0517)]
     Enum {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct, code = "E0517")]
+    #[diag(passes_attr_application_struct, code = E0517)]
     Struct {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_union, code = "E0517")]
+    #[diag(passes_attr_application_struct_union, code = E0517)]
     StructUnion {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_enum_union, code = "E0517")]
+    #[diag(passes_attr_application_struct_enum_union, code = E0517)]
     StructEnumUnion {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_enum_function_method_union, code = "E0517")]
+    #[diag(passes_attr_application_struct_enum_function_method_union, code = E0517)]
     StructEnumFunctionMethodUnion {
         #[primary_span]
         hint_span: Span,
@@ -1465,7 +1465,7 @@ pub enum AttrApplication {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_transparent_incompatible, code = "E0692")]
+#[diag(passes_transparent_incompatible, code = E0692)]
 pub struct TransparentIncompatible {
     #[primary_span]
     pub hint_spans: Vec<Span>,
@@ -1473,7 +1473,7 @@ pub struct TransparentIncompatible {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_deprecated_attribute, code = "E0549")]
+#[diag(passes_deprecated_attribute, code = E0549)]
 pub struct DeprecatedAttribute {
     #[primary_span]
     pub span: Span,
@@ -1524,7 +1524,7 @@ pub struct TraitImplConstStable {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_feature_only_on_nightly, code = "E0554")]
+#[diag(passes_feature_only_on_nightly, code = E0554)]
 pub struct FeatureOnlyOnNightly {
     #[primary_span]
     pub span: Span,
@@ -1532,7 +1532,7 @@ pub struct FeatureOnlyOnNightly {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unknown_feature, code = "E0635")]
+#[diag(passes_unknown_feature, code = E0635)]
 pub struct UnknownFeature {
     #[primary_span]
     pub span: Span,
@@ -1549,7 +1549,7 @@ pub struct ImpliedFeatureNotExist {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_duplicate_feature_err, code = "E0636")]
+#[diag(passes_duplicate_feature_err, code = E0636)]
 pub struct DuplicateFeatureErr {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 528a52f4225..e94d8c4c932 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -328,11 +328,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
         hir_visit::walk_expr(self, e)
     }
 
-    fn visit_let_expr(&mut self, lex: &'v hir::Let<'v>) {
-        self.record("Let", Id::Node(lex.hir_id), lex);
-        hir_visit::walk_let_expr(self, lex)
-    }
-
     fn visit_expr_field(&mut self, f: &'v hir::ExprField<'v>) {
         self.record("ExprField", Id::Node(f.hir_id), f);
         hir_visit::walk_expr_field(self, f)
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index bb33a4feb05..862b76b1f60 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,13 +8,10 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
-#![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
-#![feature(slice_group_by)]
 #![feature(try_blocks)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml
index 1d0e1cb7e6a..b9bdcb41929 100644
--- a/compiler/rustc_pattern_analysis/Cargo.toml
+++ b/compiler/rustc_pattern_analysis/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-derivative = "2.2.0"
 rustc-hash = "1.1.0"
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena", optional = true }
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index e94a0373c79..4996015f863 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -151,6 +151,7 @@
 use std::cmp::{self, max, min, Ordering};
 use std::fmt;
 use std::iter::once;
+use std::mem;
 
 use smallvec::SmallVec;
 
@@ -648,8 +649,6 @@ impl OpaqueId {
 /// `specialize_constructor` returns the list of fields corresponding to a pattern, given a
 /// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
 /// `Fields`.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""), PartialEq(bound = ""))]
 pub enum Constructor<Cx: TypeCx> {
     /// Tuples and structs.
     Struct,
@@ -692,6 +691,101 @@ pub enum Constructor<Cx: TypeCx> {
     Missing,
 }
 
+impl<Cx: TypeCx> Clone for Constructor<Cx> {
+    fn clone(&self) -> Self {
+        match self {
+            Constructor::Struct => Constructor::Struct,
+            Constructor::Variant(idx) => Constructor::Variant(idx.clone()),
+            Constructor::Ref => Constructor::Ref,
+            Constructor::Slice(slice) => Constructor::Slice(slice.clone()),
+            Constructor::UnionField => Constructor::UnionField,
+            Constructor::Bool(b) => Constructor::Bool(b.clone()),
+            Constructor::IntRange(range) => Constructor::IntRange(range.clone()),
+            Constructor::F32Range(lo, hi, end) => {
+                Constructor::F32Range(lo.clone(), hi.clone(), end.clone())
+            }
+            Constructor::F64Range(lo, hi, end) => {
+                Constructor::F64Range(lo.clone(), hi.clone(), end.clone())
+            }
+            Constructor::Str(value) => Constructor::Str(value.clone()),
+            Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
+            Constructor::Or => Constructor::Or,
+            Constructor::Wildcard => Constructor::Wildcard,
+            Constructor::NonExhaustive => Constructor::NonExhaustive,
+            Constructor::Hidden => Constructor::Hidden,
+            Constructor::Missing => Constructor::Missing,
+        }
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for Constructor<Cx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Constructor::Struct => f.debug_tuple("Struct").finish(),
+            Constructor::Variant(idx) => f.debug_tuple("Variant").field(idx).finish(),
+            Constructor::Ref => f.debug_tuple("Ref").finish(),
+            Constructor::Slice(slice) => f.debug_tuple("Slice").field(slice).finish(),
+            Constructor::UnionField => f.debug_tuple("UnionField").finish(),
+            Constructor::Bool(b) => f.debug_tuple("Bool").field(b).finish(),
+            Constructor::IntRange(range) => f.debug_tuple("IntRange").field(range).finish(),
+            Constructor::F32Range(lo, hi, end) => {
+                f.debug_tuple("F32Range").field(lo).field(hi).field(end).finish()
+            }
+            Constructor::F64Range(lo, hi, end) => {
+                f.debug_tuple("F64Range").field(lo).field(hi).field(end).finish()
+            }
+            Constructor::Str(value) => f.debug_tuple("Str").field(value).finish(),
+            Constructor::Opaque(inner) => f.debug_tuple("Opaque").field(inner).finish(),
+            Constructor::Or => f.debug_tuple("Or").finish(),
+            Constructor::Wildcard => f.debug_tuple("Wildcard").finish(),
+            Constructor::NonExhaustive => f.debug_tuple("NonExhaustive").finish(),
+            Constructor::Hidden => f.debug_tuple("Hidden").finish(),
+            Constructor::Missing => f.debug_tuple("Missing").finish(),
+        }
+    }
+}
+
+impl<Cx: TypeCx> PartialEq for Constructor<Cx> {
+    fn eq(&self, other: &Self) -> bool {
+        (mem::discriminant(self) == mem::discriminant(other))
+            && match (self, other) {
+                (Constructor::Struct, Constructor::Struct) => true,
+                (Constructor::Variant(self_variant), Constructor::Variant(other_variant)) => {
+                    self_variant == other_variant
+                }
+                (Constructor::Ref, Constructor::Ref) => true,
+                (Constructor::Slice(self_slice), Constructor::Slice(other_slice)) => {
+                    self_slice == other_slice
+                }
+                (Constructor::UnionField, Constructor::UnionField) => true,
+                (Constructor::Bool(self_b), Constructor::Bool(other_b)) => self_b == other_b,
+                (Constructor::IntRange(self_range), Constructor::IntRange(other_range)) => {
+                    self_range == other_range
+                }
+                (
+                    Constructor::F32Range(self_lo, self_hi, self_end),
+                    Constructor::F32Range(other_lo, other_hi, other_end),
+                ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
+                (
+                    Constructor::F64Range(self_lo, self_hi, self_end),
+                    Constructor::F64Range(other_lo, other_hi, other_end),
+                ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
+                (Constructor::Str(self_value), Constructor::Str(other_value)) => {
+                    self_value == other_value
+                }
+                (Constructor::Opaque(self_inner), Constructor::Opaque(other_inner)) => {
+                    self_inner == other_inner
+                }
+                (Constructor::Or, Constructor::Or) => true,
+                (Constructor::Wildcard, Constructor::Wildcard) => true,
+                (Constructor::NonExhaustive, Constructor::NonExhaustive) => true,
+                (Constructor::Hidden, Constructor::Hidden) => true,
+                (Constructor::Missing, Constructor::Missing) => true,
+                _ => unreachable!(),
+            }
+    }
+}
+
 impl<Cx: TypeCx> Constructor<Cx> {
     pub(crate) fn is_non_exhaustive(&self) -> bool {
         matches!(self, NonExhaustive)
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index a55d53dfdac..a53d7a0d809 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -95,6 +95,7 @@ pub trait TypeCx: Sized + fmt::Debug {
     type PatData: Clone;
 
     fn is_exhaustive_patterns_feature_on(&self) -> bool;
+    fn is_min_exhaustive_patterns_feature_on(&self) -> bool;
 
     /// The number of fields for this constructor.
     fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize;
@@ -135,23 +136,35 @@ pub trait TypeCx: Sized + fmt::Debug {
 }
 
 /// Context that provides information global to a match.
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""), Copy(bound = ""))]
 pub struct MatchCtxt<'a, Cx: TypeCx> {
     /// The context for type information.
     pub tycx: &'a Cx,
 }
 
+impl<'a, Cx: TypeCx> Clone for MatchCtxt<'a, Cx> {
+    fn clone(&self) -> Self {
+        Self { tycx: self.tycx }
+    }
+}
+
+impl<'a, Cx: TypeCx> Copy for MatchCtxt<'a, Cx> {}
+
 /// The arm of a match expression.
 #[derive(Debug)]
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""), Copy(bound = ""))]
 pub struct MatchArm<'p, Cx: TypeCx> {
     pub pat: &'p DeconstructedPat<'p, Cx>,
     pub has_guard: bool,
     pub arm_data: Cx::ArmData,
 }
 
+impl<'p, Cx: TypeCx> Clone for MatchArm<'p, Cx> {
+    fn clone(&self) -> Self {
+        Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data }
+    }
+}
+
+impl<'p, Cx: TypeCx> Copy for MatchArm<'p, Cx> {}
+
 /// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are
 /// useful, and runs some lints.
 #[cfg(feature = "rustc")]
diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs
index 1cc31074556..d476766d466 100644
--- a/compiler/rustc_pattern_analysis/src/pat.rs
+++ b/compiler/rustc_pattern_analysis/src/pat.rs
@@ -218,8 +218,6 @@ impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
 /// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input.
 ///
 /// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard.
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""), Copy(bound = ""))]
 pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
     /// A non-user-provided wildcard, created during specialization.
     Wild,
@@ -227,6 +225,17 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
     Pat(&'p DeconstructedPat<'p, Cx>),
 }
 
+impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
+    fn clone(&self) -> Self {
+        match self {
+            PatOrWild::Wild => PatOrWild::Wild,
+            PatOrWild::Pat(pat) => PatOrWild::Pat(pat),
+        }
+    }
+}
+
+impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {}
+
 impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
     pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
         match self {
@@ -289,14 +298,28 @@ impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> {
 
 /// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
 /// purposes. As such they don't use interning and can be cloned.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""))]
 pub struct WitnessPat<Cx: TypeCx> {
     ctor: Constructor<Cx>,
     pub(crate) fields: Vec<WitnessPat<Cx>>,
     ty: Cx::Ty,
 }
 
+impl<Cx: TypeCx> Clone for WitnessPat<Cx> {
+    fn clone(&self) -> Self {
+        Self { ctor: self.ctor.clone(), fields: self.fields.clone(), ty: self.ty.clone() }
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for WitnessPat<Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_struct("WitnessPat")
+            .field("ctor", &self.ctor)
+            .field("fields", &self.fields)
+            .field("ty", &self.ty)
+            .finish()
+    }
+}
+
 impl<Cx: TypeCx> WitnessPat<Cx> {
     pub(crate) fn new(ctor: Constructor<Cx>, fields: Vec<Self>, ty: Cx::Ty) -> Self {
         Self { ctor, fields, ty }
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 23cab5f43ab..223d6cefc83 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -46,11 +46,15 @@ pub type WitnessPat<'p, 'tcx> = crate::pat::WitnessPat<RustcMatchCheckCtxt<'p, '
 ///
 /// Use `.inner()` or deref to get to the `Ty<'tcx>`.
 #[repr(transparent)]
-#[derive(derivative::Derivative)]
 #[derive(Clone, Copy)]
-#[derivative(Debug = "transparent")]
 pub struct RevealedTy<'tcx>(Ty<'tcx>);
 
+impl<'tcx> fmt::Debug for RevealedTy<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(fmt)
+    }
+}
+
 impl<'tcx> std::ops::Deref for RevealedTy<'tcx> {
     type Target = Ty<'tcx>;
     fn deref(&self) -> &Self::Target {
@@ -181,7 +185,9 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
             // `field.ty()` doesn't normalize after substituting.
             let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
             let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
-            let is_uninhabited = cx.tcx.features().exhaustive_patterns && cx.is_uninhabited(ty);
+            let is_uninhabited = (cx.tcx.features().exhaustive_patterns
+                || cx.tcx.features().min_exhaustive_patterns)
+                && cx.is_uninhabited(ty);
 
             if is_uninhabited && (!is_visible || is_non_exhaustive) {
                 None
@@ -863,6 +869,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
     fn is_exhaustive_patterns_feature_on(&self) -> bool {
         self.tcx.features().exhaustive_patterns
     }
+    fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
+        self.tcx.features().min_exhaustive_patterns
+    }
 
     fn ctor_arity(&self, ctor: &crate::constructor::Constructor<Self>, ty: &Self::Ty) -> usize {
         self.ctor_arity(ctor, *ty)
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index 0de48c9f3c0..b15de1c0ca9 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -548,11 +548,12 @@
 //! [`ValidityConstraint::specialize`].
 //!
 //! Having said all that, in practice we don't fully follow what's been presented in this section.
-//! Under `exhaustive_patterns`, we allow omitting empty arms even in `!known_valid` places, for
-//! backwards-compatibility until we have a better alternative. Without `exhaustive_patterns`, we
-//! mostly treat empty types as inhabited, except specifically a non-nested `!` or empty enum. In
-//! this specific case we also allow the empty match regardless of place validity, for
-//! backwards-compatibility. Hopefully we can eventually deprecate this.
+//! Let's call "toplevel exception" the case where the match scrutinee itself has type `!` or
+//! `EmptyEnum`. First, on stable rust, we require `_` patterns for empty types in all cases apart
+//! from the toplevel exception. The `exhaustive_patterns` and `min_exaustive_patterns` allow
+//! omitting patterns in the cases described above. There's a final detail: in the toplevel
+//! exception or with the `exhaustive_patterns` feature, we ignore place validity when checking
+//! whether a pattern is required for exhaustiveness. I (Nadrieril) hope to deprecate this behavior.
 //!
 //!
 //!
@@ -730,16 +731,26 @@ pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
 }
 
 /// Context that provides information local to a place under investigation.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""), Copy(bound = ""))]
 pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
-    #[derivative(Debug = "ignore")]
     pub(crate) mcx: MatchCtxt<'a, Cx>,
     /// Type of the place under investigation.
-    #[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90
     pub(crate) ty: &'a Cx::Ty,
 }
 
+impl<'a, Cx: TypeCx> Clone for PlaceCtxt<'a, Cx> {
+    fn clone(&self) -> Self {
+        Self { mcx: self.mcx, ty: self.ty }
+    }
+}
+
+impl<'a, Cx: TypeCx> Copy for PlaceCtxt<'a, Cx> {}
+
+impl<'a, Cx: TypeCx> fmt::Debug for PlaceCtxt<'a, Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_struct("PlaceCtxt").field("ty", self.ty).finish()
+    }
+}
+
 impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
     /// A `PlaceCtxt` when code other than `is_useful` needs one.
     #[cfg_attr(not(feature = "rustc"), allow(dead_code))]
@@ -812,8 +823,6 @@ impl fmt::Display for ValidityConstraint {
 // The three lifetimes are:
 // - 'p coming from the input
 // - Cx global compilation context
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""))]
 struct PatStack<'p, Cx: TypeCx> {
     // Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
     pats: SmallVec<[PatOrWild<'p, Cx>; 2]>,
@@ -823,6 +832,12 @@ struct PatStack<'p, Cx: TypeCx> {
     relevant: bool,
 }
 
+impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> {
+    fn clone(&self) -> Self {
+        Self { pats: self.pats.clone(), relevant: self.relevant }
+    }
+}
+
 impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
     fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
         PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
@@ -1183,10 +1198,20 @@ impl<'p, Cx: TypeCx> fmt::Debug for Matrix<'p, Cx> {
 /// The final `Pair(Some(_), true)` is then the resulting witness.
 ///
 /// See the top of the file for more detailed explanations and examples.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""))]
 struct WitnessStack<Cx: TypeCx>(Vec<WitnessPat<Cx>>);
 
+impl<Cx: TypeCx> Clone for WitnessStack<Cx> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for WitnessStack<Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_tuple("WitnessStack").field(&self.0).finish()
+    }
+}
+
 impl<Cx: TypeCx> WitnessStack<Cx> {
     /// Asserts that the witness contains a single pattern, and returns it.
     fn single_pattern(self) -> WitnessPat<Cx> {
@@ -1231,18 +1256,28 @@ impl<Cx: TypeCx> WitnessStack<Cx> {
 ///
 /// Just as the `Matrix` starts with a single column, by the end of the algorithm, this has a single
 /// column, which contains the patterns that are missing for the match to be exhaustive.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""))]
 struct WitnessMatrix<Cx: TypeCx>(Vec<WitnessStack<Cx>>);
 
+impl<Cx: TypeCx> Clone for WitnessMatrix<Cx> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for WitnessMatrix<Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_tuple("WitnessMatrix").field(&self.0).finish()
+    }
+}
+
 impl<Cx: TypeCx> WitnessMatrix<Cx> {
     /// New matrix with no witnesses.
     fn empty() -> Self {
-        WitnessMatrix(vec![])
+        WitnessMatrix(Vec::new())
     }
     /// New matrix with one `()` witness, i.e. with no columns.
     fn unit_witness() -> Self {
-        WitnessMatrix(vec![WitnessStack(vec![])])
+        WitnessMatrix(vec![WitnessStack(Vec::new())])
     }
 
     /// Whether this has any witnesses.
@@ -1442,10 +1477,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
     // We treat match scrutinees of type `!` or `EmptyEnum` differently.
     let is_toplevel_exception =
         is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
-    // Whether empty patterns can be omitted for exhaustiveness.
-    let can_omit_empty_arms = is_toplevel_exception || mcx.tycx.is_exhaustive_patterns_feature_on();
-    // Whether empty patterns are counted as useful or not.
-    let empty_arms_are_unreachable = place_validity.is_known_valid() && can_omit_empty_arms;
+    // Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
+    // it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
+    let empty_arms_are_unreachable = place_validity.is_known_valid()
+        && (is_toplevel_exception
+            || mcx.tycx.is_exhaustive_patterns_feature_on()
+            || mcx.tycx.is_min_exhaustive_patterns_feature_on());
+    // Whether empty patterns can be omitted for exhaustiveness. We ignore place validity in the
+    // toplevel exception and `exhaustive_patterns` cases for backwards compatibility.
+    let can_omit_empty_arms = empty_arms_are_unreachable
+        || is_toplevel_exception
+        || mcx.tycx.is_exhaustive_patterns_feature_on();
 
     // Analyze the constructors present in this column.
     let ctors = matrix.heads().map(|p| p.ctor());
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index b1242f82f4f..01c6d18c0e1 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -1,9 +1,9 @@
-use rustc_errors::DiagnosticArgFromDisplay;
+use rustc_errors::{codes::*, DiagnosticArgFromDisplay};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
-#[diag(privacy_field_is_private, code = "E0451")]
+#[diag(privacy_field_is_private, code = E0451)]
 pub struct FieldIsPrivate {
     #[primary_span]
     pub span: Span,
@@ -48,7 +48,7 @@ pub struct UnnamedItemIsPrivate {
 }
 
 #[derive(Diagnostic)]
-#[diag(privacy_in_public_interface, code = "E0446")]
+#[diag(privacy_in_public_interface, code = E0446)]
 pub struct InPublicInterface<'a> {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index ae10695fae4..a64b06e70d6 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -3,10 +3,8 @@
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
 #![feature(associated_type_defaults)]
-#![feature(rustc_private)]
 #![feature(try_blocks)]
 #![feature(let_chains)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
@@ -24,7 +22,6 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, PatKind};
-use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::GenericArgs;
@@ -36,9 +33,9 @@ use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 
+use std::fmt;
 use std::marker::PhantomData;
 use std::ops::ControlFlow;
-use std::{fmt, mem};
 
 use errors::{
     FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
@@ -935,7 +932,6 @@ impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
 struct NamePrivacyVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
-    current_item: LocalDefId,
 }
 
 impl<'tcx> NamePrivacyVisitor<'tcx> {
@@ -951,6 +947,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
     // Checks that a field in a struct constructor (expression or pattern) is accessible.
     fn check_field(
         &mut self,
+        hir_id: hir::HirId,    // ID of the field use
         use_ctxt: Span,        // syntax context of the field name at the use site
         span: Span,            // span of the field pattern, e.g., `x: 0`
         def: ty::AdtDef<'tcx>, // definition of the struct or enum
@@ -963,7 +960,6 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
 
         // definition of the field
         let ident = Ident::new(kw::Empty, use_ctxt);
-        let hir_id = self.tcx.local_def_id_to_hir_id(self.current_item);
         let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1;
         if !field.vis.is_accessible_from(def_id, self.tcx) {
             self.tcx.dcx().emit_err(FieldIsPrivate {
@@ -982,33 +978,13 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
 }
 
 impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
-    type NestedFilter = nested_filter::All;
-
-    /// We want to visit items in the context of their containing
-    /// module and so forth, so supply a crate for doing a deep walk.
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.tcx.hir()
-    }
-
-    fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
-        // Don't visit nested modules, since we run a separate visitor walk
-        // for each module in `effective_visibilities`
-    }
-
-    fn visit_nested_body(&mut self, body: hir::BodyId) {
+    fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         let old_maybe_typeck_results =
-            self.maybe_typeck_results.replace(self.tcx.typeck_body(body));
-        let body = self.tcx.hir().body(body);
-        self.visit_body(body);
+            self.maybe_typeck_results.replace(self.tcx.typeck_body(body_id));
+        self.visit_body(self.tcx.hir().body(body_id));
         self.maybe_typeck_results = old_maybe_typeck_results;
     }
 
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        let orig_current_item = mem::replace(&mut self.current_item, item.owner_id.def_id);
-        intravisit::walk_item(self, item);
-        self.current_item = orig_current_item;
-    }
-
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Struct(qpath, fields, ref base) = expr.kind {
             let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
@@ -1022,17 +998,17 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
                     let field = fields
                         .iter()
                         .find(|f| self.typeck_results().field_index(f.hir_id) == vf_index);
-                    let (use_ctxt, span) = match field {
-                        Some(field) => (field.ident.span, field.span),
-                        None => (base.span, base.span),
+                    let (hir_id, use_ctxt, span) = match field {
+                        Some(field) => (field.hir_id, field.ident.span, field.span),
+                        None => (base.hir_id, base.span, base.span),
                     };
-                    self.check_field(use_ctxt, span, adt, variant_field, true);
+                    self.check_field(hir_id, use_ctxt, span, adt, variant_field, true);
                 }
             } else {
                 for field in fields {
-                    let use_ctxt = field.ident.span;
+                    let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
                     let index = self.typeck_results().field_index(field.hir_id);
-                    self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
+                    self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false);
                 }
             }
         }
@@ -1046,9 +1022,9 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
             let adt = self.typeck_results().pat_ty(pat).ty_adt_def().unwrap();
             let variant = adt.variant_of_res(res);
             for field in fields {
-                let use_ctxt = field.ident.span;
+                let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
                 let index = self.typeck_results().field_index(field.hir_id);
-                self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
+                self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false);
             }
         }
 
@@ -1743,17 +1719,12 @@ pub fn provide(providers: &mut Providers) {
 
 fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     // Check privacy of names not checked in previous compilation stages.
-    let mut visitor = NamePrivacyVisitor {
-        tcx,
-        maybe_typeck_results: None,
-        current_item: module_def_id.to_local_def_id(),
-    };
-    let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
-
-    intravisit::walk_mod(&mut visitor, module, hir_id);
+    let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_results: None };
+    tcx.hir().visit_item_likes_in_module(module_def_id, &mut visitor);
 
     // Check privacy of explicitly written types and traits as well as
     // inferred types of expressions and patterns.
+    let span = tcx.def_span(module_def_id);
     let mut visitor = TypePrivacyVisitor { tcx, module_def_id, maybe_typeck_results: None, span };
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut visitor);
 }
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index b5e8ac4018d..818a67a7deb 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -4,9 +4,7 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![feature(min_specialization)]
-#![feature(never_type)]
 #![feature(rustc_attrs)]
-#![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability, unused_parens)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs
index 5829e17ec16..9db6fac8036 100644
--- a/compiler/rustc_query_system/src/error.rs
+++ b/compiler/rustc_query_system/src/error.rs
@@ -1,3 +1,4 @@
+use rustc_errors::codes::*;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::Limit;
 use rustc_span::{Span, Symbol};
@@ -45,7 +46,7 @@ pub struct CycleUsage {
 }
 
 #[derive(Diagnostic)]
-#[diag(query_system_cycle, code = "E0391")]
+#[diag(query_system_cycle, code = E0391)]
 pub struct Cycle {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
index a1a353ce057..b6ae54010c2 100644
--- a/compiler/rustc_resolve/Cargo.toml
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2021"
 [dependencies]
 # tidy-alphabetical-start
 bitflags = "2.4.1"
-pulldown-cmark = { version = "0.9.3", default-features = false }
+pulldown-cmark = { version = "0.9.6", default-features = false }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index b855ec8f920..7eb7c8c2bca 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -19,7 +19,7 @@ use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
 use rustc_ast::{Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId};
 use rustc_attr as attr;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{struct_span_code_err, Applicability};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability};
 use rustc_expand::expand::AstFragment;
 use rustc_hir::def::{self, *};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index b77102c085c..42ace9bb22f 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -289,12 +289,18 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
                 // we must create two defs.
                 let closure_def = self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span);
                 match closure.coroutine_kind {
-                    Some(coroutine_kind) => self.create_def(
-                        coroutine_kind.closure_id(),
-                        kw::Empty,
-                        DefKind::Closure,
-                        expr.span,
-                    ),
+                    Some(coroutine_kind) => {
+                        self.with_parent(closure_def, |this| {
+                            let coroutine_def = this.create_def(
+                                coroutine_kind.closure_id(),
+                                kw::Empty,
+                                DefKind::Closure,
+                                expr.span,
+                            );
+                            this.with_parent(coroutine_def, |this| visit::walk_expr(this, expr));
+                        });
+                        return;
+                    }
                     None => closure_def,
                 }
             }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 66dfee6c062..f3a6eb65a72 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -6,8 +6,8 @@ use rustc_ast::{MetaItemKind, NestedMetaItem};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt, Diagnostic,
-    DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle,
+    codes::*, pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt,
+    Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle,
 };
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 821b1e946f3..50ff09feb4d 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -1,3 +1,4 @@
+use rustc_errors::codes::*;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{
     symbol::{Ident, Symbol},
@@ -7,16 +8,16 @@ use rustc_span::{
 use crate::{late::PatternSource, Res};
 
 #[derive(Diagnostic)]
-#[diag(resolve_parent_module_reset_for_binding, code = "E0637")]
+#[diag(resolve_parent_module_reset_for_binding, code = E0637)]
 pub(crate) struct ParentModuleResetForBinding;
 
 #[derive(Diagnostic)]
-#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = "E0637")]
+#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = E0637)]
 #[note]
 pub(crate) struct AmpersandUsedWithoutExplicitLifetimeName(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
-#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = "E0637")]
+#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = E0637)]
 #[note]
 pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(crate) Span);
 
@@ -33,7 +34,7 @@ pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate)
 pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
-#[diag(resolve_generic_params_from_outer_item, code = "E0401")]
+#[diag(resolve_generic_params_from_outer_item, code = E0401)]
 pub(crate) struct GenericParamsFromOuterItem {
     #[primary_span]
     #[label]
@@ -67,7 +68,7 @@ pub(crate) struct GenericParamsFromOuterItemSugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")]
+#[diag(resolve_name_is_already_used_as_generic_parameter, code = E0403)]
 pub(crate) struct NameAlreadyUsedInParameterList {
     #[primary_span]
     #[label]
@@ -78,7 +79,7 @@ pub(crate) struct NameAlreadyUsedInParameterList {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_method_not_member_of_trait, code = "E0407")]
+#[diag(resolve_method_not_member_of_trait, code = E0407)]
 pub(crate) struct MethodNotMemberOfTrait {
     #[primary_span]
     #[label]
@@ -102,7 +103,7 @@ pub(crate) struct AssociatedFnWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_type_not_member_of_trait, code = "E0437")]
+#[diag(resolve_type_not_member_of_trait, code = E0437)]
 pub(crate) struct TypeNotMemberOfTrait {
     #[primary_span]
     #[label]
@@ -126,7 +127,7 @@ pub(crate) struct AssociatedTypeWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_const_not_member_of_trait, code = "E0438")]
+#[diag(resolve_const_not_member_of_trait, code = E0438)]
 pub(crate) struct ConstNotMemberOfTrait {
     #[primary_span]
     #[label]
@@ -150,7 +151,7 @@ pub(crate) struct AssociatedConstWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_variable_bound_with_different_mode, code = "E0409")]
+#[diag(resolve_variable_bound_with_different_mode, code = E0409)]
 pub(crate) struct VariableBoundWithDifferentMode {
     #[primary_span]
     #[label]
@@ -161,7 +162,7 @@ pub(crate) struct VariableBoundWithDifferentMode {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = "E0415")]
+#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = E0415)]
 pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
     #[primary_span]
     #[label]
@@ -170,7 +171,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = "E0416")]
+#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = E0416)]
 pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
     #[primary_span]
     #[label]
@@ -179,7 +180,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_undeclared_label, code = "E0426")]
+#[diag(resolve_undeclared_label, code = E0426)]
 pub(crate) struct UndeclaredLabel {
     #[primary_span]
     #[label]
@@ -217,7 +218,7 @@ pub(crate) struct UnreachableLabelWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = "E0430")]
+#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = E0430)]
 pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
     #[primary_span]
     #[label]
@@ -225,7 +226,7 @@ pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = "E0431")]
+#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = E0431)]
 pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
     #[primary_span]
     #[label]
@@ -233,7 +234,7 @@ pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = "E0434")]
+#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = E0434)]
 #[help]
 pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
     #[primary_span]
@@ -241,7 +242,7 @@ pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = "E0435")]
+#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = E0435)]
 pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
     #[primary_span]
     pub(crate) span: Span,
@@ -283,7 +284,7 @@ pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_imports_only_allowed_within, code = "E0429")]
+#[diag(resolve_self_imports_only_allowed_within, code = E0429)]
 pub(crate) struct SelfImportsOnlyAllowedWithin {
     #[primary_span]
     pub(crate) span: Span,
@@ -317,7 +318,7 @@ pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_binding_shadows_something_unacceptable, code = "E0530")]
+#[diag(resolve_binding_shadows_something_unacceptable, code = E0530)]
 pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
     #[primary_span]
     #[label]
@@ -346,7 +347,7 @@ pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_forward_declared_generic_param, code = "E0128")]
+#[diag(resolve_forward_declared_generic_param, code = E0128)]
 pub(crate) struct ForwardDeclaredGenericParam {
     #[primary_span]
     #[label]
@@ -354,7 +355,7 @@ pub(crate) struct ForwardDeclaredGenericParam {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_param_in_ty_of_const_param, code = "E0770")]
+#[diag(resolve_param_in_ty_of_const_param, code = E0770)]
 pub(crate) struct ParamInTyOfConstParam {
     #[primary_span]
     #[label]
@@ -376,7 +377,7 @@ pub(crate) enum ParamKindInTyOfConstParam {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_in_generic_param_default, code = "E0735")]
+#[diag(resolve_self_in_generic_param_default, code = E0735)]
 pub(crate) struct SelfInGenericParamDefault {
     #[primary_span]
     #[label]
@@ -412,7 +413,7 @@ pub(crate) enum ParamKindInNonTrivialAnonConst {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_unreachable_label, code = "E0767")]
+#[diag(resolve_unreachable_label, code = E0767)]
 #[note]
 pub(crate) struct UnreachableLabel {
     #[primary_span]
@@ -456,7 +457,7 @@ pub(crate) struct UnreachableLabelSubLabelUnreachable {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_trait_impl_mismatch, code = "{code}")]
+#[diag(resolve_trait_impl_mismatch)]
 pub(crate) struct TraitImplMismatch {
     #[primary_span]
     #[label]
@@ -466,7 +467,6 @@ pub(crate) struct TraitImplMismatch {
     #[label(resolve_label_trait_item)]
     pub(crate) trait_item_span: Span,
     pub(crate) trait_path: String,
-    pub(crate) code: String,
 }
 
 #[derive(Diagnostic)]
@@ -496,7 +496,7 @@ pub(crate) struct BindingInNeverPattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_trait_impl_duplicate, code = "E0201")]
+#[diag(resolve_trait_impl_duplicate, code = E0201)]
 pub(crate) struct TraitImplDuplicate {
     #[primary_span]
     #[label]
@@ -519,11 +519,11 @@ pub(crate) struct Relative2018 {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_ancestor_only, code = "E0742")]
+#[diag(resolve_ancestor_only, code = E0742)]
 pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
-#[diag(resolve_expected_found, code = "E0577")]
+#[diag(resolve_expected_found, code = E0577)]
 pub(crate) struct ExpectedFound {
     #[primary_span]
     #[label]
@@ -533,7 +533,7 @@ pub(crate) struct ExpectedFound {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_indeterminate, code = "E0578")]
+#[diag(resolve_indeterminate, code = E0578)]
 pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
@@ -715,7 +715,7 @@ pub(crate) struct CannotDetermineMacroResolution {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_private, code = "E0364")]
+#[diag(resolve_cannot_be_reexported_private, code = E0364)]
 pub(crate) struct CannotBeReexportedPrivate {
     #[primary_span]
     pub(crate) span: Span,
@@ -723,7 +723,7 @@ pub(crate) struct CannotBeReexportedPrivate {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_crate_public, code = "E0364")]
+#[diag(resolve_cannot_be_reexported_crate_public, code = E0364)]
 pub(crate) struct CannotBeReexportedCratePublic {
     #[primary_span]
     pub(crate) span: Span,
@@ -731,7 +731,7 @@ pub(crate) struct CannotBeReexportedCratePublic {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_private, code = "E0365")]
+#[diag(resolve_cannot_be_reexported_private, code = E0365)]
 #[note(resolve_consider_declaring_with_pub)]
 pub(crate) struct CannotBeReexportedPrivateNS {
     #[primary_span]
@@ -741,7 +741,7 @@ pub(crate) struct CannotBeReexportedPrivateNS {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_crate_public, code = "E0365")]
+#[diag(resolve_cannot_be_reexported_crate_public, code = E0365)]
 #[note(resolve_consider_declaring_with_pub)]
 pub(crate) struct CannotBeReexportedCratePublicNS {
     #[primary_span]
@@ -780,7 +780,7 @@ pub(crate) struct ItemsInTraitsAreNotImportable {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_is_not_directly_importable, code = "E0253")]
+#[diag(resolve_is_not_directly_importable, code = E0253)]
 pub(crate) struct IsNotDirectlyImportable {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index ad60caed354..30fb35238c3 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -17,7 +17,7 @@ use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult};
 use rustc_ast::NodeId;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::intern::Interned;
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan};
 use rustc_hir::def::{self, DefKind, PartialRes};
 use rustc_middle::metadata::ModChild;
 use rustc_middle::metadata::Reexport;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index abd724a6cc2..9788fcb3c7d 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -16,7 +16,9 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
 use rustc_ast::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
-use rustc_errors::{Applicability, DiagnosticArgValue, IntoDiagnosticArg};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, DiagnosticArgValue, ErrCode, IntoDiagnosticArg,
+};
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -88,7 +90,7 @@ impl PatternSource {
 }
 
 impl IntoDiagnosticArg for PatternSource {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
     }
 }
@@ -533,21 +535,20 @@ impl<'a> PathSource<'a> {
         }
     }
 
-    fn error_code(self, has_unexpected_resolution: bool) -> String {
-        use rustc_errors::error_code;
+    fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {
         match (self, has_unexpected_resolution) {
-            (PathSource::Trait(_), true) => error_code!(E0404),
-            (PathSource::Trait(_), false) => error_code!(E0405),
-            (PathSource::Type, true) => error_code!(E0573),
-            (PathSource::Type, false) => error_code!(E0412),
-            (PathSource::Struct, true) => error_code!(E0574),
-            (PathSource::Struct, false) => error_code!(E0422),
-            (PathSource::Expr(..), true) | (PathSource::Delegation, true) => error_code!(E0423),
-            (PathSource::Expr(..), false) | (PathSource::Delegation, false) => error_code!(E0425),
-            (PathSource::Pat | PathSource::TupleStruct(..), true) => error_code!(E0532),
-            (PathSource::Pat | PathSource::TupleStruct(..), false) => error_code!(E0531),
-            (PathSource::TraitItem(..), true) => error_code!(E0575),
-            (PathSource::TraitItem(..), false) => error_code!(E0576),
+            (PathSource::Trait(_), true) => E0404,
+            (PathSource::Trait(_), false) => E0405,
+            (PathSource::Type, true) => E0573,
+            (PathSource::Type, false) => E0412,
+            (PathSource::Struct, true) => E0574,
+            (PathSource::Struct, false) => E0422,
+            (PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
+            (PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425,
+            (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,
+            (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
+            (PathSource::TraitItem(..), true) => E0575,
+            (PathSource::TraitItem(..), false) => E0576,
         }
     }
 }
@@ -1673,13 +1674,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     } else {
                         ("`'_` cannot be used here", "`'_` is a reserved lifetime name")
                     };
-                    let mut diag = rustc_errors::struct_span_code_err!(
-                        self.r.dcx(),
-                        lifetime.ident.span,
-                        E0637,
-                        "{}",
-                        msg,
-                    );
+                    let mut diag =
+                        struct_span_code_err!(self.r.dcx(), lifetime.ident.span, E0637, "{}", msg,);
                     diag.span_label(lifetime.ident.span, note);
                     if elided {
                         for rib in self.lifetime_ribs[i..].iter().rev() {
@@ -1863,7 +1859,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
                     | LifetimeRibKind::AnonymousWarn(_) => {
                         let sess = self.r.tcx.sess;
-                        let mut err = rustc_errors::struct_span_code_err!(
+                        let mut err = struct_span_code_err!(
                             sess.dcx(),
                             path_span,
                             E0726,
@@ -2608,7 +2604,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
 
             if param.ident.name == kw::UnderscoreLifetime {
-                rustc_errors::struct_span_code_err!(
+                struct_span_code_err!(
                     self.r.dcx(),
                     param.ident.span,
                     E0637,
@@ -2622,7 +2618,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
 
             if param.ident.name == kw::StaticLifetime {
-                rustc_errors::struct_span_code_err!(
+                struct_span_code_err!(
                     self.r.dcx(),
                     param.ident.span,
                     E0262,
@@ -3164,10 +3160,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // The method kind does not correspond to what appeared in the trait, report.
         let path = &self.current_trait_ref.as_ref().unwrap().1.path;
         let (code, kind) = match kind {
-            AssocItemKind::Const(..) => (rustc_errors::error_code!(E0323), "const"),
-            AssocItemKind::Fn(..) => (rustc_errors::error_code!(E0324), "method"),
-            AssocItemKind::Type(..) => (rustc_errors::error_code!(E0325), "type"),
-            AssocItemKind::Delegation(..) => (rustc_errors::error_code!(E0324), "method"),
+            AssocItemKind::Const(..) => (E0323, "const"),
+            AssocItemKind::Fn(..) => (E0324, "method"),
+            AssocItemKind::Type(..) => (E0325, "type"),
+            AssocItemKind::Delegation(..) => (E0324, "method"),
             AssocItemKind::MacCall(..) => span_bug!(span, "unexpanded macro"),
         };
         let trait_path = path_names_to_string(path);
@@ -4424,35 +4420,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             ExprKind::Type(ref _type_expr, ref _ty) => {
                 visit::walk_expr(self, expr);
             }
-            // `async |x| ...` gets desugared to `|x| async {...}`, so we need to
-            // resolve the arguments within the proper scopes so that usages of them inside the
-            // closure are detected as upvars rather than normal closure arg usages.
-            //
-            // Similarly, `gen |x| ...` gets desugared to `|x| gen {...}`, so we handle that too.
-            ExprKind::Closure(box ast::Closure {
-                coroutine_kind: Some(_),
-                ref fn_decl,
-                ref body,
-                ..
-            }) => {
-                self.with_rib(ValueNS, RibKind::Normal, |this| {
-                    this.with_label_rib(RibKind::FnOrCoroutine, |this| {
-                        // Resolve arguments:
-                        this.resolve_params(&fn_decl.inputs);
-                        // No need to resolve return type --
-                        // the outer closure return type is `FnRetTy::Default`.
-
-                        // Now resolve the inner closure
-                        {
-                            // No need to resolve arguments: the inner closure has none.
-                            // Resolve the return type:
-                            visit::walk_fn_ret_ty(this, &fn_decl.output);
-                            // Resolve the body
-                            this.visit_expr(body);
-                        }
-                    })
-                });
-            }
             // For closures, RibKind::FnOrCoroutine is added in visit_fn
             ExprKind::Closure(box ast::Closure {
                 binder: ClosureBinder::For { ref generic_params, span },
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index abb0a7a465a..a4c041f1ff2 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -16,8 +16,8 @@ use rustc_ast::{
 use rustc_ast_pretty::pprust::where_bound_predicate_to_string;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    MultiSpan, SuggestionStyle,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed, MultiSpan, SuggestionStyle,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
@@ -922,8 +922,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         path: &[Segment],
         span: Span,
     ) {
-        if let Some(err_code) = &err.code {
-            if err_code == &rustc_errors::error_code!(E0425) {
+        if let Some(err_code) = err.code {
+            if err_code == E0425 {
                 for label_rib in &self.label_ribs {
                     for (label_ident, node_id) in &label_rib.bindings {
                         let ident = path.last().unwrap().ident;
@@ -946,7 +946,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         }
                     }
                 }
-            } else if err_code == &rustc_errors::error_code!(E0412) {
+            } else if err_code == E0412 {
                 if let Some(correct) = Self::likely_rust_type(path) {
                     err.span_suggestion(
                         span,
@@ -970,7 +970,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         if !is_self_type(path, source.namespace()) {
             return false;
         }
-        err.code(rustc_errors::error_code!(E0411));
+        err.code(E0411);
         err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
         if let Some(item_kind) = self.diagnostic_metadata.current_item {
             if !item_kind.ident.span.is_dummy() {
@@ -999,7 +999,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
 
         debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
-        err.code(rustc_errors::error_code!(E0424));
+        err.code(E0424);
         err.span_label(
             span,
             match source {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 1c00f545eb8..9d09d060b59 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -15,9 +15,7 @@
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![feature(never_type)]
 #![feature(rustc_attrs)]
-#![recursion_limit = "256"]
 #![allow(rustdoc::private_intra_doc_links)]
 #![allow(rustc::potential_query_instability)]
 #![allow(internal_features)]
@@ -37,7 +35,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
-use rustc_errors::{Applicability, DiagnosticBuilder};
+use rustc_errors::{Applicability, DiagnosticBuilder, ErrCode};
 use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
@@ -258,7 +256,7 @@ enum ResolutionError<'a> {
         kind: &'static str,
         trait_path: String,
         trait_item_span: Span,
-        code: String,
+        code: ErrCode,
     },
     /// Error E0201: multiple impl items for the same trait item.
     TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 1c085ddf57b..170cc1268c3 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -1,10 +1,9 @@
 //! A bunch of methods and structures more or less related to resolving macros and
 //! interface provided by `Resolver` to macro expander.
 
-use crate::errors::{
-    self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
-    MacroExpectedFound, RemoveSurroundingDerive,
-};
+use crate::errors::CannotDetermineMacroResolution;
+use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope};
+use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive};
 use crate::Namespace::*;
 use crate::{BuiltinMacroState, Determinacy, MacroData};
 use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
@@ -15,7 +14,7 @@ use rustc_ast_pretty::pprust;
 use rustc_attr::StabilityLevel;
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{struct_span_code_err, Applicability};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, StashKey};
 use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand};
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::compile_declarative_macro;
@@ -25,9 +24,8 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_middle::middle::stability;
 use rustc_middle::ty::RegisteredTools;
 use rustc_middle::ty::{TyCtxt, Visibility};
-use rustc_session::lint::builtin::{
-    LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-};
+use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
+use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE};
 use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES};
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::parse::feature_err;
@@ -703,21 +701,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // situations should be reported as errors, so this is a bug.
                     this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
                 }
-            } else {
+            } else if this.tcx.dcx().has_errors().is_none() && this.privacy_errors.is_empty() {
                 // It's possible that the macro was unresolved (indeterminate) and silently
                 // expanded into a dummy fragment for recovery during expansion.
                 // Now, post-expansion, the resolution may succeed, but we can't change the
                 // past and need to report an error.
                 // However, non-speculative `resolve_path` can successfully return private items
                 // even if speculative `resolve_path` returned nothing previously, so we skip this
-                // less informative error if the privacy error is reported elsewhere.
-                if this.privacy_errors.is_empty() {
-                    this.dcx().emit_err(CannotDetermineMacroResolution {
-                        span,
-                        kind: kind.descr(),
-                        path: Segment::names_to_string(path),
-                    });
-                }
+                // less informative error if no other error is reported elsewhere.
+
+                let err = this.dcx().create_err(CannotDetermineMacroResolution {
+                    span,
+                    kind: kind.descr(),
+                    path: Segment::names_to_string(path),
+                });
+                err.stash(span, StashKey::UndeterminedMacroResolution);
             }
         };
 
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 48bee4cd2f0..9c34aa93957 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -8,7 +8,6 @@
 #![doc(rust_logo)]
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
-#![feature(allocator_api)]
 #![feature(associated_type_bounds)]
 #![feature(const_option)]
 #![feature(core_intrinsics)]
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index e751ff13a34..d35f951e2ae 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -347,6 +347,7 @@ impl SwitchWithOptPath {
 pub enum SymbolManglingVersion {
     Legacy,
     V0,
+    Hashed,
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Hash)]
@@ -2692,6 +2693,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
     match cg.symbol_mangling_version {
         // Stable values:
         None | Some(SymbolManglingVersion::V0) => {}
+
         // Unstable values:
         Some(SymbolManglingVersion::Legacy) => {
             if !unstable_opts.unstable_options {
@@ -2700,6 +2702,13 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
                 );
             }
         }
+        Some(SymbolManglingVersion::Hashed) => {
+            if !unstable_opts.unstable_options {
+                early_dcx.early_fatal(
+                    "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
+                );
+            }
+        }
     }
 
     // Check for unstable values of `-C instrument-coverage`.
@@ -2741,6 +2750,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
                 );
             }
             Some(SymbolManglingVersion::V0) => {}
+            Some(SymbolManglingVersion::Hashed) => {
+                early_dcx.early_warn(
+                    "-C instrument-coverage requires symbol mangling version `v0`, \
+                    but `-C symbol-mangling-version=hashed` was specified",
+                );
+            }
         }
     }
 
@@ -3077,7 +3092,7 @@ impl fmt::Display for CrateType {
 }
 
 impl IntoDiagnosticArg for CrateType {
-    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index e19f0fd84de..c36cec6f353 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -3,7 +3,7 @@ use std::num::NonZeroU32;
 use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
 use rustc_errors::{
-    error_code, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, IntoDiagnostic, Level, MultiSpan,
+    codes::*, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, IntoDiagnostic, Level, MultiSpan,
 };
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
@@ -19,9 +19,7 @@ pub struct FeatureGateError {
 impl<'a> IntoDiagnostic<'a> for FeatureGateError {
     #[track_caller]
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> {
-        DiagnosticBuilder::new(dcx, level, self.explain)
-            .with_span(self.span)
-            .with_code(error_code!(E0658))
+        DiagnosticBuilder::new(dcx, level, self.explain).with_span(self.span).with_code(E0658)
     }
 }
 
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 805854bd5cf..0d6328fbb07 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,11 +1,9 @@
 #![feature(let_chains)]
-#![feature(never_type)]
 #![feature(lazy_cell)]
 #![feature(option_get_or_insert_default)]
 #![feature(rustc_attrs)]
 #![feature(map_many_mut)]
 #![feature(iter_intersperse)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 486b6d4bf2e..d8d201d5f24 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -407,7 +407,8 @@ mod desc {
     pub const parse_switch_with_opt_path: &str =
         "an optional path to the profiling data output directory";
     pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
-    pub const parse_symbol_mangling_version: &str = "either `legacy` or `v0` (RFC 2603)";
+    pub const parse_symbol_mangling_version: &str =
+        "one of: `legacy`, `v0` (RFC 2603), or `hashed`";
     pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
     pub const parse_relocation_model: &str =
         "one of supported relocation models (`rustc --print relocation-models`)";
@@ -1180,6 +1181,7 @@ mod parse {
         *slot = match v {
             Some("legacy") => Some(SymbolManglingVersion::Legacy),
             Some("v0") => Some(SymbolManglingVersion::V0),
+            Some("hashed") => Some(SymbolManglingVersion::Hashed),
             _ => return false,
         };
         true
@@ -1504,7 +1506,7 @@ options! {
         "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
     symbol_mangling_version: Option<SymbolManglingVersion> = (None,
         parse_symbol_mangling_version, [TRACKED],
-        "which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
+        "which mangling version to use for symbol names ('legacy' (default), 'v0', or 'hashed')"),
     target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
         "select target processor (`rustc --print target-cpus` for details)"),
     target_feature: String = (String::new(), parse_target_feature, [TRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 891a83ce80c..3a0ae74dd92 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -22,7 +22,7 @@ use rustc_errors::emitter::{DynEmitter, HumanEmitter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
 use rustc_errors::{
-    error_code, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticMessage,
+    codes::*, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrCode,
     ErrorGuaranteed, FatalAbort, FluentBundle, IntoDiagnostic, LazyFallbackBundle, TerminalUrl,
 };
 use rustc_macros::HashStable_Generic;
@@ -111,7 +111,7 @@ impl Mul<usize> for Limit {
 }
 
 impl rustc_errors::IntoDiagnosticArg for Limit {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue {
         self.to_string().into_diagnostic_arg()
     }
 }
@@ -316,7 +316,7 @@ impl Session {
     ) -> DiagnosticBuilder<'a> {
         let mut err = self.dcx().create_err(err);
         if err.code.is_none() {
-            err.code(error_code!(E0658));
+            err.code(E0658);
         }
         add_feature_diagnostics(&mut err, self, feature);
         err
@@ -893,7 +893,7 @@ impl Session {
         CodegenUnits::Default(16)
     }
 
-    pub fn teach(&self, code: &str) -> bool {
+    pub fn teach(&self, code: ErrCode) -> bool {
         self.opts.unstable_opts.teach && self.dcx().must_teach(code)
     }
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 65702f76fda..ea6766ea583 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -2105,7 +2105,7 @@ fn remove_bom(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) {
 
 /// Replaces `\r\n` with `\n` in-place in `src`.
 ///
-/// Returns error if there's a lone `\r` in the string.
+/// Leaves any occurrences of lone `\r` unchanged.
 fn normalize_newlines(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) {
     if !src.as_bytes().contains(&b'\r') {
         return;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 4a1c222a528..dbfc89c2d49 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -246,17 +246,7 @@ symbols! {
         MutexGuard,
         N,
         NonNull,
-        NonZeroI128,
-        NonZeroI16,
-        NonZeroI32,
-        NonZeroI64,
-        NonZeroI8,
-        NonZeroU128,
-        NonZeroU16,
-        NonZeroU32,
-        NonZeroU64,
-        NonZeroU8,
-        NonZeroUsize,
+        NonZero,
         None,
         Normal,
         Ok,
@@ -1029,6 +1019,7 @@ symbols! {
         min_const_fn,
         min_const_generics,
         min_const_unsafe_fn,
+        min_exhaustive_patterns,
         min_specialization,
         min_type_alias_impl_trait,
         minnumf32,
@@ -1798,7 +1789,6 @@ symbols! {
         warn,
         wasm_abi,
         wasm_import_module,
-        wasm_preview2,
         wasm_target_feature,
         while_let,
         windows,
diff --git a/compiler/rustc_symbol_mangling/src/hashed.rs b/compiler/rustc_symbol_mangling/src/hashed.rs
new file mode 100644
index 00000000000..d4cd6161ac0
--- /dev/null
+++ b/compiler/rustc_symbol_mangling/src/hashed.rs
@@ -0,0 +1,43 @@
+use crate::v0;
+use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
+use rustc_hir::def_id::CrateNum;
+use rustc_middle::ty::{Instance, TyCtxt};
+
+use std::fmt::Write;
+
+pub(super) fn mangle<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+    instantiating_crate: Option<CrateNum>,
+    full_mangling_name: impl FnOnce() -> String,
+) -> String {
+    // The symbol of a generic function may be scattered in multiple downstream dylibs.
+    // If the symbol of a generic function still contains `crate name`, hash conflicts between the
+    // generic funcion and other symbols of the same `crate` cannot be detected in time during
+    // construction. This symbol conflict is left over until it occurs during run time.
+    // In this case, `instantiating-crate name` is used to replace `crate name` can completely
+    // eliminate the risk of the preceding potential hash conflict.
+    let crate_num =
+        if let Some(krate) = instantiating_crate { krate } else { instance.def_id().krate };
+
+    let mut symbol = "_RNxC".to_string();
+    v0::push_ident(tcx.crate_name(crate_num).as_str(), &mut symbol);
+
+    let hash = tcx.with_stable_hashing_context(|mut hcx| {
+        let mut hasher = StableHasher::new();
+        full_mangling_name().hash_stable(&mut hcx, &mut hasher);
+        hasher.finish::<Hash64>().as_u64()
+    });
+
+    push_hash64(hash, &mut symbol);
+
+    symbol
+}
+
+// The hash is encoded based on `base-62` and the final terminator `_` is removed because it does
+// not help prevent hash collisions
+fn push_hash64(hash: u64, output: &mut String) {
+    let hash = v0::encode_integer_62(hash);
+    let hash_len = hash.len();
+    let _ = write!(output, "{hash_len}H{}", &hash[..hash_len - 1]);
+}
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 8c035ba948b..362aaca6364 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -91,8 +91,6 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
-#![feature(never_type)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
@@ -111,6 +109,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Instance, TyCtxt};
 use rustc_session::config::SymbolManglingVersion;
 
+mod hashed;
 mod legacy;
 mod v0;
 
@@ -265,6 +264,9 @@ fn compute_symbol_name<'tcx>(
     let symbol = match mangling_version {
         SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate),
         SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
+        SymbolManglingVersion::Hashed => hashed::mangle(tcx, instance, instantiating_crate, || {
+            v0::mangle(tcx, instance, instantiating_crate)
+        }),
     };
 
     debug_assert!(
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index e89a640767f..16ebda55a7a 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -116,10 +116,7 @@ impl<'tcx> SymbolMangler<'tcx> {
     /// * `x > 0` is encoded as `x - 1` in base 62, followed by `"_"`,
     ///   e.g. `1` becomes `"0_"`, `62` becomes `"Z_"`, etc.
     fn push_integer_62(&mut self, x: u64) {
-        if let Some(x) = x.checked_sub(1) {
-            base_n::push_str(x as u128, 62, &mut self.out);
-        }
-        self.push("_");
+        push_integer_62(x, &mut self.out)
     }
 
     /// Push a `tag`-prefixed base 62 integer, when larger than `0`, that is:
@@ -138,45 +135,7 @@ impl<'tcx> SymbolMangler<'tcx> {
     }
 
     fn push_ident(&mut self, ident: &str) {
-        let mut use_punycode = false;
-        for b in ident.bytes() {
-            match b {
-                b'_' | b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' => {}
-                0x80..=0xff => use_punycode = true,
-                _ => bug!("symbol_names: bad byte {} in ident {:?}", b, ident),
-            }
-        }
-
-        let punycode_string;
-        let ident = if use_punycode {
-            self.push("u");
-
-            // FIXME(eddyb) we should probably roll our own punycode implementation.
-            let mut punycode_bytes = match punycode::encode(ident) {
-                Ok(s) => s.into_bytes(),
-                Err(()) => bug!("symbol_names: punycode encoding failed for ident {:?}", ident),
-            };
-
-            // Replace `-` with `_`.
-            if let Some(c) = punycode_bytes.iter_mut().rfind(|&&mut c| c == b'-') {
-                *c = b'_';
-            }
-
-            // FIXME(eddyb) avoid rechecking UTF-8 validity.
-            punycode_string = String::from_utf8(punycode_bytes).unwrap();
-            &punycode_string
-        } else {
-            ident
-        };
-
-        let _ = write!(self.out, "{}", ident.len());
-
-        // Write a separating `_` if necessary (leading digit or `_`).
-        if let Some('_' | '0'..='9') = ident.chars().next() {
-            self.push("_");
-        }
-
-        self.push(ident);
+        push_ident(ident, &mut self.out)
     }
 
     fn path_append_ns(
@@ -836,3 +795,62 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
         Ok(())
     }
 }
+/// Push a `_`-terminated base 62 integer, using the format
+/// specified in the RFC as `<base-62-number>`, that is:
+/// * `x = 0` is encoded as just the `"_"` terminator
+/// * `x > 0` is encoded as `x - 1` in base 62, followed by `"_"`,
+///   e.g. `1` becomes `"0_"`, `62` becomes `"Z_"`, etc.
+pub(crate) fn push_integer_62(x: u64, output: &mut String) {
+    if let Some(x) = x.checked_sub(1) {
+        base_n::push_str(x as u128, 62, output);
+    }
+    output.push('_');
+}
+
+pub(crate) fn encode_integer_62(x: u64) -> String {
+    let mut output = String::new();
+    push_integer_62(x, &mut output);
+    output
+}
+
+pub(crate) fn push_ident(ident: &str, output: &mut String) {
+    let mut use_punycode = false;
+    for b in ident.bytes() {
+        match b {
+            b'_' | b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' => {}
+            0x80..=0xff => use_punycode = true,
+            _ => bug!("symbol_names: bad byte {} in ident {:?}", b, ident),
+        }
+    }
+
+    let punycode_string;
+    let ident = if use_punycode {
+        output.push('u');
+
+        // FIXME(eddyb) we should probably roll our own punycode implementation.
+        let mut punycode_bytes = match punycode::encode(ident) {
+            Ok(s) => s.into_bytes(),
+            Err(()) => bug!("symbol_names: punycode encoding failed for ident {:?}", ident),
+        };
+
+        // Replace `-` with `_`.
+        if let Some(c) = punycode_bytes.iter_mut().rfind(|&&mut c| c == b'-') {
+            *c = b'_';
+        }
+
+        // FIXME(eddyb) avoid rechecking UTF-8 validity.
+        punycode_string = String::from_utf8(punycode_bytes).unwrap();
+        &punycode_string
+    } else {
+        ident
+    };
+
+    let _ = write!(output, "{}", ident.len());
+
+    // Write a separating `_` if necessary (leading digit or `_`).
+    if let Some('_' | '0'..='9') = ident.chars().next() {
+        output.push('_');
+    }
+
+    output.push_str(ident);
+}
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 257c6777996..bffb3681f13 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -11,12 +11,10 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![feature(assert_matches)]
-#![feature(associated_type_bounds)]
 #![feature(exhaustive_patterns)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
-#![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(step_trait)]
 #![deny(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index ead3be7fd52..884bd23e8cc 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1574,7 +1574,6 @@ supported_targets! {
     ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
     ("wasm32-unknown-unknown", wasm32_unknown_unknown),
     ("wasm32-wasi", wasm32_wasi),
-    ("wasm32-wasi-preview2", wasm32_wasi_preview2),
     ("wasm32-wasi-preview1-threads", wasm32_wasi_preview1_threads),
     ("wasm64-unknown-unknown", wasm64_unknown_unknown),
 
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs
index 389c67f8ae9..28ea4cc9ece 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs
@@ -72,12 +72,11 @@
 //! best we can with this target. Don't start relying on too much here unless
 //! you know what you're getting in to!
 
-use crate::spec::{base, crt_objects, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
+use crate::spec::{base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
 
 pub fn target() -> Target {
     let mut options = base::wasm::options();
 
-    options.families = cvs!["wasm", "wasi"];
     options.os = "wasi".into();
 
     options.add_pre_link_args(
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs
deleted file mode 100644
index fc44e5d4cbc..00000000000
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-//! The `wasm32-wasi-preview2` target is the next evolution of the
-//! wasm32-wasi target. While the wasi specification is still under
-//! active development, the {review 2 iteration is considered an "island
-//! of stability" that should allow users to rely on it indefinitely.
-//!
-//! The `wasi` target is a proposal to define a standardized set of WebAssembly
-//! component imports that allow it to interoperate with the host system in a
-//! standardized way. This set of imports is intended to empower WebAssembly
-//! binaries with host capabilities such as filesystem access, network access, etc.
-//!
-//! Wasi Preview 2 relies on the WebAssembly component model which is an extension of
-//! the core WebAssembly specification which allows interoperability between WebAssembly
-//! modules (known as "components") through high-level, shared-nothing APIs instead of the
-//! low-level, shared-everything linear memory model of the core WebAssembly specification.
-//!
-//! You can see more about wasi at <https://wasi.dev> and the component model at
-//! <https://github.com/WebAssembly/component-model>.
-
-use crate::spec::crt_objects;
-use crate::spec::LinkSelfContainedDefault;
-use crate::spec::{base, Target};
-
-pub fn target() -> Target {
-    let mut options = base::wasm::options();
-
-    options.os = "wasi".into();
-    options.env = "preview2".into();
-    options.linker = Some("wasm-component-ld".into());
-
-    options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
-    options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
-
-    // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
-    options.link_self_contained = LinkSelfContainedDefault::True;
-
-    // Right now this is a bit of a workaround but we're currently saying that
-    // the target by default has a static crt which we're taking as a signal
-    // for "use the bundled crt". If that's turned off then the system's crt
-    // will be used, but this means that default usage of this target doesn't
-    // need an external compiler but it's still interoperable with an external
-    // compiler if configured correctly.
-    options.crt_static_default = true;
-    options.crt_static_respected = true;
-
-    // Allow `+crt-static` to create a "cdylib" output which is just a wasm file
-    // without a main function.
-    options.crt_static_allows_dylibs = true;
-
-    // WASI's `sys::args::init` function ignores its arguments; instead,
-    // `args::args()` makes the WASI API calls itself.
-    options.main_needs_argc_argv = false;
-
-    // And, WASI mangles the name of "main" to distinguish between different
-    // signatures.
-    options.entry_name = "__main_void".into();
-
-    Target {
-        llvm_target: "wasm32-unknown-unknown".into(),
-        pointer_width: 32,
-        data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20".into(),
-        arch: "wasm32".into(),
-        options,
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 5eff52afbca..7894f8dd98f 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1,7 +1,7 @@
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee,
-    IntoDiagnostic, Level, SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    EmissionGuarantee, IntoDiagnostic, Level, SubdiagnosticMessage,
 };
 use rustc_macros::Diagnostic;
 use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
@@ -25,7 +25,7 @@ pub struct UnableToConstructConstantValue<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = E0232)]
 pub struct EmptyOnClauseInOnUnimplemented {
     #[primary_span]
     #[label]
@@ -33,7 +33,7 @@ pub struct EmptyOnClauseInOnUnimplemented {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_invalid_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+#[diag(trait_selection_invalid_on_clause_in_rustc_on_unimplemented, code = E0232)]
 pub struct InvalidOnClauseInOnUnimplemented {
     #[primary_span]
     #[label]
@@ -41,7 +41,7 @@ pub struct InvalidOnClauseInOnUnimplemented {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_no_value_in_rustc_on_unimplemented, code = "E0232")]
+#[diag(trait_selection_no_value_in_rustc_on_unimplemented, code = E0232)]
 #[note]
 pub struct NoValueInOnUnimplemented {
     #[primary_span]
@@ -59,17 +59,13 @@ pub struct NegativePositiveConflict<'tcx> {
 
 impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for NegativePositiveConflict<'_> {
     #[track_caller]
-    fn into_diagnostic(
-        self,
-        dcx: &DiagCtxt,
-        level: Level,
-    ) -> rustc_errors::DiagnosticBuilder<'_, G> {
+    fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
         let mut diag =
             DiagnosticBuilder::new(dcx, level, fluent::trait_selection_negative_positive_conflict);
         diag.arg("trait_desc", self.trait_desc.print_only_trait_path().to_string());
         diag.arg("self_desc", self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string()));
         diag.span(self.impl_span);
-        diag.code(rustc_errors::error_code!(E0751));
+        diag.code(E0751);
         match self.negative_impl_span {
             Ok(span) => {
                 diag.span_label(span, fluent::trait_selection_negative_implementation_here);
@@ -132,7 +128,7 @@ impl AddToDiagnostic for AdjustSignatureBorrow {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_closure_kind_mismatch, code = "E0525")]
+#[diag(trait_selection_closure_kind_mismatch, code = E0525)]
 pub struct ClosureKindMismatch {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 552c28c0586..5ec45212bc7 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -20,7 +20,6 @@
 #![feature(extract_if)]
 #![feature(let_chains)]
 #![feature(option_take_if)]
-#![feature(if_let_guard)]
 #![feature(never_type)]
 #![feature(type_alias_impl_trait)]
 #![feature(min_specialization)]
@@ -40,6 +39,7 @@ extern crate smallvec;
 
 pub mod errors;
 pub mod infer;
+pub mod regions;
 pub mod solve;
 pub mod traits;
 
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
new file mode 100644
index 00000000000..e8929f114e1
--- /dev/null
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -0,0 +1,40 @@
+use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::{InferCtxt, RegionResolutionError};
+use rustc_middle::traits::ObligationCause;
+
+pub trait InferCtxtRegionExt<'tcx> {
+    /// Resolve regions, using the deep normalizer to normalize any type-outlives
+    /// obligations in the process. This is in `rustc_trait_selection` because
+    /// we need to normalize.
+    ///
+    /// Prefer this method over `resolve_regions_with_normalize`, unless you are
+    /// doing something specific for normalization.
+    fn resolve_regions(
+        &self,
+        outlives_env: &OutlivesEnvironment<'tcx>,
+    ) -> Vec<RegionResolutionError<'tcx>>;
+}
+
+impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
+    fn resolve_regions(
+        &self,
+        outlives_env: &OutlivesEnvironment<'tcx>,
+    ) -> Vec<RegionResolutionError<'tcx>> {
+        self.resolve_regions_with_normalize(outlives_env, |ty, origin| {
+            let ty = self.resolve_vars_if_possible(ty);
+
+            if self.next_trait_solver() {
+                crate::solve::deeply_normalize(
+                    self.at(
+                        &ObligationCause::dummy_with_span(origin.span()),
+                        outlives_env.param_env,
+                    ),
+                    ty,
+                )
+                .map_err(|_| ty)
+            } else {
+                Ok(ty)
+            }
+        })
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index caf9470b4c6..915d722dd02 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -253,17 +253,6 @@ pub(super) trait GoalKind<'tcx>:
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)>;
-
-    /// Consider the `Unsize` candidate corresponding to coercing a sized type
-    /// into a `dyn Trait`.
-    ///
-    /// This is computed separately from the rest of the `Unsize` candidates
-    /// since it is only done once per self type, and not once per
-    /// *normalization step* (in `assemble_candidates_via_self_ty`).
-    fn consider_unsize_to_dyn_candidate(
-        ecx: &mut EvalCtxt<'_, 'tcx>,
-        goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx>;
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -271,64 +260,32 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         &mut self,
         goal: Goal<'tcx, G>,
     ) -> Vec<Candidate<'tcx>> {
-        debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
-        if let Some(ambig) = self.assemble_self_ty_infer_ambiguity_response(goal) {
-            return vec![ambig];
-        }
-
-        let mut candidates = self.assemble_candidates_via_self_ty(goal, 0);
-
-        self.assemble_unsize_to_dyn_candidate(goal, &mut candidates);
-
-        self.assemble_blanket_impl_candidates(goal, &mut candidates);
-
-        self.assemble_param_env_candidates(goal, &mut candidates);
-
-        self.assemble_coherence_unknowable_candidates(goal, &mut candidates);
-
-        candidates
-    }
-
-    /// `?0: Trait` is ambiguous, because it may be satisfied via a builtin rule,
-    /// object bound, alias bound, etc. We are unable to determine this until we can at
-    /// least structurally resolve the type one layer.
-    ///
-    /// It would also require us to consider all impls of the trait, which is both pretty
-    /// bad for perf and would also constrain the self type if there is just a single impl.
-    fn assemble_self_ty_infer_ambiguity_response<G: GoalKind<'tcx>>(
-        &mut self,
-        goal: Goal<'tcx, G>,
-    ) -> Option<Candidate<'tcx>> {
-        if goal.predicate.self_ty().is_ty_var() {
-            debug!("adding self_ty_infer_ambiguity_response");
+        let dummy_candidate = |this: &mut EvalCtxt<'_, 'tcx>, certainty| {
             let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
-            let result = self
-                .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
-                .unwrap();
-            let mut dummy_probe = self.inspect.new_probe();
+            let result = this.evaluate_added_goals_and_make_canonical_response(certainty).unwrap();
+            let mut dummy_probe = this.inspect.new_probe();
             dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result: Ok(result) });
-            self.inspect.finish_probe(dummy_probe);
-            Some(Candidate { source, result })
-        } else {
-            None
+            this.inspect.finish_probe(dummy_probe);
+            vec![Candidate { source, result }]
+        };
+
+        let Some(normalized_self_ty) =
+            self.try_normalize_ty(goal.param_env, goal.predicate.self_ty())
+        else {
+            debug!("overflow while evaluating self type");
+            return dummy_candidate(self, Certainty::OVERFLOW);
+        };
+
+        if normalized_self_ty.is_ty_var() {
+            debug!("self type has been normalized to infer");
+            return dummy_candidate(self, Certainty::AMBIGUOUS);
         }
-    }
 
-    /// Assemble candidates which apply to the self type. This only looks at candidate which
-    /// apply to the specific self type and ignores all others.
-    ///
-    /// Returns `None` if the self type is still ambiguous.
-    fn assemble_candidates_via_self_ty<G: GoalKind<'tcx>>(
-        &mut self,
-        goal: Goal<'tcx, G>,
-        num_steps: usize,
-    ) -> Vec<Candidate<'tcx>> {
+        let goal =
+            goal.with(self.tcx(), goal.predicate.with_self_ty(self.tcx(), normalized_self_ty));
         debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
-        if let Some(ambig) = self.assemble_self_ty_infer_ambiguity_response(goal) {
-            return vec![ambig];
-        }
 
-        let mut candidates = Vec::new();
+        let mut candidates = vec![];
 
         self.assemble_non_blanket_impl_candidates(goal, &mut candidates);
 
@@ -338,61 +295,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         self.assemble_object_bound_candidates(goal, &mut candidates);
 
-        self.assemble_candidates_after_normalizing_self_ty(goal, &mut candidates, num_steps);
-        candidates
-    }
+        self.assemble_blanket_impl_candidates(goal, &mut candidates);
 
-    /// If the self type of a goal is an alias we first try to normalize the self type
-    /// and compute the candidates for the normalized self type in case that succeeds.
-    ///
-    /// These candidates are used in addition to the ones with the alias as a self type.
-    /// We do this to simplify both builtin candidates and for better performance.
-    ///
-    /// We generate the builtin candidates on the fly by looking at the self type, e.g.
-    /// add `FnPtr` candidates if the self type is a function pointer. Handling builtin
-    /// candidates while the self type is still an alias seems difficult. This is similar
-    /// to `try_structurally_resolve_type` during hir typeck (FIXME once implemented).
-    ///
-    /// Looking at all impls for some trait goal is prohibitively expensive. We therefore
-    /// only look at implementations with a matching self type. Because of this function,
-    /// we can avoid looking at all existing impls if the self type is an alias.
-    #[instrument(level = "debug", skip_all)]
-    fn assemble_candidates_after_normalizing_self_ty<G: GoalKind<'tcx>>(
-        &mut self,
-        goal: Goal<'tcx, G>,
-        candidates: &mut Vec<Candidate<'tcx>>,
-        num_steps: usize,
-    ) {
-        let tcx = self.tcx();
-        let &ty::Alias(_, alias) = goal.predicate.self_ty().kind() else { return };
-
-        candidates.extend(self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
-            if tcx.recursion_limit().value_within_limit(num_steps) {
-                let normalized_ty = ecx.next_ty_infer();
-                let normalizes_to_goal =
-                    goal.with(tcx, ty::NormalizesTo { alias, term: normalized_ty.into() });
-                ecx.add_goal(GoalSource::Misc, normalizes_to_goal);
-                if let Err(NoSolution) = ecx.try_evaluate_added_goals() {
-                    debug!("self type normalization failed");
-                    return vec![];
-                }
-                let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty);
-                debug!(?normalized_ty, "self type normalized");
-                // NOTE: Alternatively we could call `evaluate_goal` here and only
-                // have a `Normalized` candidate. This doesn't work as long as we
-                // use `CandidateSource` in winnowing.
-                let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty));
-                ecx.assemble_candidates_via_self_ty(goal, num_steps + 1)
-            } else {
-                match ecx.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW) {
-                    Ok(result) => vec![Candidate {
-                        source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                        result,
-                    }],
-                    Err(NoSolution) => vec![],
-                }
-            }
-        }));
+        self.assemble_param_env_candidates(goal, &mut candidates);
+
+        self.assemble_coherence_unknowable_candidates(goal, &mut candidates);
+
+        candidates
     }
 
     #[instrument(level = "debug", skip_all)]
@@ -501,24 +410,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     }
 
     #[instrument(level = "debug", skip_all)]
-    fn assemble_unsize_to_dyn_candidate<G: GoalKind<'tcx>>(
-        &mut self,
-        goal: Goal<'tcx, G>,
-        candidates: &mut Vec<Candidate<'tcx>>,
-    ) {
-        let tcx = self.tcx();
-        if tcx.lang_items().unsize_trait() == Some(goal.predicate.trait_def_id(tcx)) {
-            match G::consider_unsize_to_dyn_candidate(self, goal) {
-                Ok(result) => candidates.push(Candidate {
-                    source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                    result,
-                }),
-                Err(NoSolution) => (),
-            }
-        }
-    }
-
-    #[instrument(level = "debug", skip_all)]
     fn assemble_blanket_impl_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 7c8f885a1f2..6984f0ba694 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -288,11 +288,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
     /// Normalize a type when it is structually matched on.
     ///
-    /// For self types this is generally already handled through
-    /// `assemble_candidates_after_normalizing_self_ty`, so anything happening
-    /// in [`EvalCtxt::assemble_candidates_via_self_ty`] does not have to normalize
-    /// the self type. It is required when structurally matching on any other
-    /// arguments of a trait goal, e.g. when assembling builtin unsize candidates.
+    /// In nearly all cases this function must be used before matching on a type.
+    /// Not doing so is likely to be incomplete and therefore unsound during
+    /// coherence.
     #[instrument(level = "debug", skip(self), ret)]
     fn try_normalize_ty(
         &mut self,
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index ccee6f8eb29..9f1b4a09a20 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -603,13 +603,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
         )
     }
 
-    fn consider_unsize_to_dyn_candidate(
-        _ecx: &mut EvalCtxt<'_, 'tcx>,
-        goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
-        bug!("`Unsize` does not have an associated type: {:?}", goal)
-    }
-
     fn consider_structural_builtin_unsize_candidates(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index be079275684..b185e4e5f8e 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -490,53 +490,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         ecx.evaluate_added_goals_and_make_canonical_response(certainty)
     }
 
-    fn consider_unsize_to_dyn_candidate(
-        ecx: &mut EvalCtxt<'_, 'tcx>,
-        goal: Goal<'tcx, Self>,
-    ) -> QueryResult<'tcx> {
-        ecx.probe(|_| ProbeKind::UnsizeAssembly).enter(|ecx| {
-            let a_ty = goal.predicate.self_ty();
-            // We need to normalize the b_ty since it's destructured as a `dyn Trait`.
-            let Some(b_ty) =
-                ecx.try_normalize_ty(goal.param_env, goal.predicate.trait_ref.args.type_at(1))
-            else {
-                return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW);
-            };
-
-            let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
-                return Err(NoSolution);
-            };
-
-            let tcx = ecx.tcx();
-
-            // Can only unsize to an object-safe trait.
-            if b_data.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) {
-                return Err(NoSolution);
-            }
-
-            // Check that the type implements all of the predicates of the trait object.
-            // (i.e. the principal, all of the associated types match, and any auto traits)
-            ecx.add_goals(
-                GoalSource::ImplWhereBound,
-                b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
-            );
-
-            // The type must be `Sized` to be unsized.
-            if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
-                ecx.add_goal(
-                    GoalSource::ImplWhereBound,
-                    goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])),
-                );
-            } else {
-                return Err(NoSolution);
-            }
-
-            // The type must outlive the lifetime of the `dyn` we're unsizing into.
-            ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
-            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-        })
-    }
-
     /// ```ignore (builtin impl example)
     /// trait Trait {
     ///     fn foo(&self);
@@ -588,8 +541,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                     goal, a_data, a_region, b_data, b_region,
                 ),
 
-                // `T` -> `dyn Trait` unsizing is handled separately in `consider_unsize_to_dyn_candidate`
-                (_, &ty::Dynamic(..)) => vec![],
+                // `T` -> `dyn Trait` unsizing.
+                (_, &ty::Dynamic(b_region, b_data, ty::Dyn)) => result_to_single(
+                    ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region, b_data),
+                    BuiltinImplSource::Misc,
+                ),
 
                 // `[T; N]` -> `[T]` unsizing
                 (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => result_to_single(
@@ -691,6 +647,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         responses
     }
 
+    fn consider_builtin_unsize_to_dyn_candidate(
+        &mut self,
+        goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
+        b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
+        b_region: ty::Region<'tcx>,
+    ) -> QueryResult<'tcx> {
+        let tcx = self.tcx();
+        let Goal { predicate: (a_ty, _), .. } = goal;
+
+        // Can only unsize to an object-safe trait.
+        if b_data.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) {
+            return Err(NoSolution);
+        }
+
+        // Check that the type implements all of the predicates of the trait object.
+        // (i.e. the principal, all of the associated types match, and any auto traits)
+        self.add_goals(
+            GoalSource::ImplWhereBound,
+            b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
+        );
+
+        // The type must be `Sized` to be unsized.
+        if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
+            self.add_goal(
+                GoalSource::ImplWhereBound,
+                goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])),
+            );
+        } else {
+            return Err(NoSolution);
+        }
+
+        // The type must outlive the lifetime of the `dyn` we're unsizing into.
+        self.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
+        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+    }
+
     fn consider_builtin_upcast_to_principal(
         &mut self,
         goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index c4344758574..7933654a915 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         }
 
         let outlives_env = OutlivesEnvironment::new(full_env);
-        infcx.process_registered_region_obligations(&outlives_env);
+        let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty, _| Ok(ty));
 
         let region_data =
             infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();
@@ -513,6 +513,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         }
 
         while !vid_map.is_empty() {
+            #[allow(rustc::potential_query_instability)]
             let target = *vid_map.keys().next().expect("Keys somehow empty");
             let deps = vid_map.remove(&target).expect("Entry somehow missing");
 
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index ecbb92ca5b9..c49185a52c7 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -6,6 +6,7 @@
 
 use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::InferOk;
+use crate::regions::InferCtxtRegionExt;
 use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
 use crate::solve::{deeply_normalize_for_diagnostics, inspect};
 use crate::traits::engine::TraitEngineExt;
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 013a50f9fa1..caf950037fd 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -3,6 +3,7 @@ use std::fmt::Debug;
 
 use super::FulfillmentContext;
 use super::TraitEngine;
+use crate::regions::InferCtxtRegionExt;
 use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt;
 use crate::traits::error_reporting::TypeErrCtxtExt;
 use crate::traits::NormalizeExt;
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
index 864580afe62..ca43436848b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
@@ -1,7 +1,7 @@
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxt;
 use crate::traits::{Obligation, ObligationCause, ObligationCtxt};
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::Node;
 use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index bb1b6ec1390..972da180a33 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -6,7 +6,7 @@ use rustc_ast::AttrKind;
 use rustc_ast::{Attribute, MetaItem, NestedMetaItem};
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
+use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::GenericArgsRef;
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 6a40ffebdad..69649e36178 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -13,7 +13,7 @@ use hir::def::CtorOf;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    error_code, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
     MultiSpan, Style, SuggestionStyle,
 };
 use rustc_hir as hir;
@@ -2014,7 +2014,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             return false;
         };
 
-        err.code(error_code!(E0746));
+        err.code(E0746);
         err.primary_message("return type cannot have an unboxed trait object");
         err.children.clear();
 
@@ -3292,7 +3292,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     err.help("unsized fn params are gated as an unstable feature");
                 }
             }
-            ObligationCauseCode::SizedReturnType => {
+            ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType => {
                 err.note("the return type of a function must have a statically known size");
             }
             ObligationCauseCode::SizedYieldType => {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 149dcffe333..dee3e14f3c9 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -19,8 +19,8 @@ use crate::traits::{
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    MultiSpan, StashKey, Style,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed, MultiSpan, StashKey, Style,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace, Res};
@@ -99,7 +99,7 @@ pub trait TypeErrCtxtExt<'tcx> {
         obligation: PredicateObligation<'tcx>,
         root_obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
-    );
+    ) -> ErrorGuaranteed;
 
     fn emit_specialized_closure_kind_error(
         &self,
@@ -107,7 +107,10 @@ pub trait TypeErrCtxtExt<'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Option<ErrorGuaranteed>;
 
-    fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool;
+    fn fn_arg_obligation(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+    ) -> Result<(), ErrorGuaranteed>;
 
     fn try_conversion_context(
         &self,
@@ -142,6 +145,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 (
                     span,
                     predicates
+                        .0
                         .iter()
                         .map(|&predicate| ErrorDescriptor { predicate, index: None })
                         .collect(),
@@ -208,10 +212,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
 
+        let mut reported = None;
+
         for from_expansion in [false, true] {
             for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
                 if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
-                    self.report_fulfillment_error(error);
+                    let guar = self.report_fulfillment_error(error);
+                    reported = Some(guar);
                     // We want to ignore desugarings here: spans are equivalent even
                     // if one is the result of a desugaring and the other is not.
                     let mut span = error.obligation.cause.span;
@@ -222,13 +229,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     self.reported_trait_errors
                         .borrow_mut()
                         .entry(span)
-                        .or_default()
+                        .or_insert_with(|| (vec![], guar))
+                        .0
                         .push(error.obligation.predicate);
                 }
             }
         }
 
-        self.dcx().delayed_bug("expected fulfillment errors")
+        // It could be that we don't report an error because we have seen an `ErrorReported` from another source.
+        // We should probably be able to fix most of these, but some are delayed bugs that get a proper error
+        // after this function.
+        reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors"))
     }
 
     /// Reports that an overflow has occurred and halts compilation. We
@@ -374,7 +385,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         mut obligation: PredicateObligation<'tcx>,
         root_obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
-    ) {
+    ) -> ErrorGuaranteed {
         let tcx = self.tcx;
 
         if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
@@ -384,10 +395,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         }
 
         let mut span = obligation.cause.span;
-        // FIXME: statically guarantee this by tainting after the diagnostic is emitted
-        self.set_tainted_by_errors(
-            tcx.dcx().span_delayed_bug(span, "`report_selection_error` did not emit an error"),
-        );
 
         let mut err = match *error {
             SelectionError::Unimplemented => {
@@ -412,21 +419,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     kind: _,
                 } = *obligation.cause.code()
                 {
-                    self.report_extra_impl_obligation(
+                    return self.report_extra_impl_obligation(
                         span,
                         impl_item_def_id,
                         trait_item_def_id,
                         &format!("`{}`", obligation.predicate),
                     )
-                    .emit();
-                    return;
+                    .emit()
                 }
 
                 // Report a const-param specific error
                 if let ObligationCauseCode::ConstParam(ty) = *obligation.cause.code().peel_derives()
                 {
-                    self.report_const_param_not_wf(ty, &obligation).emit();
-                    return;
+                    return self.report_const_param_not_wf(ty, &obligation).emit();
                 }
 
                 let bound_predicate = obligation.predicate.kind();
@@ -436,22 +441,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
                         let trait_ref = trait_predicate.to_poly_trait_ref();
 
-                        if let Some(_guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) {
-                            return;
+                        if let Some(guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) {
+                            return guar;
                         }
 
                         // FIXME(effects)
                         let predicate_is_const = false;
 
-                        if self.dcx().has_errors().is_some()
+                        if let Some(guar) = self.dcx().has_errors()
                             && trait_predicate.references_error()
                         {
-                            return;
+                            return guar;
                         }
-                        if self.fn_arg_obligation(&obligation) {
-                            // Silence redundant errors on binding acccess that are already
-                            // reported on the binding definition (#56607).
-                            return;
+                        // Silence redundant errors on binding acccess that are already
+                        // reported on the binding definition (#56607).
+                        if let Err(guar) = self.fn_arg_obligation(&obligation) {
+                            return guar;
                         }
                         let mut file = None;
                         let (post_message, pre_message, type_def) = self
@@ -515,7 +520,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 trait_ref,
                                 span,
                             ) {
-                                GetSafeTransmuteErrorAndReason::Silent => return,
+                                GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"),
                                 GetSafeTransmuteErrorAndReason::Error {
                                     err_msg,
                                     safe_transmute_explanation,
@@ -576,8 +581,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             have_alt_message,
                         ) {
                             self.note_obligation_cause(&mut err, &obligation);
-                            err.emit();
-                            return;
+                            return err.emit();
                         }
 
                         file_note.map(|note| err.note(note));
@@ -680,13 +684,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         }
 
                         if self.suggest_add_clone_to_arg(&obligation, &mut err, trait_predicate) {
-                            err.emit();
-                            return;
+                            return err.emit();
                         }
 
                         if self.suggest_impl_trait(&mut err, &obligation, trait_predicate) {
-                            err.emit();
-                            return;
+                            return err.emit();
                         }
 
                         if is_unsize {
@@ -776,8 +778,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 Some(sym::Debug | sym::Display)
                             )
                         {
-                            err.emit();
-                            return;
+                            return err.emit();
                         }
 
                         err
@@ -912,8 +913,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     found_trait_ref,
                     expected_trait_ref,
                 ) {
-                    Some(err) => err,
-                    None => return,
+                    Ok(err) => err,
+                    Err(guar) => return guar,
                 }
             }
 
@@ -934,15 +935,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => {
                 match self.report_not_const_evaluatable_error(&obligation, span) {
-                    Some(err) => err,
-                    None => return,
+                    Ok(err) => err,
+                    Err(guar) => return guar,
                 }
             }
 
             // Already reported in the query.
-            SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) |
+            SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) |
             // Already reported.
-            Overflow(OverflowError::Error(_)) => return,
+            Overflow(OverflowError::Error(guar)) => return guar,
 
             Overflow(_) => {
                 bug!("overflow should be handled before the `report_selection_error` path");
@@ -951,7 +952,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
         self.note_obligation_cause(&mut err, &obligation);
         self.point_at_returns_when_relevant(&mut err, &obligation);
-        err.emit();
+        err.emit()
     }
 
     fn emit_specialized_closure_kind_error(
@@ -986,7 +987,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         }
     }
 
-    fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
+    fn fn_arg_obligation(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+    ) -> Result<(), ErrorGuaranteed> {
         if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
             obligation.cause.code()
             && let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id)
@@ -996,12 +1000,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 hir::Path { res: hir::def::Res::Local(hir_id), .. },
             )) = arg.kind
             && let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id)
-            && let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span)
+            && let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)
             && preds.contains(&obligation.predicate)
         {
-            return true;
+            return Err(*guar);
         }
-        false
+        Ok(())
     }
 
     /// When the `E` of the resulting `Result<T, E>` in an expression `foo().bar().baz()?`,
@@ -1323,13 +1327,13 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
     // `error` occurring implies that `cond` occurs.
     fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool;
 
-    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>);
+    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed;
 
     fn report_projection_error(
         &self,
         obligation: &PredicateObligation<'tcx>,
         error: &MismatchedProjectionTypes<'tcx>,
-    );
+    ) -> ErrorGuaranteed;
 
     fn maybe_detailed_projection_msg(
         &self,
@@ -1395,7 +1399,7 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
         trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
     ) -> PredicateObligation<'tcx>;
 
-    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>);
+    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed;
 
     fn predicate_can_apply(
         &self,
@@ -1512,13 +1516,13 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
         span: Span,
         found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
         expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-    ) -> Option<DiagnosticBuilder<'tcx>>;
+    ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
 
     fn report_not_const_evaluatable_error(
         &self,
         obligation: &PredicateObligation<'tcx>,
         span: Span,
-    ) -> Option<DiagnosticBuilder<'tcx>>;
+    ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed>;
 }
 
 impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
@@ -1564,7 +1568,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
+    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed {
         if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
             == DumpSolverProofTree::OnError
         {
@@ -1572,31 +1576,29 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         }
 
         match error.code {
-            FulfillmentErrorCode::SelectionError(ref selection_error) => {
-                self.report_selection_error(
+            FulfillmentErrorCode::SelectionError(ref selection_error) => self
+                .report_selection_error(
                     error.obligation.clone(),
                     &error.root_obligation,
                     selection_error,
-                );
-            }
+                ),
             FulfillmentErrorCode::ProjectionError(ref e) => {
-                self.report_projection_error(&error.obligation, e);
+                self.report_projection_error(&error.obligation, e)
             }
             FulfillmentErrorCode::Ambiguity { overflow: false } => {
-                self.maybe_report_ambiguity(&error.obligation);
+                self.maybe_report_ambiguity(&error.obligation)
             }
             FulfillmentErrorCode::Ambiguity { overflow: true } => {
-                self.report_overflow_no_abort(error.obligation.clone());
+                self.report_overflow_no_abort(error.obligation.clone())
             }
-            FulfillmentErrorCode::SubtypeError(ref expected_found, ref err) => {
-                self.report_mismatched_types(
+            FulfillmentErrorCode::SubtypeError(ref expected_found, ref err) => self
+                .report_mismatched_types(
                     &error.obligation.cause,
                     expected_found.expected,
                     expected_found.found,
                     *err,
                 )
-                .emit();
-            }
+                .emit(),
             FulfillmentErrorCode::ConstEquateError(ref expected_found, ref err) => {
                 let mut diag = self.report_mismatched_consts(
                     &error.obligation.cause,
@@ -1620,11 +1622,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         &mut Default::default(),
                     );
                 }
-                diag.emit();
-            }
-            FulfillmentErrorCode::Cycle(ref cycle) => {
-                self.report_overflow_obligation_cycle(cycle);
+                diag.emit()
             }
+            FulfillmentErrorCode::Cycle(ref cycle) => self.report_overflow_obligation_cycle(cycle),
         }
     }
 
@@ -1633,11 +1633,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         &self,
         obligation: &PredicateObligation<'tcx>,
         error: &MismatchedProjectionTypes<'tcx>,
-    ) {
+    ) -> ErrorGuaranteed {
         let predicate = self.resolve_vars_if_possible(obligation.predicate);
 
-        if predicate.references_error() {
-            return;
+        if let Err(e) = predicate.error_reported() {
+            return e;
         }
 
         self.probe(|_| {
@@ -1802,8 +1802,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 false,
             );
             self.note_obligation_cause(&mut diag, obligation);
-            diag.emit();
-        });
+            diag.emit()
+        })
     }
 
     fn maybe_detailed_projection_msg(
@@ -2341,7 +2341,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
+    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed {
         // Unable to successfully determine, probably means
         // insufficient type information, but could mean
         // ambiguous impls. The latter *ought* to be a
@@ -2361,8 +2361,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 let trait_ref = bound_predicate.rebind(data.trait_ref);
                 debug!(?trait_ref);
 
-                if predicate.references_error() {
-                    return;
+                if let Err(e) = predicate.error_reported() {
+                    return e;
                 }
 
                 // This is kind of a hack: it frequently happens that some earlier
@@ -2381,17 +2381,20 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 // check upstream for type errors and don't add the obligations to
                 // begin with in those cases.
                 if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
-                    if let None = self.tainted_by_errors() {
-                        let err = self.emit_inference_failure_err(
-                            obligation.cause.body_id,
-                            span,
-                            trait_ref.self_ty().skip_binder().into(),
-                            ErrorCode::E0282,
-                            false,
-                        );
-                        err.stash(span, StashKey::MaybeForgetReturn);
+                    match self.tainted_by_errors() {
+                        None => {
+                            let err = self.emit_inference_failure_err(
+                                obligation.cause.body_id,
+                                span,
+                                trait_ref.self_ty().skip_binder().into(),
+                                ErrorCode::E0282,
+                                false,
+                            );
+                            err.stash(span, StashKey::MaybeForgetReturn);
+                            return self.dcx().delayed_bug("stashed error never reported");
+                        }
+                        Some(e) => return e,
                     }
-                    return;
                 }
 
                 // Typically, this ambiguity should only happen if
@@ -2450,19 +2453,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     }
                 }
                 if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
-                    if self.tainted_by_errors().is_some() && subst.is_none() {
+                    if let Some(e) = self.tainted_by_errors()
+                        && subst.is_none()
+                    {
                         // If `subst.is_none()`, then this is probably two param-env
                         // candidates or impl candidates that are equal modulo lifetimes.
                         // Therefore, if we've already emitted an error, just skip this
                         // one, since it's not particularly actionable.
                         err.cancel();
-                        return;
+                        return e;
                     }
                     self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
                 } else {
-                    if self.tainted_by_errors().is_some() {
+                    if let Some(e) = self.tainted_by_errors() {
                         err.cancel();
-                        return;
+                        return e;
                     }
                     err.note(format!("cannot satisfy `{predicate}`"));
                     let impl_candidates = self
@@ -2493,7 +2498,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     expr_finder.visit_expr(self.tcx.hir().body(body_id).value);
 
                     if let Some(hir::Expr {
-                        kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
+                        kind:
+                            hir::ExprKind::Call(
+                                hir::Expr {
+                                    kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
+                                    ..
+                                },
+                                _,
+                            )
+                            | hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
                         ..
                     }) = expr_finder.result
                         && let [
@@ -2529,7 +2542,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                  corresponding `impl` type",
                             ),
                         );
-                        err.code(rustc_errors::error_code!(E0790));
+                        err.code(E0790);
 
                         if let Some(local_def_id) = data.trait_ref.def_id.as_local()
                             && let Some(hir::Node::Item(hir::Item {
@@ -2605,11 +2618,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
                 // Same hacky approach as above to avoid deluging user
                 // with error messages.
-                if arg.references_error()
-                    || self.dcx().has_errors().is_some()
-                    || self.tainted_by_errors().is_some()
-                {
-                    return;
+
+                if let Err(e) = arg.error_reported() {
+                    return e;
+                }
+                if let Some(e) = self.tainted_by_errors() {
+                    return e;
+                }
+                if let Some(e) = self.dcx().has_errors() {
+                    return e;
                 }
 
                 self.emit_inference_failure_err(
@@ -2622,12 +2639,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
 
             ty::PredicateKind::Subtype(data) => {
-                if data.references_error()
-                    || self.dcx().has_errors().is_some()
-                    || self.tainted_by_errors().is_some()
-                {
+                if let Err(e) = data.error_reported() {
+                    return e;
+                }
+                if let Some(e) = self.tainted_by_errors() {
+                    return e;
+                }
+                if let Some(e) = self.dcx().has_errors() {
                     // no need to overload user in such cases
-                    return;
+                    return e;
                 }
                 let SubtypePredicate { a_is_expected: _, a, b } = data;
                 // both must be type variables, or the other would've been instantiated
@@ -2641,8 +2661,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 )
             }
             ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
-                if predicate.references_error() || self.tainted_by_errors().is_some() {
-                    return;
+                if let Err(e) = predicate.error_reported() {
+                    return e;
+                }
+                if let Some(e) = self.tainted_by_errors() {
+                    return e;
                 }
                 let subst = data
                     .projection_ty
@@ -2673,8 +2696,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
 
             ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(data)) => {
-                if predicate.references_error() || self.tainted_by_errors().is_some() {
-                    return;
+                if let Err(e) = predicate.error_reported() {
+                    return e;
+                }
+                if let Some(e) = self.tainted_by_errors() {
+                    return e;
                 }
                 let subst = data.walk().find(|g| g.is_non_region_infer());
                 if let Some(subst) = subst {
@@ -2699,8 +2725,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             _ => {
-                if self.dcx().has_errors().is_some() || self.tainted_by_errors().is_some() {
-                    return;
+                if let Some(e) = self.tainted_by_errors() {
+                    return e;
+                }
+                if let Some(e) = self.dcx().has_errors() {
+                    // no need to overload user in such cases
+                    return e;
                 }
                 struct_span_code_err!(
                     self.dcx(),
@@ -2713,7 +2743,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         };
         self.note_obligation_cause(&mut err, obligation);
-        err.emit();
+        err.emit()
     }
 
     fn annotate_source_of_ambiguity(
@@ -3162,7 +3192,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             | ObligationCauseCode::ItemObligation(def_id)
                 if self.tcx.is_fn_trait(*def_id) =>
             {
-                err.code(rustc_errors::error_code!(E0059));
+                err.code(E0059);
                 err.primary_message(format!(
                     "type parameter to bare `{}` trait must be a tuple",
                     self.tcx.def_path_str(*def_id)
@@ -3433,16 +3463,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         span: Span,
         found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
         expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-    ) -> Option<DiagnosticBuilder<'tcx>> {
+    ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed> {
         let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref);
         let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref);
 
-        if expected_trait_ref.self_ty().references_error() {
-            return None;
-        }
+        expected_trait_ref.self_ty().error_reported()?;
 
         let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else {
-            return None;
+            return Err(self.dcx().delayed_bug("bound vars outside binder"));
         };
 
         let found_did = match *found_trait_ty.kind() {
@@ -3456,7 +3484,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         if !self.reported_signature_mismatch.borrow_mut().insert((span, found_span)) {
             // We check closures twice, with obligations flowing in different directions,
             // but we want to complain about them only once.
-            return None;
+            return Err(self.dcx().span_delayed_bug(span, "already_reported"));
         }
 
         let mut not_tupled = false;
@@ -3485,7 +3513,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         // This shouldn't be common unless manually implementing one of the
         // traits manually, but don't make it more confusing when it does
         // happen.
-        Some(
+        Ok(
             if Some(expected_trait_ref.def_id()) != self.tcx.lang_items().coroutine_trait()
                 && not_tupled
             {
@@ -3534,9 +3562,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         &self,
         obligation: &PredicateObligation<'tcx>,
         span: Span,
-    ) -> Option<DiagnosticBuilder<'tcx>> {
+    ) -> Result<DiagnosticBuilder<'tcx>, ErrorGuaranteed> {
         if !self.tcx.features().generic_const_exprs {
-            self.dcx()
+            let guar = self
+                .dcx()
                 .struct_span_err(span, "constant expression depends on a generic parameter")
                 // FIXME(const_generics): we should suggest to the user how they can resolve this
                 // issue. However, this is currently not actually possible
@@ -3546,7 +3575,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 // be reachable.
                 .with_note("this may fail depending on what value the parameter takes")
                 .emit();
-            return None;
+            return Err(guar);
         }
 
         match obligation.predicate.kind().skip_binder() {
@@ -3561,13 +3590,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             )),
                             _ => err.help("consider adding a `where` bound using this expression"),
                         };
-                    Some(err)
+                    Ok(err)
                 }
                 ty::ConstKind::Expr(_) => {
                     let err = self
                         .dcx()
                         .struct_span_err(span, format!("unconstrained generic constant `{ct}`"));
-                    Some(err)
+                    Ok(err)
                 }
                 _ => {
                     bug!("const evaluatable failed for non-unevaluated const `{ct:?}`");
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index 0cd376fcbbd..93f9c2333f0 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -1,5 +1,6 @@
 //! Miscellaneous type-system utilities that are too small to deserve their own modules.
 
+use crate::regions::InferCtxtRegionExt;
 use crate::traits::{self, ObligationCause, ObligationCtxt};
 
 use hir::LangItem;
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 080ad7bd549..a7f6021d57a 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -25,6 +25,7 @@ pub mod wf;
 
 use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::{InferCtxt, TyCtxtInferExt};
+use crate::regions::InferCtxtRegionExt;
 use crate::traits::error_reporting::TypeErrCtxtExt as _;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_errors::ErrorGuaranteed;
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index bfc6937a3eb..de08e7d2f03 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -20,7 +20,7 @@ use crate::traits::{
     self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
 };
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{error_code, DelayDm, Diagnostic};
+use rustc_errors::{codes::*, DelayDm, Diagnostic};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
@@ -449,7 +449,7 @@ fn report_conflicting_impls<'tcx>(
                 || tcx.orphan_check_impl(impl_def_id).is_ok()
             {
                 let mut err = tcx.dcx().struct_span_err(impl_span, msg);
-                err.code(error_code!(E0119));
+                err.code(E0119);
                 decorate(tcx, &overlap, impl_span, &mut err);
                 err.emit()
             } else {
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index dfa5814219b..c7916ec60bb 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -2,7 +2,6 @@
 
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-#![feature(let_chains)]
 #![recursion_limit = "256"]
 
 #[macro_use]
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 4b559632017..c80389a3a4d 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -1,4 +1,5 @@
-#![feature(alloc_layout_extra, decl_macro, iterator_try_reduce, never_type)]
+#![feature(alloc_layout_extra)]
+#![feature(never_type)]
 #![allow(dead_code, unused_variables)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index 947d4bbe86e..bfbb45f0cb5 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -1,5 +1,6 @@
 //! Errors emitted by ty_utils
 
+use rustc_errors::codes::*;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::{GenericArg, Ty};
 use rustc_span::Span;
@@ -113,7 +114,7 @@ pub struct DuplicateArg<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ty_utils_impl_trait_not_param, code = "E0792")]
+#[diag(ty_utils_impl_trait_not_param, code = E0792)]
 pub struct NotParam<'tcx> {
     pub arg: GenericArg<'tcx>,
     #[primary_span]
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index fa1f94e8b41..51acb99d29b 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -15,7 +15,6 @@
 #![feature(iterator_try_collect)]
 #![feature(let_chains)]
 #![feature(never_type)]
-#![recursion_limit = "256"]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index de5dfcdf207..4f57f532a40 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -16,7 +16,6 @@
 //!
 //! The goal is to eventually be published on
 //! [crates.io](https://crates.io).
-#![feature(type_alias_impl_trait)]
 #[macro_use]
 extern crate scoped_tls;
 
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 6977681e5a3..2e321018407 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -191,8 +191,7 @@ mod thin;
 #[fundamental]
 #[stable(feature = "rust1", since = "1.0.0")]
 // The declaration of the `Box` struct must be kept in sync with the
-// `alloc::alloc::box_free` function or ICEs will happen. See the comment
-// on `box_free` for more details.
+// compiler or ICEs will happen.
 pub struct Box<
     T: ?Sized,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 02ecbe22b3e..ab08b483367 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -103,7 +103,6 @@
 #![feature(allocator_api)]
 #![feature(array_chunks)]
 #![feature(array_into_iter_constructors)]
-#![feature(array_methods)]
 #![feature(array_windows)]
 #![feature(ascii_char)]
 #![feature(assert_matches)]
@@ -149,7 +148,6 @@
 #![feature(set_ptr_value)]
 #![feature(sized_type_properties)]
 #![feature(slice_from_ptr_range)]
-#![feature(slice_group_by)]
 #![feature(slice_ptr_get)]
 #![feature(slice_ptr_len)]
 #![feature(slice_range)]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 7705c86001e..0338565980c 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -939,8 +939,11 @@ impl<T, A: Allocator> Rc<T, A> {
     /// it is guaranteed that exactly one of the calls returns the inner value.
     /// This means in particular that the inner value is not dropped.
     ///
-    /// This is equivalent to `Rc::try_unwrap(this).ok()`. (Note that these are not equivalent for
-    /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`.)
+    /// [`Rc::try_unwrap`] is conceptually similar to `Rc::into_inner`.
+    /// And while they are meant for different use-cases, `Rc::into_inner(this)`
+    /// is in fact equivalent to <code>[Rc::try_unwrap]\(this).[ok][Result::ok]()</code>.
+    /// (Note that the same kind of equivalence does **not** hold true for
+    /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`!)
     #[inline]
     #[stable(feature = "rc_into_inner", since = "1.70.0")]
     pub fn into_inner(this: Self) -> Option<T> {
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index aa3b7b7e191..4033f4eb068 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -51,14 +51,14 @@ pub use core::slice::{from_mut, from_ref};
 pub use core::slice::{from_mut_ptr_range, from_ptr_range};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+pub use core::slice::{ChunkBy, ChunkByMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{Chunks, Windows};
 #[stable(feature = "chunks_exact", since = "1.31.0")]
 pub use core::slice::{ChunksExact, ChunksExactMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{ChunksMut, Split, SplitMut};
-#[unstable(feature = "slice_group_by", issue = "80552")]
-pub use core::slice::{GroupBy, GroupByMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{Iter, IterMut};
 #[stable(feature = "rchunks", since = "1.31.0")]
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index 38f9f39fbf8..ade114678b7 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -30,6 +30,8 @@ pub use core::str::SplitAsciiWhitespace;
 pub use core::str::SplitInclusive;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::SplitWhitespace;
+#[unstable(feature = "str_from_raw_parts", issue = "119206")]
+pub use core::str::{from_raw_parts, from_raw_parts_mut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::str::{from_utf8, from_utf8_mut, Bytes, CharIndices, Chars};
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 48c8d9d113b..e16574f3d80 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -280,6 +280,12 @@ impl<T: ?Sized> Arc<T> {
 
 impl<T: ?Sized, A: Allocator> Arc<T, A> {
     #[inline]
+    fn internal_into_inner_with_allocator(self) -> (NonNull<ArcInner<T>>, A) {
+        let this = mem::ManuallyDrop::new(self);
+        (this.ptr, unsafe { ptr::read(&this.alloc) })
+    }
+
+    #[inline]
     unsafe fn from_inner_in(ptr: NonNull<ArcInner<T>>, alloc: A) -> Self {
         Self { ptr, phantom: PhantomData, alloc }
     }
@@ -983,9 +989,13 @@ impl<T, A: Allocator> Arc<T, A> {
     /// it is guaranteed that exactly one of the calls returns the inner value.
     /// This means in particular that the inner value is not dropped.
     ///
-    /// The similar expression `Arc::try_unwrap(this).ok()` does not
-    /// offer such a guarantee. See the last example below
-    /// and the documentation of [`Arc::try_unwrap`].
+    /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it
+    /// is meant for different use-cases. If used as a direct replacement
+    /// for `Arc::into_inner` anyway, such as with the expression
+    /// <code>[Arc::try_unwrap]\(this).[ok][Result::ok]()</code>, then it does
+    /// **not** give the same guarantee as described in the previous paragraph.
+    /// For more information, see the examples below and read the documentation
+    /// of [`Arc::try_unwrap`].
     ///
     /// # Examples
     ///
@@ -1271,12 +1281,9 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
-    pub unsafe fn assume_init(self) -> Arc<T, A>
-    where
-        A: Clone,
-    {
-        let md_self = mem::ManuallyDrop::new(self);
-        unsafe { Arc::from_inner_in(md_self.ptr.cast(), md_self.alloc.clone()) }
+    pub unsafe fn assume_init(self) -> Arc<T, A> {
+        let (ptr, alloc) = self.internal_into_inner_with_allocator();
+        unsafe { Arc::from_inner_in(ptr.cast(), alloc) }
     }
 }
 
@@ -1316,12 +1323,9 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
-    pub unsafe fn assume_init(self) -> Arc<[T], A>
-    where
-        A: Clone,
-    {
-        let md_self = mem::ManuallyDrop::new(self);
-        unsafe { Arc::from_ptr_in(md_self.ptr.as_ptr() as _, md_self.alloc.clone()) }
+    pub unsafe fn assume_init(self) -> Arc<[T], A> {
+        let (ptr, alloc) = self.internal_into_inner_with_allocator();
+        unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) }
     }
 }
 
@@ -2409,7 +2413,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Arc<T, A> {
     }
 }
 
-impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
+impl<A: Allocator> Arc<dyn Any + Send + Sync, A> {
     /// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
     ///
     /// # Examples
@@ -2436,10 +2440,8 @@ impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
     {
         if (*self).is::<T>() {
             unsafe {
-                let ptr = self.ptr.cast::<ArcInner<T>>();
-                let alloc = self.alloc.clone();
-                mem::forget(self);
-                Ok(Arc::from_inner_in(ptr, alloc))
+                let (ptr, alloc) = self.internal_into_inner_with_allocator();
+                Ok(Arc::from_inner_in(ptr.cast(), alloc))
             }
         } else {
             Err(self)
@@ -2479,10 +2481,8 @@ impl<A: Allocator + Clone> Arc<dyn Any + Send + Sync, A> {
         T: Any + Send + Sync,
     {
         unsafe {
-            let ptr = self.ptr.cast::<ArcInner<T>>();
-            let alloc = self.alloc.clone();
-            mem::forget(self);
-            Arc::from_inner_in(ptr, alloc)
+            let (ptr, alloc) = self.internal_into_inner_with_allocator();
+            Arc::from_inner_in(ptr.cast(), alloc)
         }
     }
 }
@@ -3438,13 +3438,13 @@ impl From<Arc<str>> for Arc<[u8]> {
 }
 
 #[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
-impl<T, A: Allocator + Clone, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
+impl<T, A: Allocator, const N: usize> TryFrom<Arc<[T], A>> for Arc<[T; N], A> {
     type Error = Arc<[T], A>;
 
     fn try_from(boxed_slice: Arc<[T], A>) -> Result<Self, Self::Error> {
         if boxed_slice.len() == N {
-            let alloc = boxed_slice.alloc.clone();
-            Ok(unsafe { Arc::from_raw_in(Arc::into_raw(boxed_slice) as *mut [T; N], alloc) })
+            let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator();
+            Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) })
         } else {
             Err(boxed_slice)
         }
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs
index d37e45569cf..49eae718c16 100644
--- a/library/alloc/src/sync/tests.rs
+++ b/library/alloc/src/sync/tests.rs
@@ -1,13 +1,15 @@
 use super::*;
 
 use std::clone::Clone;
+use std::mem::MaybeUninit;
 use std::option::Option::None;
+use std::sync::atomic::AtomicUsize;
 use std::sync::atomic::Ordering::SeqCst;
 use std::sync::mpsc::channel;
 use std::sync::Mutex;
 use std::thread;
 
-struct Canary(*mut atomic::AtomicUsize);
+struct Canary(*mut AtomicUsize);
 
 impl Drop for Canary {
     fn drop(&mut self) {
@@ -21,6 +23,37 @@ impl Drop for Canary {
     }
 }
 
+struct AllocCanary<'a>(&'a AtomicUsize);
+
+impl<'a> AllocCanary<'a> {
+    fn new(counter: &'a AtomicUsize) -> Self {
+        counter.fetch_add(1, SeqCst);
+        Self(counter)
+    }
+}
+
+unsafe impl Allocator for AllocCanary<'_> {
+    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+        std::alloc::Global.allocate(layout)
+    }
+
+    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
+        unsafe { std::alloc::Global.deallocate(ptr, layout) }
+    }
+}
+
+impl Clone for AllocCanary<'_> {
+    fn clone(&self) -> Self {
+        Self::new(self.0)
+    }
+}
+
+impl Drop for AllocCanary<'_> {
+    fn drop(&mut self) {
+        self.0.fetch_sub(1, SeqCst);
+    }
+}
+
 #[test]
 #[cfg_attr(target_os = "emscripten", ignore)]
 fn manually_share_arc() {
@@ -295,16 +328,16 @@ fn weak_self_cyclic() {
 
 #[test]
 fn drop_arc() {
-    let mut canary = atomic::AtomicUsize::new(0);
-    let x = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    let mut canary = AtomicUsize::new(0);
+    let x = Arc::new(Canary(&mut canary as *mut AtomicUsize));
     drop(x);
     assert!(canary.load(Acquire) == 1);
 }
 
 #[test]
 fn drop_arc_weak() {
-    let mut canary = atomic::AtomicUsize::new(0);
-    let arc = Arc::new(Canary(&mut canary as *mut atomic::AtomicUsize));
+    let mut canary = AtomicUsize::new(0);
+    let arc = Arc::new(Canary(&mut canary as *mut AtomicUsize));
     let arc_weak = Arc::downgrade(&arc);
     assert!(canary.load(Acquire) == 0);
     drop(arc);
@@ -660,3 +693,25 @@ fn arc_drop_dereferenceable_race() {
         thread.join().unwrap();
     }
 }
+
+#[test]
+fn arc_doesnt_leak_allocator() {
+    let counter = AtomicUsize::new(0);
+
+    {
+        let arc: Arc<dyn Any + Send + Sync, _> = Arc::new_in(5usize, AllocCanary::new(&counter));
+        drop(arc.downcast::<usize>().unwrap());
+
+        let arc: Arc<dyn Any + Send + Sync, _> = Arc::new_in(5usize, AllocCanary::new(&counter));
+        drop(unsafe { arc.downcast_unchecked::<usize>() });
+
+        let arc = Arc::new_in(MaybeUninit::<usize>::new(5usize), AllocCanary::new(&counter));
+        drop(unsafe { arc.assume_init() });
+
+        let arc: Arc<[MaybeUninit<usize>], _> =
+            Arc::new_zeroed_slice_in(5, AllocCanary::new(&counter));
+        drop(unsafe { arc.assume_init() });
+    }
+
+    assert_eq!(counter.load(SeqCst), 0);
+}
diff --git a/library/alloc/src/vec/cow.rs b/library/alloc/src/vec/cow.rs
index 2c799605b7b..b12910f3690 100644
--- a/library/alloc/src/vec/cow.rs
+++ b/library/alloc/src/vec/cow.rs
@@ -15,6 +15,19 @@ impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> {
     }
 }
 
+#[stable(feature = "cow_from_array_ref", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: Clone, const N: usize> From<&'a [T; N]> for Cow<'a, [T]> {
+    /// Creates a [`Borrowed`] variant of [`Cow`]
+    /// from a reference to an array.
+    ///
+    /// This conversion does not allocate or clone the data.
+    ///
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
+    fn from(s: &'a [T; N]) -> Cow<'a, [T]> {
+        Cow::Borrowed(s as &[_])
+    }
+}
+
 #[stable(feature = "cow_from_vec", since = "1.8.0")]
 impl<'a, T: Clone> From<Vec<T>> for Cow<'a, [T]> {
     /// Creates an [`Owned`] variant of [`Cow`]
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 6ca0dca1e9d..a360c430946 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2204,14 +2204,6 @@ impl<T, A: Allocator> Vec<T, A> {
             assert_failed(at, self.len());
         }
 
-        if at == 0 {
-            // the new vector can take over the original buffer and avoid the copy
-            return mem::replace(
-                self,
-                Vec::with_capacity_in(self.capacity(), self.allocator().clone()),
-            );
-        }
-
         let other_len = self.len - at;
         let mut other = Vec::with_capacity_in(other_len, self.allocator().clone());
 
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 2dcfc6b4abf..ca17dab55b0 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -29,7 +29,6 @@
 #![feature(iter_advance_by)]
 #![feature(iter_next_chunk)]
 #![feature(round_char_boundary)]
-#![feature(slice_group_by)]
 #![feature(slice_partition_dedup)]
 #![feature(string_remove_matches)]
 #![feature(const_btree_len)]
diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs
index 784839a3ffa..c0f7a11a93e 100644
--- a/library/alloc/tests/slice.rs
+++ b/library/alloc/tests/slice.rs
@@ -1614,10 +1614,10 @@ fn subslice_patterns() {
 }
 
 #[test]
-fn test_group_by() {
+fn test_chunk_by() {
     let slice = &[1, 1, 1, 3, 3, 2, 2, 2, 1, 0];
 
-    let mut iter = slice.group_by(|a, b| a == b);
+    let mut iter = slice.chunk_by(|a, b| a == b);
     assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
     assert_eq!(iter.next(), Some(&[3, 3][..]));
     assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
@@ -1625,7 +1625,7 @@ fn test_group_by() {
     assert_eq!(iter.next(), Some(&[0][..]));
     assert_eq!(iter.next(), None);
 
-    let mut iter = slice.group_by(|a, b| a == b);
+    let mut iter = slice.chunk_by(|a, b| a == b);
     assert_eq!(iter.next_back(), Some(&[0][..]));
     assert_eq!(iter.next_back(), Some(&[1][..]));
     assert_eq!(iter.next_back(), Some(&[2, 2, 2][..]));
@@ -1633,7 +1633,7 @@ fn test_group_by() {
     assert_eq!(iter.next_back(), Some(&[1, 1, 1][..]));
     assert_eq!(iter.next_back(), None);
 
-    let mut iter = slice.group_by(|a, b| a == b);
+    let mut iter = slice.chunk_by(|a, b| a == b);
     assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
     assert_eq!(iter.next_back(), Some(&[0][..]));
     assert_eq!(iter.next(), Some(&[3, 3][..]));
@@ -1643,10 +1643,10 @@ fn test_group_by() {
 }
 
 #[test]
-fn test_group_by_mut() {
+fn test_chunk_by_mut() {
     let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2, 1, 0];
 
-    let mut iter = slice.group_by_mut(|a, b| a == b);
+    let mut iter = slice.chunk_by_mut(|a, b| a == b);
     assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
     assert_eq!(iter.next(), Some(&mut [3, 3][..]));
     assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
@@ -1654,7 +1654,7 @@ fn test_group_by_mut() {
     assert_eq!(iter.next(), Some(&mut [0][..]));
     assert_eq!(iter.next(), None);
 
-    let mut iter = slice.group_by_mut(|a, b| a == b);
+    let mut iter = slice.chunk_by_mut(|a, b| a == b);
     assert_eq!(iter.next_back(), Some(&mut [0][..]));
     assert_eq!(iter.next_back(), Some(&mut [1][..]));
     assert_eq!(iter.next_back(), Some(&mut [2, 2, 2][..]));
@@ -1662,7 +1662,7 @@ fn test_group_by_mut() {
     assert_eq!(iter.next_back(), Some(&mut [1, 1, 1][..]));
     assert_eq!(iter.next_back(), None);
 
-    let mut iter = slice.group_by_mut(|a, b| a == b);
+    let mut iter = slice.chunk_by_mut(|a, b| a == b);
     assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
     assert_eq!(iter.next_back(), Some(&mut [0][..]));
     assert_eq!(iter.next(), Some(&mut [3, 3][..]));
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index d5ae8cdac1f..38a68df79cc 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -958,23 +958,35 @@ fn test_append() {
 #[test]
 fn test_split_off() {
     let mut vec = vec![1, 2, 3, 4, 5, 6];
+    let orig_ptr = vec.as_ptr();
     let orig_capacity = vec.capacity();
-    let vec2 = vec.split_off(4);
+
+    let split_off = vec.split_off(4);
     assert_eq!(vec, [1, 2, 3, 4]);
-    assert_eq!(vec2, [5, 6]);
+    assert_eq!(split_off, [5, 6]);
     assert_eq!(vec.capacity(), orig_capacity);
+    assert_eq!(vec.as_ptr(), orig_ptr);
 }
 
 #[test]
 fn test_split_off_take_all() {
-    let mut vec = vec![1, 2, 3, 4, 5, 6];
+    // Allocate enough capacity that we can tell whether the split-off vector's
+    // capacity is based on its size, or (incorrectly) on the original capacity.
+    let mut vec = Vec::with_capacity(1000);
+    vec.extend([1, 2, 3, 4, 5, 6]);
     let orig_ptr = vec.as_ptr();
     let orig_capacity = vec.capacity();
-    let vec2 = vec.split_off(0);
+
+    let split_off = vec.split_off(0);
     assert_eq!(vec, []);
-    assert_eq!(vec2, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(split_off, [1, 2, 3, 4, 5, 6]);
     assert_eq!(vec.capacity(), orig_capacity);
-    assert_eq!(vec2.as_ptr(), orig_ptr);
+    assert_eq!(vec.as_ptr(), orig_ptr);
+
+    // The split-off vector should be newly-allocated, and should not have
+    // stolen the original vector's allocation.
+    assert!(split_off.capacity() < orig_capacity);
+    assert_ne!(split_off.as_ptr(), orig_ptr);
 }
 
 #[test]
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 9d95b32409c..85cce81f2c1 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -559,8 +559,6 @@ impl<T, const N: usize> [T; N] {
     /// # Example
     ///
     /// ```
-    /// #![feature(array_methods)]
-    ///
     /// let floats = [3.1, 2.7, -1.0];
     /// let float_refs: [&f64; 3] = floats.each_ref();
     /// assert_eq!(float_refs, [&3.1, &2.7, &-1.0]);
@@ -571,8 +569,6 @@ impl<T, const N: usize> [T; N] {
     /// array if its elements are not [`Copy`].
     ///
     /// ```
-    /// #![feature(array_methods)]
-    ///
     /// let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
     /// let is_ascii = strings.each_ref().map(|s| s.is_ascii());
     /// assert_eq!(is_ascii, [true, false, true]);
@@ -580,7 +576,7 @@ impl<T, const N: usize> [T; N] {
     /// // We can still access the original array: it has not been moved.
     /// assert_eq!(strings.len(), 3);
     /// ```
-    #[unstable(feature = "array_methods", issue = "76118")]
+    #[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn each_ref(&self) -> [&T; N] {
         from_trusted_iterator(self.iter())
     }
@@ -592,7 +588,6 @@ impl<T, const N: usize> [T; N] {
     /// # Example
     ///
     /// ```
-    /// #![feature(array_methods)]
     ///
     /// let mut floats = [3.1, 2.7, -1.0];
     /// let float_refs: [&mut f64; 3] = floats.each_mut();
@@ -600,7 +595,7 @@ impl<T, const N: usize> [T; N] {
     /// assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]);
     /// assert_eq!(floats, [0.0, 2.7, -1.0]);
     /// ```
-    #[unstable(feature = "array_methods", issue = "76118")]
+    #[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn each_mut(&mut self) -> [&mut T; N] {
         from_trusted_iterator(self.iter_mut())
     }
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index cc872a5343d..5f758af1624 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -537,6 +537,22 @@ impl AsciiChar {
     }
 }
 
+macro_rules! into_int_impl {
+    ($($ty:ty)*) => {
+        $(
+            #[unstable(feature = "ascii_char", issue = "110998")]
+            impl From<AsciiChar> for $ty {
+                #[inline]
+                fn from(chr: AsciiChar) -> $ty {
+                    chr as u8 as $ty
+                }
+            }
+        )*
+    }
+}
+
+into_int_impl!(u8 u16 u32 u64 u128 char);
+
 impl [AsciiChar] {
     /// Views this slice of ASCII characters as a UTF-8 `str`.
     #[unstable(feature = "ascii_char", issue = "110998")]
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index 7340ad90da5..44200926a32 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -11,7 +11,6 @@
 
 use crate::fmt;
 use crate::marker::PhantomData;
-use crate::num::*;
 use crate::ops::{Deref, DerefMut};
 
 #[stable(feature = "core_c_str", since = "1.64.0")]
@@ -19,7 +18,7 @@ pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError};
 
 mod c_str;
 
-macro_rules! type_alias_no_nz {
+macro_rules! type_alias {
     {
       $Docfile:tt, $Alias:ident = $Real:ty;
       $( $Cfg:tt )*
@@ -31,49 +30,24 @@ macro_rules! type_alias_no_nz {
     }
 }
 
-// To verify that the NonZero types in this file's macro invocations correspond
-//
-//  perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2'
-//
-// NB this does not check that the main c_* types are right.
-
-macro_rules! type_alias {
-    {
-      $Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
-      $( $Cfg:tt )*
-    } => {
-        type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* }
-
-        #[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")]
-        #[unstable(feature = "raw_os_nonzero", issue = "82363")]
-        $( $Cfg )*
-        pub type $NZAlias = $NZReal;
-    }
-}
-
-type_alias! { "c_char.md", c_char = c_char_definition::c_char, NonZero_c_char = c_char_definition::NonZero_c_char;
-#[doc(cfg(all()))] }
+type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
 
-type_alias! { "c_schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; }
-type_alias! { "c_uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
-type_alias! { "c_short.md", c_short = i16, NonZero_c_short = NonZeroI16; }
-type_alias! { "c_ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
+type_alias! { "c_schar.md", c_schar = i8; }
+type_alias! { "c_uchar.md", c_uchar = u8; }
+type_alias! { "c_short.md", c_short = i16; }
+type_alias! { "c_ushort.md", c_ushort = u16; }
 
-type_alias! { "c_int.md", c_int = c_int_definition::c_int, NonZero_c_int = c_int_definition::NonZero_c_int;
-#[doc(cfg(all()))] }
-type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint, NonZero_c_uint = c_int_definition::NonZero_c_uint;
-#[doc(cfg(all()))] }
+type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
+type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
 
-type_alias! { "c_long.md", c_long = c_long_definition::c_long, NonZero_c_long = c_long_definition::NonZero_c_long;
-#[doc(cfg(all()))] }
-type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong, NonZero_c_ulong = c_long_definition::NonZero_c_ulong;
-#[doc(cfg(all()))] }
+type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
+type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
 
-type_alias! { "c_longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
-type_alias! { "c_ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
+type_alias! { "c_longlong.md", c_longlong = i64; }
+type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
 
-type_alias_no_nz! { "c_float.md", c_float = f32; }
-type_alias_no_nz! { "c_double.md", c_double = f64; }
+type_alias! { "c_float.md", c_float = f32; }
+type_alias! { "c_double.md", c_double = f64; }
 
 /// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
 ///
@@ -152,11 +126,9 @@ mod c_char_definition {
             target_os = "horizon"
         ))] {
             pub type c_char = u8;
-            pub type NonZero_c_char = crate::num::NonZeroU8;
         } else {
             // On every other target, c_char is signed.
             pub type c_char = i8;
-            pub type NonZero_c_char = crate::num::NonZeroI8;
         }
     }
 }
@@ -165,14 +137,10 @@ mod c_int_definition {
     cfg_if! {
         if #[cfg(any(target_arch = "avr", target_arch = "msp430"))] {
             pub type c_int = i16;
-            pub type NonZero_c_int = crate::num::NonZeroI16;
             pub type c_uint = u16;
-            pub type NonZero_c_uint = crate::num::NonZeroU16;
         } else {
             pub type c_int = i32;
-            pub type NonZero_c_int = crate::num::NonZeroI32;
             pub type c_uint = u32;
-            pub type NonZero_c_uint = crate::num::NonZeroU32;
         }
     }
 }
@@ -181,15 +149,11 @@ mod c_long_definition {
     cfg_if! {
         if #[cfg(all(target_pointer_width = "64", not(windows)))] {
             pub type c_long = i64;
-            pub type NonZero_c_long = crate::num::NonZeroI64;
             pub type c_ulong = u64;
-            pub type NonZero_c_ulong = crate::num::NonZeroU64;
         } else {
             // The minimal size of `long` in the C standard is 32 bits
             pub type c_long = i32;
-            pub type NonZero_c_long = crate::num::NonZeroI32;
             pub type c_ulong = u32;
-            pub type NonZero_c_ulong = crate::num::NonZeroU32;
         }
     }
 }
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 76a53a9366a..43124535ab5 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2531,7 +2531,7 @@ extern "rust-intrinsic" {
     /// or `false`, and the caller has to ensure sound behavior for both cases.
     /// In other words, the following code has *Undefined Behavior*:
     ///
-    /// ```
+    /// ```no_run
     /// #![feature(is_val_statically_known)]
     /// #![feature(core_intrinsics)]
     /// # #![allow(internal_features)]
diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs
index d8bbd424cf2..c97a59b614f 100644
--- a/library/core/src/iter/adapters/intersperse.rs
+++ b/library/core/src/iter/adapters/intersperse.rs
@@ -1,4 +1,5 @@
-use super::Peekable;
+use crate::fmt;
+use crate::iter::{Fuse, FusedIterator};
 
 /// An iterator adapter that places a separator between all elements.
 ///
@@ -10,9 +11,18 @@ pub struct Intersperse<I: Iterator>
 where
     I::Item: Clone,
 {
+    started: bool,
     separator: I::Item,
-    iter: Peekable<I>,
-    needs_sep: bool,
+    next_item: Option<I::Item>,
+    iter: Fuse<I>,
+}
+
+#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
+impl<I> FusedIterator for Intersperse<I>
+where
+    I: FusedIterator,
+    I::Item: Clone,
+{
 }
 
 impl<I: Iterator> Intersperse<I>
@@ -20,7 +30,7 @@ where
     I::Item: Clone,
 {
     pub(in crate::iter) fn new(iter: I, separator: I::Item) -> Self {
-        Self { iter: iter.peekable(), separator, needs_sep: false }
+        Self { started: false, separator, next_item: None, iter: iter.fuse() }
     }
 }
 
@@ -33,27 +43,43 @@ where
     type Item = I::Item;
 
     #[inline]
-    fn next(&mut self) -> Option<I::Item> {
-        if self.needs_sep && self.iter.peek().is_some() {
-            self.needs_sep = false;
-            Some(self.separator.clone())
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.started {
+            if let Some(v) = self.next_item.take() {
+                Some(v)
+            } else {
+                let next_item = self.iter.next();
+                if next_item.is_some() {
+                    self.next_item = next_item;
+                    Some(self.separator.clone())
+                } else {
+                    None
+                }
+            }
         } else {
-            self.needs_sep = true;
+            self.started = true;
             self.iter.next()
         }
     }
 
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        intersperse_size_hint(&self.iter, self.started, self.next_item.is_some())
+    }
+
     fn fold<B, F>(self, init: B, f: F) -> B
     where
         Self: Sized,
         F: FnMut(B, Self::Item) -> B,
     {
         let separator = self.separator;
-        intersperse_fold(self.iter, init, f, move || separator.clone(), self.needs_sep)
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        intersperse_size_hint(&self.iter, self.needs_sep)
+        intersperse_fold(
+            self.iter,
+            init,
+            f,
+            move || separator.clone(),
+            self.started,
+            self.next_item,
+        )
     }
 }
 
@@ -66,39 +92,50 @@ pub struct IntersperseWith<I, G>
 where
     I: Iterator,
 {
+    started: bool,
     separator: G,
-    iter: Peekable<I>,
-    needs_sep: bool,
+    next_item: Option<I::Item>,
+    iter: Fuse<I>,
+}
+
+#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
+impl<I, G> FusedIterator for IntersperseWith<I, G>
+where
+    I: FusedIterator,
+    G: FnMut() -> I::Item,
+{
 }
 
 #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
-impl<I, G> crate::fmt::Debug for IntersperseWith<I, G>
+impl<I, G> fmt::Debug for IntersperseWith<I, G>
 where
-    I: Iterator + crate::fmt::Debug,
-    I::Item: crate::fmt::Debug,
-    G: crate::fmt::Debug,
+    I: Iterator + fmt::Debug,
+    I::Item: fmt::Debug,
+    G: fmt::Debug,
 {
-    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("IntersperseWith")
+            .field("started", &self.started)
             .field("separator", &self.separator)
             .field("iter", &self.iter)
-            .field("needs_sep", &self.needs_sep)
+            .field("next_item", &self.next_item)
             .finish()
     }
 }
 
 #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
-impl<I, G> crate::clone::Clone for IntersperseWith<I, G>
+impl<I, G> Clone for IntersperseWith<I, G>
 where
-    I: Iterator + crate::clone::Clone,
-    I::Item: crate::clone::Clone,
+    I: Iterator + Clone,
+    I::Item: Clone,
     G: Clone,
 {
     fn clone(&self) -> Self {
-        IntersperseWith {
+        Self {
+            started: self.started,
             separator: self.separator.clone(),
             iter: self.iter.clone(),
-            needs_sep: self.needs_sep.clone(),
+            next_item: self.next_item.clone(),
         }
     }
 }
@@ -109,7 +146,7 @@ where
     G: FnMut() -> I::Item,
 {
     pub(in crate::iter) fn new(iter: I, separator: G) -> Self {
-        Self { iter: iter.peekable(), separator, needs_sep: false }
+        Self { started: false, separator, next_item: None, iter: iter.fuse() }
     }
 }
 
@@ -122,38 +159,52 @@ where
     type Item = I::Item;
 
     #[inline]
-    fn next(&mut self) -> Option<I::Item> {
-        if self.needs_sep && self.iter.peek().is_some() {
-            self.needs_sep = false;
-            Some((self.separator)())
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.started {
+            if let Some(v) = self.next_item.take() {
+                Some(v)
+            } else {
+                let next_item = self.iter.next();
+                if next_item.is_some() {
+                    self.next_item = next_item;
+                    Some((self.separator)())
+                } else {
+                    None
+                }
+            }
         } else {
-            self.needs_sep = true;
+            self.started = true;
             self.iter.next()
         }
     }
 
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        intersperse_size_hint(&self.iter, self.started, self.next_item.is_some())
+    }
+
     fn fold<B, F>(self, init: B, f: F) -> B
     where
         Self: Sized,
         F: FnMut(B, Self::Item) -> B,
     {
-        intersperse_fold(self.iter, init, f, self.separator, self.needs_sep)
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        intersperse_size_hint(&self.iter, self.needs_sep)
+        intersperse_fold(self.iter, init, f, self.separator, self.started, self.next_item)
     }
 }
 
-fn intersperse_size_hint<I>(iter: &I, needs_sep: bool) -> (usize, Option<usize>)
+fn intersperse_size_hint<I>(iter: &I, started: bool, next_is_some: bool) -> (usize, Option<usize>)
 where
     I: Iterator,
 {
     let (lo, hi) = iter.size_hint();
-    let next_is_elem = !needs_sep;
     (
-        lo.saturating_sub(next_is_elem as usize).saturating_add(lo),
-        hi.and_then(|hi| hi.saturating_sub(next_is_elem as usize).checked_add(hi)),
+        lo.saturating_sub(!started as usize)
+            .saturating_add(next_is_some as usize)
+            .saturating_add(lo),
+        hi.and_then(|hi| {
+            hi.saturating_sub(!started as usize)
+                .saturating_add(next_is_some as usize)
+                .checked_add(hi)
+        }),
     )
 }
 
@@ -162,7 +213,8 @@ fn intersperse_fold<I, B, F, G>(
     init: B,
     mut f: F,
     mut separator: G,
-    needs_sep: bool,
+    started: bool,
+    mut next_item: Option<I::Item>,
 ) -> B
 where
     I: Iterator,
@@ -171,12 +223,9 @@ where
 {
     let mut accum = init;
 
-    if !needs_sep {
-        if let Some(x) = iter.next() {
-            accum = f(accum, x);
-        } else {
-            return accum;
-        }
+    let first = if started { next_item.take() } else { iter.next() };
+    if let Some(x) = first {
+        accum = f(accum, x);
     }
 
     iter.fold(accum, |mut accum, x| {
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index 408002d18ca..959c3289aff 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1893,7 +1893,6 @@ impl Ipv6Addr {
     /// # Examples
     ///
     /// ```
-    /// #![feature(ip)]
     /// use std::net::Ipv6Addr;
     ///
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false);
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index c2b646b9b3e..03c977abbbb 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -61,7 +61,15 @@ pub use dec2flt::ParseFloatError;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use error::ParseIntError;
 
-pub(crate) use nonzero::NonZero;
+#[unstable(
+    feature = "nonzero_internals",
+    reason = "implementation detail which may disappear or be replaced at any time",
+    issue = "none"
+)]
+pub use nonzero::ZeroablePrimitive;
+
+#[unstable(feature = "generic_nonzero", issue = "120257")]
+pub use nonzero::NonZero;
 
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 45ac544ceaa..1124719fc8d 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -3,6 +3,8 @@
 use crate::cmp::Ordering;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
+#[cfg(bootstrap)]
+use crate::marker::StructuralEq;
 use crate::marker::StructuralPartialEq;
 use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
 use crate::str::FromStr;
@@ -30,9 +32,7 @@ mod private {
     issue = "none"
 )]
 #[const_trait]
-pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {
-    type NonZero;
-}
+pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {}
 
 macro_rules! impl_zeroable_primitive {
     ($NonZero:ident ( $primitive:ty )) => {
@@ -48,9 +48,7 @@ macro_rules! impl_zeroable_primitive {
             reason = "implementation detail which may disappear or be replaced at any time",
             issue = "none"
         )]
-        impl const ZeroablePrimitive for $primitive {
-            type NonZero = $NonZero;
-        }
+        impl const ZeroablePrimitive for $primitive {}
     };
 }
 
@@ -67,12 +65,23 @@ impl_zeroable_primitive!(NonZeroI64(i64));
 impl_zeroable_primitive!(NonZeroI128(i128));
 impl_zeroable_primitive!(NonZeroIsize(isize));
 
-#[unstable(
-    feature = "nonzero_internals",
-    reason = "implementation detail which may disappear or be replaced at any time",
-    issue = "none"
-)]
-pub(crate) type NonZero<T> = <T as ZeroablePrimitive>::NonZero;
+/// A value that is known not to equal zero.
+///
+/// This enables some memory layout optimization.
+/// For example, `Option<NonZero<u32>>` is the same size as `u32`:
+///
+/// ```
+/// #![feature(generic_nonzero)]
+/// use core::mem::size_of;
+///
+/// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
+/// ```
+#[unstable(feature = "generic_nonzero", issue = "120257")]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(1)]
+#[rustc_nonnull_optimization_guaranteed]
+#[rustc_diagnostic_item = "NonZero"]
+pub struct NonZero<T: ZeroablePrimitive>(T);
 
 macro_rules! impl_nonzero_fmt {
     ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
@@ -131,12 +140,7 @@ macro_rules! nonzero_integer {
         ///
         /// [null pointer optimization]: crate::option#representation
         #[$stability]
-        #[derive(Copy, Eq)]
-        #[repr(transparent)]
-        #[rustc_layout_scalar_valid_range_start(1)]
-        #[rustc_nonnull_optimization_guaranteed]
-        #[rustc_diagnostic_item = stringify!($Ty)]
-        pub struct $Ty($Int);
+        pub type $Ty = NonZero<$Int>;
 
         impl $Ty {
             /// Creates a non-zero without checking whether the value is non-zero.
@@ -544,6 +548,9 @@ macro_rules! nonzero_integer {
         }
 
         #[$stability]
+        impl Copy for $Ty {}
+
+        #[$stability]
         impl PartialEq for $Ty {
             #[inline]
             fn eq(&self, other: &Self) -> bool {
@@ -560,6 +567,13 @@ macro_rules! nonzero_integer {
         impl StructuralPartialEq for $Ty {}
 
         #[$stability]
+        impl Eq for $Ty {}
+
+        #[unstable(feature = "structural_match", issue = "31434")]
+        #[cfg(bootstrap)]
+        impl StructuralEq for $Ty {}
+
+        #[$stability]
         impl PartialOrd for $Ty {
             #[inline]
             fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index bb6c81a486a..a0227d9130b 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1092,14 +1092,20 @@ pub struct Pin<Ptr> {
     //   - deter downstream users from accessing it (which would be unsound!),
     //   - let the `pin!` macro access it (such a macro requires using struct
     //     literal syntax in order to benefit from lifetime extension).
-    // Long-term, `unsafe` fields or macro hygiene are expected to offer more robust alternatives.
+    //
+    // However, if the `Deref` impl exposes a field with the same name as this
+    // field, then the two will collide, resulting in a confusing error when the
+    // user attempts to access the field through a `Pin<Ptr>`. Therefore, the
+    // name `__pointer` is designed to be unlikely to collide with any other
+    // field. Long-term, macro hygiene is expected to offer a more robust
+    // alternative, alongside `unsafe` fields.
     #[unstable(feature = "unsafe_pin_internals", issue = "none")]
     #[doc(hidden)]
-    pub pointer: Ptr,
+    pub __pointer: Ptr,
 }
 
 // The following implementations aren't derived in order to avoid soundness
-// issues. `&self.pointer` should not be accessible to untrusted trait
+// issues. `&self.__pointer` should not be accessible to untrusted trait
 // implementations.
 //
 // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> for more details.
@@ -1212,7 +1218,7 @@ impl<Ptr: Deref<Target: Unpin>> Pin<Ptr> {
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin_into_inner", since = "1.39.0")]
     pub const fn into_inner(pin: Pin<Ptr>) -> Ptr {
-        pin.pointer
+        pin.__pointer
     }
 }
 
@@ -1349,7 +1355,7 @@ impl<Ptr: Deref> Pin<Ptr> {
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin", since = "1.33.0")]
     pub const unsafe fn new_unchecked(pointer: Ptr) -> Pin<Ptr> {
-        Pin { pointer }
+        Pin { __pointer: pointer }
     }
 
     /// Gets a shared reference to the pinned value this [`Pin`] points to.
@@ -1363,7 +1369,7 @@ impl<Ptr: Deref> Pin<Ptr> {
     #[inline(always)]
     pub fn as_ref(&self) -> Pin<&Ptr::Target> {
         // SAFETY: see documentation on this function
-        unsafe { Pin::new_unchecked(&*self.pointer) }
+        unsafe { Pin::new_unchecked(&*self.__pointer) }
     }
 
     /// Unwraps this `Pin<Ptr>`, returning the underlying `Ptr`.
@@ -1388,7 +1394,7 @@ impl<Ptr: Deref> Pin<Ptr> {
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin_into_inner", since = "1.39.0")]
     pub const unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr {
-        pin.pointer
+        pin.__pointer
     }
 }
 
@@ -1426,7 +1432,7 @@ impl<Ptr: DerefMut> Pin<Ptr> {
     #[inline(always)]
     pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target> {
         // SAFETY: see documentation on this function
-        unsafe { Pin::new_unchecked(&mut *self.pointer) }
+        unsafe { Pin::new_unchecked(&mut *self.__pointer) }
     }
 
     /// Assigns a new value to the memory location pointed to by the `Pin<Ptr>`.
@@ -1455,7 +1461,7 @@ impl<Ptr: DerefMut> Pin<Ptr> {
     where
         Ptr::Target: Sized,
     {
-        *(self.pointer) = value;
+        *(self.__pointer) = value;
     }
 }
 
@@ -1481,7 +1487,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
         U: ?Sized,
         F: FnOnce(&T) -> &U,
     {
-        let pointer = &*self.pointer;
+        let pointer = &*self.__pointer;
         let new_pointer = func(pointer);
 
         // SAFETY: the safety contract for `new_unchecked` must be
@@ -1511,7 +1517,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin", since = "1.33.0")]
     pub const fn get_ref(self) -> &'a T {
-        self.pointer
+        self.__pointer
     }
 }
 
@@ -1522,7 +1528,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin", since = "1.33.0")]
     pub const fn into_ref(self) -> Pin<&'a T> {
-        Pin { pointer: self.pointer }
+        Pin { __pointer: self.__pointer }
     }
 
     /// Gets a mutable reference to the data inside of this `Pin`.
@@ -1542,7 +1548,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     where
         T: Unpin,
     {
-        self.pointer
+        self.__pointer
     }
 
     /// Gets a mutable reference to the data inside of this `Pin`.
@@ -1560,7 +1566,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     #[stable(feature = "pin", since = "1.33.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const unsafe fn get_unchecked_mut(self) -> &'a mut T {
-        self.pointer
+        self.__pointer
     }
 
     /// Construct a new pin by mapping the interior value.
@@ -1684,21 +1690,21 @@ impl<Ptr: Receiver> Receiver for Pin<Ptr> {}
 #[stable(feature = "pin", since = "1.33.0")]
 impl<Ptr: fmt::Debug> fmt::Debug for Pin<Ptr> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(&self.pointer, f)
+        fmt::Debug::fmt(&self.__pointer, f)
     }
 }
 
 #[stable(feature = "pin", since = "1.33.0")]
 impl<Ptr: fmt::Display> fmt::Display for Pin<Ptr> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&self.pointer, f)
+        fmt::Display::fmt(&self.__pointer, f)
     }
 }
 
 #[stable(feature = "pin", since = "1.33.0")]
 impl<Ptr: fmt::Pointer> fmt::Pointer for Pin<Ptr> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Pointer::fmt(&self.pointer, f)
+        fmt::Pointer::fmt(&self.__pointer, f)
     }
 }
 
@@ -1941,16 +1947,16 @@ pub macro pin($value:expr $(,)?) {
     // instead, dropped _at the end of the enscoping block_.
     // For instance,
     // ```rust
-    // let p = Pin { pointer: &mut <temporary> };
+    // let p = Pin { __pointer: &mut <temporary> };
     // ```
     // becomes:
     // ```rust
     // let mut anon = <temporary>;
-    // let p = Pin { pointer: &mut anon };
+    // let p = Pin { __pointer: &mut anon };
     // ```
     // which is *exactly* what we want.
     //
     // See https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension
     // for more info.
-    $crate::pin::Pin::<&mut _> { pointer: &mut { $value } }
+    $crate::pin::Pin::<&mut _> { __pointer: &mut { $value } }
 }
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 7dee30585e9..bf47d767a92 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1384,6 +1384,30 @@ mod prim_usize {}
 /// work on references as well as they do on owned values! The implementations described here are
 /// meant for generic contexts, where the final type `T` is a type parameter or otherwise not
 /// locally known.
+///
+/// # Safety
+///
+/// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API
+/// boundary, the following invariants must generally be upheld:
+///
+/// * `t` is aligned to `align_of_val(t)`
+/// * `t` is dereferenceable for `size_of_val(t)` many bytes
+///
+/// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range
+/// `[a, a + N)` is all contained within a single [allocated object].
+///
+/// For instance, this means that unsafe code in a safe function may assume these invariants are
+/// ensured of arguments passed by the caller, and it may assume that these invariants are ensured
+/// of return values from any safe functions it calls. In most cases, the inverse is also true:
+/// unsafe code must not violate these invariants when passing arguments to safe functions or
+/// returning values from safe functions; such violations may result in undefined behavior. Where
+/// exceptions to this latter requirement exist, they will be called out explicitly in documentation.
+///
+/// It is not decided yet whether unsafe code may violate these invariants temporarily on internal
+/// data. As a consequence, unsafe code which violates these invariants temporarily on internal data
+/// may become unsound in future versions of Rust depending on how this question is decided.
+///
+/// [allocated object]: ptr#allocated-object
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_ref {}
 
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 5ce9ddeb676..f3ceadee24c 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -285,7 +285,7 @@ impl<T: ?Sized> *const T {
         self.with_addr(f(self.addr()))
     }
 
-    /// Decompose a (possibly wide) pointer into its address and metadata components.
+    /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts`].
     #[unstable(feature = "ptr_metadata", issue = "81513")]
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 040aa069787..a6a390db043 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -39,13 +39,13 @@ use crate::hash::{Hash, Hasher};
 ///
 /// # Usage
 ///
-/// Raw pointers can be decomposed into the data address and metadata components
+/// Raw pointers can be decomposed into the data pointer and metadata components
 /// with their [`to_raw_parts`] method.
 ///
 /// Alternatively, metadata alone can be extracted with the [`metadata`] function.
 /// A reference can be passed to [`metadata`] and implicitly coerced.
 ///
-/// A (possibly-wide) pointer can be put back together from its address and metadata
+/// A (possibly-wide) pointer can be put back together from its data pointer and metadata
 /// with [`from_raw_parts`] or [`from_raw_parts_mut`].
 ///
 /// [`to_raw_parts`]: *const::to_raw_parts
@@ -98,7 +98,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
     unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
 }
 
-/// Forms a (possibly-wide) raw pointer from a data address and metadata.
+/// Forms a (possibly-wide) raw pointer from a data pointer and metadata.
 ///
 /// This function is safe but the returned pointer is not necessarily safe to dereference.
 /// For slices, see the documentation of [`slice::from_raw_parts`] for safety requirements.
@@ -109,13 +109,13 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
 #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
 #[inline]
 pub const fn from_raw_parts<T: ?Sized>(
-    data_address: *const (),
+    data_pointer: *const (),
     metadata: <T as Pointee>::Metadata,
 ) -> *const T {
     // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
     // and PtrComponents<T> have the same memory layouts. Only std can make this
     // guarantee.
-    unsafe { PtrRepr { components: PtrComponents { data_address, metadata } }.const_ptr }
+    unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
 }
 
 /// Performs the same functionality as [`from_raw_parts`], except that a
@@ -126,13 +126,13 @@ pub const fn from_raw_parts<T: ?Sized>(
 #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
 #[inline]
 pub const fn from_raw_parts_mut<T: ?Sized>(
-    data_address: *mut (),
+    data_pointer: *mut (),
     metadata: <T as Pointee>::Metadata,
 ) -> *mut T {
     // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
     // and PtrComponents<T> have the same memory layouts. Only std can make this
     // guarantee.
-    unsafe { PtrRepr { components: PtrComponents { data_address, metadata } }.mut_ptr }
+    unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
 }
 
 #[repr(C)]
@@ -144,7 +144,7 @@ union PtrRepr<T: ?Sized> {
 
 #[repr(C)]
 struct PtrComponents<T: ?Sized> {
-    data_address: *const (),
+    data_pointer: *const (),
     metadata: <T as Pointee>::Metadata,
 }
 
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 3e5678a7d91..3e47c4f440a 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -292,7 +292,7 @@ impl<T: ?Sized> *mut T {
         self.with_addr(f(self.addr()))
     }
 
-    /// Decompose a (possibly wide) pointer into its address and metadata components.
+    /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts_mut`].
     #[unstable(feature = "ptr_metadata", issue = "81513")]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 427a9f3f494..d18082c3048 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -259,16 +259,16 @@ impl<T: ?Sized> NonNull<T> {
     #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
     #[inline]
     pub const fn from_raw_parts(
-        data_address: NonNull<()>,
+        data_pointer: NonNull<()>,
         metadata: <T as super::Pointee>::Metadata,
     ) -> NonNull<T> {
-        // SAFETY: The result of `ptr::from::raw_parts_mut` is non-null because `data_address` is.
+        // SAFETY: The result of `ptr::from::raw_parts_mut` is non-null because `data_pointer` is.
         unsafe {
-            NonNull::new_unchecked(super::from_raw_parts_mut(data_address.as_ptr(), metadata))
+            NonNull::new_unchecked(super::from_raw_parts_mut(data_pointer.as_ptr(), metadata))
         }
     }
 
-    /// Decompose a (possibly wide) pointer into its address and metadata components.
+    /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
     ///
     /// The pointer can be later reconstructed with [`NonNull::from_raw_parts`].
     #[unstable(feature = "ptr_metadata", issue = "81513")]
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 1c65475b81d..2d4c7e78aea 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -3248,26 +3248,26 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
 
 /// An iterator over slice in (non-overlapping) chunks separated by a predicate.
 ///
-/// This struct is created by the [`group_by`] method on [slices].
+/// This struct is created by the [`chunk_by`] method on [slices].
 ///
-/// [`group_by`]: slice::group_by
+/// [`chunk_by`]: slice::chunk_by
 /// [slices]: slice
-#[unstable(feature = "slice_group_by", issue = "80552")]
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
-pub struct GroupBy<'a, T: 'a, P> {
+pub struct ChunkBy<'a, T: 'a, P> {
     slice: &'a [T],
     predicate: P,
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> GroupBy<'a, T, P> {
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
     pub(super) fn new(slice: &'a [T], predicate: P) -> Self {
-        GroupBy { slice, predicate }
+        ChunkBy { slice, predicate }
     }
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> Iterator for GroupBy<'a, T, P>
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
 {
@@ -3300,8 +3300,8 @@ where
     }
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> DoubleEndedIterator for GroupBy<'a, T, P>
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
 {
@@ -3322,39 +3322,39 @@ where
     }
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> FusedIterator for GroupBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupBy<'a, T, P> {
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("GroupBy").field("slice", &self.slice).finish()
+        f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
     }
 }
 
 /// An iterator over slice in (non-overlapping) mutable chunks separated
 /// by a predicate.
 ///
-/// This struct is created by the [`group_by_mut`] method on [slices].
+/// This struct is created by the [`chunk_by_mut`] method on [slices].
 ///
-/// [`group_by_mut`]: slice::group_by_mut
+/// [`chunk_by_mut`]: slice::chunk_by_mut
 /// [slices]: slice
-#[unstable(feature = "slice_group_by", issue = "80552")]
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
-pub struct GroupByMut<'a, T: 'a, P> {
+pub struct ChunkByMut<'a, T: 'a, P> {
     slice: &'a mut [T],
     predicate: P,
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> GroupByMut<'a, T, P> {
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
     pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self {
-        GroupByMut { slice, predicate }
+        ChunkByMut { slice, predicate }
     }
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> Iterator for GroupByMut<'a, T, P>
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
 {
@@ -3388,8 +3388,8 @@ where
     }
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> DoubleEndedIterator for GroupByMut<'a, T, P>
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
 {
@@ -3411,12 +3411,12 @@ where
     }
 }
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a, P> FusedIterator for GroupByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupByMut<'a, T, P> {
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("GroupByMut").field("slice", &self.slice).finish()
+        f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
     }
 }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 27dda478848..2d93ef6fbeb 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -68,8 +68,8 @@ pub use iter::{ArrayChunks, ArrayChunksMut};
 #[unstable(feature = "array_windows", issue = "75027")]
 pub use iter::ArrayWindows;
 
-#[unstable(feature = "slice_group_by", issue = "80552")]
-pub use iter::{GroupBy, GroupByMut};
+#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+pub use iter::{ChunkBy, ChunkByMut};
 
 #[stable(feature = "split_inclusive", since = "1.51.0")]
 pub use iter::{SplitInclusive, SplitInclusiveMut};
@@ -1748,18 +1748,16 @@ impl<T> [T] {
     /// Returns an iterator over the slice producing non-overlapping runs
     /// of elements using the predicate to separate them.
     ///
-    /// The predicate is called on two elements following themselves,
-    /// it means the predicate is called on `slice[0]` and `slice[1]`
-    /// then on `slice[1]` and `slice[2]` and so on.
+    /// The predicate is called for every pair of consecutive elements,
+    /// meaning that it is called on `slice[0]` and `slice[1]`,
+    /// followed by `slice[1]` and `slice[2]`, and so on.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_group_by)]
-    ///
     /// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
     ///
-    /// let mut iter = slice.group_by(|a, b| a == b);
+    /// let mut iter = slice.chunk_by(|a, b| a == b);
     ///
     /// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
     /// assert_eq!(iter.next(), Some(&[3, 3][..]));
@@ -1770,41 +1768,37 @@ impl<T> [T] {
     /// This method can be used to extract the sorted subslices:
     ///
     /// ```
-    /// #![feature(slice_group_by)]
-    ///
     /// let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
     ///
-    /// let mut iter = slice.group_by(|a, b| a <= b);
+    /// let mut iter = slice.chunk_by(|a, b| a <= b);
     ///
     /// assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
     /// assert_eq!(iter.next(), Some(&[2, 3][..]));
     /// assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
     /// assert_eq!(iter.next(), None);
     /// ```
-    #[unstable(feature = "slice_group_by", issue = "80552")]
+    #[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
-    pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>
+    pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
     where
         F: FnMut(&T, &T) -> bool,
     {
-        GroupBy::new(self, pred)
+        ChunkBy::new(self, pred)
     }
 
     /// Returns an iterator over the slice producing non-overlapping mutable
     /// runs of elements using the predicate to separate them.
     ///
-    /// The predicate is called on two elements following themselves,
-    /// it means the predicate is called on `slice[0]` and `slice[1]`
-    /// then on `slice[1]` and `slice[2]` and so on.
+    /// The predicate is called for every pair of consecutive elements,
+    /// meaning that it is called on `slice[0]` and `slice[1]`,
+    /// followed by `slice[1]` and `slice[2]`, and so on.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_group_by)]
-    ///
     /// let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
     ///
-    /// let mut iter = slice.group_by_mut(|a, b| a == b);
+    /// let mut iter = slice.chunk_by_mut(|a, b| a == b);
     ///
     /// assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
     /// assert_eq!(iter.next(), Some(&mut [3, 3][..]));
@@ -1815,24 +1809,22 @@ impl<T> [T] {
     /// This method can be used to extract the sorted subslices:
     ///
     /// ```
-    /// #![feature(slice_group_by)]
-    ///
     /// let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
     ///
-    /// let mut iter = slice.group_by_mut(|a, b| a <= b);
+    /// let mut iter = slice.chunk_by_mut(|a, b| a <= b);
     ///
     /// assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
     /// assert_eq!(iter.next(), Some(&mut [2, 3][..]));
     /// assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
     /// assert_eq!(iter.next(), None);
     /// ```
-    #[unstable(feature = "slice_group_by", issue = "80552")]
+    #[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
-    pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>
+    pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
     where
         F: FnMut(&T, &T) -> bool,
     {
-        GroupByMut::new(self, pred)
+        ChunkByMut::new(self, pred)
     }
 
     /// Divides one slice into two at an index.
diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs
index 0f23cf7ae23..ba282f09d20 100644
--- a/library/core/src/str/converts.rs
+++ b/library/core/src/str/converts.rs
@@ -1,6 +1,6 @@
 //! Ways to create a `str` from bytes slice.
 
-use crate::mem;
+use crate::{mem, ptr};
 
 use super::validations::run_utf8_validation;
 use super::Utf8Error;
@@ -205,3 +205,41 @@ pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
     // comes from a reference which is guaranteed to be valid for writes.
     unsafe { &mut *(v as *mut [u8] as *mut str) }
 }
+
+/// Creates an `&str` from a pointer and a length.
+///
+/// The pointed-to bytes must be valid UTF-8.
+/// If this might not be the case, use `str::from_utf8(slice::from_raw_parts(ptr, len))`,
+/// which will return an `Err` if the data isn't valid UTF-8.
+///
+/// This function is the `str` equivalent of [`slice::from_raw_parts`](crate::slice::from_raw_parts).
+/// See that function's documentation for safety concerns and examples.
+///
+/// The mutable version of this function is [`from_raw_parts_mut`].
+#[inline]
+#[must_use]
+#[unstable(feature = "str_from_raw_parts", issue = "119206")]
+#[rustc_const_unstable(feature = "str_from_raw_parts", issue = "119206")]
+pub const unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str {
+    // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
+    unsafe { &*ptr::from_raw_parts(ptr.cast(), len) }
+}
+
+/// Creates an `&mut str` from a pointer and a length.
+///
+/// The pointed-to bytes must be valid UTF-8.
+/// If this might not be the case, use `str::from_utf8_mut(slice::from_raw_parts_mut(ptr, len))`,
+/// which will return an `Err` if the data isn't valid UTF-8.
+///
+/// This function is the `str` equivalent of [`slice::from_raw_parts_mut`](crate::slice::from_raw_parts_mut).
+/// See that function's documentation for safety concerns and examples.
+///
+/// The immutable version of this function is [`from_raw_parts`].
+#[inline]
+#[must_use]
+#[unstable(feature = "str_from_raw_parts", issue = "119206")]
+#[rustc_const_unstable(feature = "const_str_from_raw_parts_mut", issue = "119206")]
+pub const unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a str {
+    // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
+    unsafe { &mut *ptr::from_raw_parts_mut(ptr.cast(), len) }
+}
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index dd2efb00516..4d6239e11a3 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -1187,6 +1187,31 @@ impl<'a> DoubleEndedIterator for Lines<'a> {
 #[stable(feature = "fused", since = "1.26.0")]
 impl FusedIterator for Lines<'_> {}
 
+impl<'a> Lines<'a> {
+    /// Returns the remaining lines of the split string.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(str_lines_remainder)]
+    ///
+    /// let mut lines = "a\nb\nc\nd".lines();
+    /// assert_eq!(lines.remainder(), Some("a\nb\nc\nd"));
+    ///
+    /// lines.next();
+    /// assert_eq!(lines.remainder(), Some("b\nc\nd"));
+    ///
+    /// lines.by_ref().for_each(drop);
+    /// assert_eq!(lines.remainder(), None);
+    /// ```
+    #[inline]
+    #[must_use]
+    #[unstable(feature = "str_lines_remainder", issue = "77998")]
+    pub fn remainder(&self) -> Option<&'a str> {
+        self.0.iter.remainder()
+    }
+}
+
 /// Created with the method [`lines_any`].
 ///
 /// [`lines_any`]: str::lines_any
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 80c5fe0de8d..ecc0613d7b9 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -33,6 +33,9 @@ pub use converts::{from_utf8, from_utf8_unchecked};
 #[stable(feature = "str_mut_extras", since = "1.20.0")]
 pub use converts::{from_utf8_mut, from_utf8_unchecked_mut};
 
+#[unstable(feature = "str_from_raw_parts", issue = "119206")]
+pub use converts::{from_raw_parts, from_raw_parts_mut};
+
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use error::{ParseBoolError, Utf8Error};
 
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 89d2b5ef093..9a3b477c2d1 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -1,6 +1,5 @@
 #![feature(alloc_layout_extra)]
 #![feature(array_chunks)]
-#![feature(array_methods)]
 #![feature(array_windows)]
 #![feature(ascii_char)]
 #![feature(ascii_char_variants)]
@@ -101,7 +100,6 @@
 #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
 #![cfg_attr(test, feature(cfg_match))]
 #![feature(int_roundings)]
-#![feature(slice_group_by)]
 #![feature(split_array)]
 #![feature(strict_provenance)]
 #![feature(strict_provenance_atomic_ptr)]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index fc27b6a67bf..0d4c1fa05cc 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -356,6 +356,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over keys takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
@@ -417,6 +418,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over values takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn values(&self) -> Values<'_, K, V> {
         Values { inner: self.iter() }
@@ -449,6 +451,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// In the current implementation, iterating over values takes O(capacity) time
     /// instead of O(len) because it internally visits empty buckets too.
+    #[rustc_lint_query_instability]
     #[stable(feature = "map_values_mut", since = "1.10.0")]
     pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
         ValuesMut { inner: self.iter_mut() }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index c4a92927937..80d369eb067 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -260,7 +260,8 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
     fn inner(path: &Path) -> io::Result<Vec<u8>> {
         let mut file = File::open(path)?;
         let size = file.metadata().map(|m| m.len() as usize).ok();
-        let mut bytes = Vec::with_capacity(size.unwrap_or(0));
+        let mut bytes = Vec::new();
+        bytes.try_reserve_exact(size.unwrap_or(0)).map_err(|_| io::ErrorKind::OutOfMemory)?;
         io::default_read_to_end(&mut file, &mut bytes, size)?;
         Ok(bytes)
     }
@@ -302,7 +303,8 @@ pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
     fn inner(path: &Path) -> io::Result<String> {
         let mut file = File::open(path)?;
         let size = file.metadata().map(|m| m.len() as usize).ok();
-        let mut string = String::with_capacity(size.unwrap_or(0));
+        let mut string = String::new();
+        string.try_reserve_exact(size.unwrap_or(0)).map_err(|_| io::ErrorKind::OutOfMemory)?;
         io::default_read_to_string(&mut file, &mut string, size)?;
         Ok(string)
     }
@@ -774,14 +776,14 @@ impl Read for &File {
     // Reserves space in the buffer based on the file size when available.
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         let size = buffer_capacity_required(self);
-        buf.reserve(size.unwrap_or(0));
+        buf.try_reserve_exact(size.unwrap_or(0)).map_err(|_| io::ErrorKind::OutOfMemory)?;
         io::default_read_to_end(self, buf, size)
     }
 
     // Reserves space in the buffer based on the file size when available.
     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         let size = buffer_capacity_required(self);
-        buf.reserve(size.unwrap_or(0));
+        buf.try_reserve_exact(size.unwrap_or(0)).map_err(|_| io::ErrorKind::OutOfMemory)?;
         io::default_read_to_string(self, buf, size)
     }
 }
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 6c7494a6a6f..e920500d7d0 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -345,6 +345,7 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
     // delegate to the inner implementation.
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         let inner_buf = self.buffer();
+        buf.try_reserve(inner_buf.len()).map_err(|_| io::ErrorKind::OutOfMemory)?;
         buf.extend_from_slice(inner_buf);
         let nread = inner_buf.len();
         self.discard_buffer();
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index b63091deac2..13cc0511e10 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -816,12 +816,12 @@ impl Error {
         }
     }
 
-    /// Attempt to downgrade the inner error to `E` if any.
+    /// Attempt to downcast the inner error to `E` if any.
     ///
     /// If this [`Error`] was constructed via [`new`] then this function will
     /// attempt to perform downgrade on it, otherwise it will return [`Err`].
     ///
-    /// If downgrade succeeds, it will return [`Ok`], otherwise it will also
+    /// If the downcast succeeds, it will return [`Ok`], otherwise it will also
     /// return [`Err`].
     ///
     /// [`new`]: Error::new
@@ -852,13 +852,39 @@ impl Error {
     /// impl From<io::Error> for E {
     ///     fn from(err: io::Error) -> E {
     ///         err.downcast::<E>()
-    ///             .map(|b| *b)
     ///             .unwrap_or_else(E::Io)
     ///     }
     /// }
+    ///
+    /// impl From<E> for io::Error {
+    ///     fn from(err: E) -> io::Error {
+    ///         match err {
+    ///             E::Io(io_error) => io_error,
+    ///             e => io::Error::new(io::ErrorKind::Other, e),
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// # fn main() {
+    /// let e = E::SomeOtherVariant;
+    /// // Convert it to an io::Error
+    /// let io_error = io::Error::from(e);
+    /// // Cast it back to the original variant
+    /// let e = E::from(io_error);
+    /// assert!(matches!(e, E::SomeOtherVariant));
+    ///
+    /// let io_error = io::Error::from(io::ErrorKind::AlreadyExists);
+    /// // Convert it to E
+    /// let e = E::from(io_error);
+    /// // Cast it back to the original variant
+    /// let io_error = io::Error::from(e);
+    /// assert_eq!(io_error.kind(), io::ErrorKind::AlreadyExists);
+    /// assert!(io_error.get_ref().is_none());
+    /// assert!(io_error.raw_os_error().is_none());
+    /// # }
     /// ```
     #[unstable(feature = "io_error_downcast", issue = "99262")]
-    pub fn downcast<E>(self) -> result::Result<Box<E>, Self>
+    pub fn downcast<E>(self) -> result::Result<E, Self>
     where
         E: error::Error + Send + Sync + 'static,
     {
@@ -872,7 +898,7 @@ impl Error {
                 // And the compiler should be able to eliminate the branch
                 // that produces `Err` here since b.error.is::<E>()
                 // returns true.
-                Ok(res.unwrap())
+                Ok(*res.unwrap())
             }
             repr_data => Err(Self { repr: Repr::new(repr_data) }),
         }
diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs
index 36d52aef03c..fc6db2825e8 100644
--- a/library/std/src/io/error/tests.rs
+++ b/library/std/src/io/error/tests.rs
@@ -157,7 +157,7 @@ impl error::Error for E {}
 fn test_std_io_error_downcast() {
     // Case 1: custom error, downcast succeeds
     let io_error = Error::new(ErrorKind::Other, Bojji(true));
-    let e: Box<Bojji> = io_error.downcast().unwrap();
+    let e: Bojji = io_error.downcast().unwrap();
     assert!(e.0);
 
     // Case 2: custom error, downcast fails
@@ -166,7 +166,7 @@ fn test_std_io_error_downcast() {
 
     //   ensures that the custom error is intact
     assert_eq!(ErrorKind::Other, io_error.kind());
-    let e: Box<Bojji> = io_error.downcast().unwrap();
+    let e: Bojji = io_error.downcast().unwrap();
     assert!(e.0);
 
     // Case 3: os error
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index d8c8d933eb4..557e64dc867 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -303,8 +303,9 @@ impl Read for &[u8] {
 
     #[inline]
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
-        buf.extend_from_slice(*self);
         let len = self.len();
+        buf.try_reserve(len).map_err(|_| ErrorKind::OutOfMemory)?;
+        buf.extend_from_slice(*self);
         *self = &self[len..];
         Ok(len)
     }
@@ -451,7 +452,7 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         // The total len is known upfront so we can reserve it in a single call.
         let len = self.len();
-        buf.reserve(len);
+        buf.try_reserve(len).map_err(|_| ErrorKind::OutOfMemory)?;
 
         let (front, back) = self.as_slices();
         buf.extend_from_slice(front);
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index e3aa973741f..8fca66fa17c 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -430,6 +430,8 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
         loop {
             match r.read(&mut probe) {
                 Ok(n) => {
+                    // there is no way to recover from allocation failure here
+                    // because the data has already been read.
                     buf.extend_from_slice(&probe[..n]);
                     return Ok(n);
                 }
@@ -462,7 +464,8 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
         }
 
         if buf.len() == buf.capacity() {
-            buf.reserve(PROBE_SIZE); // buf is full, need more space
+            // buf is full, need more space
+            buf.try_reserve(PROBE_SIZE).map_err(|_| ErrorKind::OutOfMemory)?;
         }
 
         let mut spare = buf.spare_capacity_mut();
@@ -815,6 +818,39 @@ pub trait Read {
     /// file.)
     ///
     /// [`std::fs::read`]: crate::fs::read
+    ///
+    /// ## Implementing `read_to_end`
+    ///
+    /// When implementing the `io::Read` trait, it is recommended to allocate
+    /// memory using [`Vec::try_reserve`]. However, this behavior is not guaranteed
+    /// by all implementations, and `read_to_end` may not handle out-of-memory
+    /// situations gracefully.
+    ///
+    /// ```no_run
+    /// # use std::io::{self, BufRead};
+    /// # struct Example { example_datasource: io::Empty } impl Example {
+    /// # fn get_some_data_for_the_example(&self) -> &'static [u8] { &[] }
+    /// fn read_to_end(&mut self, dest_vec: &mut Vec<u8>) -> io::Result<usize> {
+    ///     let initial_vec_len = dest_vec.len();
+    ///     loop {
+    ///         let src_buf = self.example_datasource.fill_buf()?;
+    ///         if src_buf.is_empty() {
+    ///             break;
+    ///         }
+    ///         dest_vec.try_reserve(src_buf.len()).map_err(|_| io::ErrorKind::OutOfMemory)?;
+    ///         dest_vec.extend_from_slice(src_buf);
+    ///
+    ///         // Any irreversible side effects should happen after `try_reserve` succeeds,
+    ///         // to avoid losing data on allocation error.
+    ///         let read = src_buf.len();
+    ///         self.example_datasource.consume(read);
+    ///     }
+    ///     Ok(dest_vec.len() - initial_vec_len)
+    /// }
+    /// # }
+    /// ```
+    ///
+    /// [`Vec::try_reserve`]: crate::vec::Vec::try_reserve
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
         default_read_to_end(self, buf, None)
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 05b21eeb40f..261b570dee7 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -8,7 +8,9 @@ use crate::io::prelude::*;
 use crate::cell::{Cell, RefCell};
 use crate::fmt;
 use crate::fs::File;
-use crate::io::{self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines};
+use crate::io::{
+    self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines, SpecReadByte,
+};
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantMutex, ReentrantMutexGuard};
 use crate::sys::stdio;
@@ -483,6 +485,13 @@ impl Read for StdinLock<'_> {
     }
 }
 
+impl SpecReadByte for StdinLock<'_> {
+    #[inline]
+    fn spec_read_byte(&mut self) -> Option<io::Result<u8>> {
+        BufReader::spec_read_byte(&mut *self.inner)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl BufRead for StdinLock<'_> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index 6bc8f181c90..a04bc481146 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -204,6 +204,16 @@ impl Read for Repeat {
         Ok(())
     }
 
+    /// This function is not supported by `io::Repeat`, because there's no end of its data
+    fn read_to_end(&mut self, _: &mut Vec<u8>) -> io::Result<usize> {
+        Err(io::Error::from(io::ErrorKind::OutOfMemory))
+    }
+
+    /// This function is not supported by `io::Repeat`, because there's no end of its data
+    fn read_to_string(&mut self, _: &mut String) -> io::Result<usize> {
+        Err(io::Error::from(io::ErrorKind::OutOfMemory))
+    }
+
     #[inline]
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         let mut nwritten = 0;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 751e988a99b..ccc7a159231 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -323,6 +323,7 @@
 #![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(float_next_up_down)]
+#![feature(generic_nonzero)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(hint_assert_unchecked)]
@@ -337,7 +338,6 @@
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
-#![feature(raw_os_nonzero)]
 #![feature(slice_internals)]
 #![feature(slice_ptr_get)]
 #![feature(slice_range)]
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index 55f6ddcf77f..1343fdfd1df 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -16,6 +16,16 @@ pub use core::num::Wrapping;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError};
 
+#[unstable(
+    feature = "nonzero_internals",
+    reason = "implementation detail which may disappear or be replaced at any time",
+    issue = "none"
+)]
+pub use core::num::ZeroablePrimitive;
+
+#[unstable(feature = "generic_nonzero", issue = "120257")]
+pub use core::num::NonZero;
+
 #[stable(feature = "signed_nonzero", since = "1.34.0")]
 pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
 #[stable(feature = "nonzero", since = "1.28.0")]
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index f03e0790305..6e11b92b618 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -85,9 +85,6 @@ pub mod linux;
 #[cfg(any(target_os = "wasi", doc))]
 pub mod wasi;
 
-#[cfg(any(all(target_os = "wasi", target_env = "preview2"), doc))]
-pub mod wasi_preview2;
-
 // windows
 #[cfg(not(all(
     doc,
diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs
index 05c8d30073f..bbaf328f457 100644
--- a/library/std/src/os/wasi/mod.rs
+++ b/library/std/src/os/wasi/mod.rs
@@ -28,8 +28,7 @@
 //! [`OsStr`]: crate::ffi::OsStr
 //! [`OsString`]: crate::ffi::OsString
 
-#![cfg_attr(not(target_env = "preview2"), stable(feature = "rust1", since = "1.0.0"))]
-#![cfg_attr(target_env = "preview2", unstable(feature = "wasm_preview2", issue = "none"))]
+#![stable(feature = "rust1", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![doc(cfg(target_os = "wasi"))]
 
diff --git a/library/std/src/os/wasi_preview2/mod.rs b/library/std/src/os/wasi_preview2/mod.rs
deleted file mode 100644
index 1d44dd72814..00000000000
--- a/library/std/src/os/wasi_preview2/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//! Platform-specific extensions to `std` for Preview 2 of the WebAssembly System Interface (WASI).
-//!
-//! This module is currently empty, but will be filled over time as wasi-libc support for WASI Preview 2 is stabilized.
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs
index 1b013d1c154..e9d7a13e9d5 100644
--- a/library/std/src/os/windows/fs.rs
+++ b/library/std/src/os/windows/fs.rs
@@ -59,7 +59,7 @@ pub trait FileExt {
     /// function, it is set to the end of the write.
     ///
     /// When writing beyond the end of the file, the file is appropriately
-    /// extended and the intermediate bytes are left uninitialized.
+    /// extended and the intermediate bytes are set to zero.
     ///
     /// Note that similar to `File::write`, it is not an error to return a
     /// short write. When returning from such a short write, the file pointer
diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs
index f927d88d46c..041b7c35582 100644
--- a/library/std/src/sys/pal/mod.rs
+++ b/library/std/src/sys/pal/mod.rs
@@ -40,9 +40,6 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "wasi")] {
         mod wasi;
         pub use self::wasi::*;
-    } else if #[cfg(all(target_os = "wasi", target_env = "preview2"))] {
-        mod wasi_preview2;
-        pub use self::wasi_preview2::*;
     } else if #[cfg(target_family = "wasm")] {
         mod wasm;
         pub use self::wasm::*;
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index df0fe2bb9d8..94c4c56bd51 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -1,11 +1,10 @@
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
 use crate::mem;
-use crate::num::NonZeroI32;
+use crate::num::{NonZero, NonZeroI32};
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
-use core::ffi::NonZero_c_int;
 
 #[cfg(target_os = "linux")]
 use crate::os::linux::process::PidFd;
@@ -935,7 +934,7 @@ impl ExitStatus {
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
         // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
-        match NonZero_c_int::try_from(self.0) {
+        match NonZero::try_from(self.0) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => Ok(()),
         }
@@ -1092,7 +1091,7 @@ impl fmt::Display for ExitStatus {
 }
 
 #[derive(PartialEq, Eq, Clone, Copy)]
-pub struct ExitStatusError(NonZero_c_int);
+pub struct ExitStatusError(NonZero<c_int>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported.rs b/library/std/src/sys/pal/unix/process/process_unsupported.rs
index 9453c8a384e..89a2a0c6e56 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/pal/unix/process/process_unsupported.rs
@@ -1,9 +1,8 @@
 use crate::fmt;
 use crate::io;
-use crate::num::NonZeroI32;
+use crate::num::{NonZero, NonZeroI32};
 use crate::sys::pal::unix::unsupported::*;
 use crate::sys::process::process_common::*;
-use core::ffi::NonZero_c_int;
 
 use libc::{c_int, pid_t};
 
@@ -59,7 +58,7 @@ mod wait_status;
 pub use wait_status::ExitStatus;
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(NonZero_c_int);
+pub struct ExitStatusError(NonZero<c_int>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
diff --git a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs b/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
index 72b7ae18cff..e6dfadcf4a4 100644
--- a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
+++ b/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs
@@ -1,10 +1,9 @@
 //! Emulated wait status for non-Unix #[cfg(unix) platforms
 //!
 //! Separate module to facilitate testing against a real Unix implementation.
-use core::ffi::NonZero_c_int;
-
 use crate::ffi::c_int;
 use crate::fmt;
+use crate::num::NonZero;
 
 use super::ExitStatusError;
 
@@ -50,7 +49,7 @@ impl ExitStatus {
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
         // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
-        match NonZero_c_int::try_from(self.wait_status) {
+        match NonZero::try_from(self.wait_status) {
             /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
             /* was zero, couldn't convert */ Err(_) => Ok(()),
         }
diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs
index 1ff2b2fb383..5b4e94d0f1b 100644
--- a/library/std/src/sys/pal/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs
@@ -1,11 +1,10 @@
 use crate::fmt;
 use crate::io::{self, Error, ErrorKind};
-use crate::num::NonZeroI32;
+use crate::num::{NonZero, NonZeroI32};
 use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
 use crate::sys_common::thread;
-use core::ffi::NonZero_c_int;
 use libc::RTP_ID;
 use libc::{self, c_char, c_int};
 
@@ -197,7 +196,7 @@ impl ExitStatus {
         // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
         // true for a platform pretending to be Unix, the tests (our doctests, and also
         // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
-        match NonZero_c_int::try_from(self.0) {
+        match NonZero::try_from(self.0) {
             Ok(failure) => Err(ExitStatusError(failure)),
             Err(_) => Ok(()),
         }
@@ -249,7 +248,7 @@ impl fmt::Display for ExitStatus {
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(NonZero_c_int);
+pub struct ExitStatusError(NonZero<c_int>);
 
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
diff --git a/library/std/src/sys/pal/wasi/helpers.rs b/library/std/src/sys/pal/wasi/helpers.rs
deleted file mode 100644
index 82149cef8fa..00000000000
--- a/library/std/src/sys/pal/wasi/helpers.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-use crate::io as std_io;
-use crate::mem;
-
-#[inline]
-pub fn is_interrupted(errno: i32) -> bool {
-    errno == wasi::ERRNO_INTR.raw().into()
-}
-
-pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
-    use std_io::ErrorKind;
-
-    let Ok(errno) = u16::try_from(errno) else {
-        return ErrorKind::Uncategorized;
-    };
-
-    macro_rules! match_errno {
-        ($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => {
-            match errno {
-                $(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*,
-                _ => ErrorKind::$wildcard,
-            }
-        };
-    }
-
-    match_errno! {
-        ERRNO_2BIG           => ArgumentListTooLong,
-        ERRNO_ACCES          => PermissionDenied,
-        ERRNO_ADDRINUSE      => AddrInUse,
-        ERRNO_ADDRNOTAVAIL   => AddrNotAvailable,
-        ERRNO_AFNOSUPPORT    => Unsupported,
-        ERRNO_AGAIN          => WouldBlock,
-        //    ALREADY        => "connection already in progress",
-        //    BADF           => "bad file descriptor",
-        //    BADMSG         => "bad message",
-        ERRNO_BUSY           => ResourceBusy,
-        //    CANCELED       => "operation canceled",
-        //    CHILD          => "no child processes",
-        ERRNO_CONNABORTED    => ConnectionAborted,
-        ERRNO_CONNREFUSED    => ConnectionRefused,
-        ERRNO_CONNRESET      => ConnectionReset,
-        ERRNO_DEADLK         => Deadlock,
-        //    DESTADDRREQ    => "destination address required",
-        ERRNO_DOM            => InvalidInput,
-        //    DQUOT          => /* reserved */,
-        ERRNO_EXIST          => AlreadyExists,
-        //    FAULT          => "bad address",
-        ERRNO_FBIG           => FileTooLarge,
-        ERRNO_HOSTUNREACH    => HostUnreachable,
-        //    IDRM           => "identifier removed",
-        //    ILSEQ          => "illegal byte sequence",
-        //    INPROGRESS     => "operation in progress",
-        ERRNO_INTR           => Interrupted,
-        ERRNO_INVAL          => InvalidInput,
-        ERRNO_IO             => Uncategorized,
-        //    ISCONN         => "socket is connected",
-        ERRNO_ISDIR          => IsADirectory,
-        ERRNO_LOOP           => FilesystemLoop,
-        //    MFILE          => "file descriptor value too large",
-        ERRNO_MLINK          => TooManyLinks,
-        //    MSGSIZE        => "message too large",
-        //    MULTIHOP       => /* reserved */,
-        ERRNO_NAMETOOLONG    => InvalidFilename,
-        ERRNO_NETDOWN        => NetworkDown,
-        //    NETRESET       => "connection aborted by network",
-        ERRNO_NETUNREACH     => NetworkUnreachable,
-        //    NFILE          => "too many files open in system",
-        //    NOBUFS         => "no buffer space available",
-        ERRNO_NODEV          => NotFound,
-        ERRNO_NOENT          => NotFound,
-        //    NOEXEC         => "executable file format error",
-        //    NOLCK          => "no locks available",
-        //    NOLINK         => /* reserved */,
-        ERRNO_NOMEM          => OutOfMemory,
-        //    NOMSG          => "no message of the desired type",
-        //    NOPROTOOPT     => "protocol not available",
-        ERRNO_NOSPC          => StorageFull,
-        ERRNO_NOSYS          => Unsupported,
-        ERRNO_NOTCONN        => NotConnected,
-        ERRNO_NOTDIR         => NotADirectory,
-        ERRNO_NOTEMPTY       => DirectoryNotEmpty,
-        //    NOTRECOVERABLE => "state not recoverable",
-        //    NOTSOCK        => "not a socket",
-        ERRNO_NOTSUP         => Unsupported,
-        //    NOTTY          => "inappropriate I/O control operation",
-        ERRNO_NXIO           => NotFound,
-        //    OVERFLOW       => "value too large to be stored in data type",
-        //    OWNERDEAD      => "previous owner died",
-        ERRNO_PERM           => PermissionDenied,
-        ERRNO_PIPE           => BrokenPipe,
-        //    PROTO          => "protocol error",
-        ERRNO_PROTONOSUPPORT => Unsupported,
-        //    PROTOTYPE      => "protocol wrong type for socket",
-        //    RANGE          => "result too large",
-        ERRNO_ROFS           => ReadOnlyFilesystem,
-        ERRNO_SPIPE          => NotSeekable,
-        ERRNO_SRCH           => NotFound,
-        //    STALE          => /* reserved */,
-        ERRNO_TIMEDOUT       => TimedOut,
-        ERRNO_TXTBSY         => ResourceBusy,
-        ERRNO_XDEV           => CrossesDevices,
-        ERRNO_NOTCAPABLE     => PermissionDenied,
-        _                    => Uncategorized,
-    }
-}
-
-pub fn abort_internal() -> ! {
-    unsafe { libc::abort() }
-}
-
-pub fn hashmap_random_keys() -> (u64, u64) {
-    let mut ret = (0u64, 0u64);
-    unsafe {
-        let base = &mut ret as *mut (u64, u64) as *mut u8;
-        let len = mem::size_of_val(&ret);
-        wasi::random_get(base, len).expect("random_get failure");
-    }
-    return ret;
-}
-
-#[inline]
-pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error {
-    std_io::Error::from_raw_os_error(err.raw().into())
-}
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index a4b55093bf4..4ffc8ecdd67 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -14,6 +14,9 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
+use crate::io as std_io;
+use crate::mem;
+
 #[path = "../unix/alloc.rs"]
 pub mod alloc;
 pub mod args;
@@ -69,12 +72,123 @@ cfg_if::cfg_if! {
 mod common;
 pub use common::*;
 
-mod helpers;
-// These exports are listed individually to work around Rust's glob import
-// conflict rules. If we glob export `helpers` and `common` together, then
-// the compiler complains about conflicts.
-pub use helpers::abort_internal;
-pub use helpers::decode_error_kind;
-use helpers::err2io;
-pub use helpers::hashmap_random_keys;
-pub use helpers::is_interrupted;
+#[inline]
+pub fn is_interrupted(errno: i32) -> bool {
+    errno == wasi::ERRNO_INTR.raw().into()
+}
+
+pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
+    use std_io::ErrorKind;
+
+    let Ok(errno) = u16::try_from(errno) else {
+        return ErrorKind::Uncategorized;
+    };
+
+    macro_rules! match_errno {
+        ($($($errno:ident)|+ => $errkind:ident),*, _ => $wildcard:ident $(,)?) => {
+            match errno {
+                $(e if $(e == ::wasi::$errno.raw())||+ => ErrorKind::$errkind),*,
+                _ => ErrorKind::$wildcard,
+            }
+        };
+    }
+
+    match_errno! {
+        ERRNO_2BIG           => ArgumentListTooLong,
+        ERRNO_ACCES          => PermissionDenied,
+        ERRNO_ADDRINUSE      => AddrInUse,
+        ERRNO_ADDRNOTAVAIL   => AddrNotAvailable,
+        ERRNO_AFNOSUPPORT    => Unsupported,
+        ERRNO_AGAIN          => WouldBlock,
+        //    ALREADY        => "connection already in progress",
+        //    BADF           => "bad file descriptor",
+        //    BADMSG         => "bad message",
+        ERRNO_BUSY           => ResourceBusy,
+        //    CANCELED       => "operation canceled",
+        //    CHILD          => "no child processes",
+        ERRNO_CONNABORTED    => ConnectionAborted,
+        ERRNO_CONNREFUSED    => ConnectionRefused,
+        ERRNO_CONNRESET      => ConnectionReset,
+        ERRNO_DEADLK         => Deadlock,
+        //    DESTADDRREQ    => "destination address required",
+        ERRNO_DOM            => InvalidInput,
+        //    DQUOT          => /* reserved */,
+        ERRNO_EXIST          => AlreadyExists,
+        //    FAULT          => "bad address",
+        ERRNO_FBIG           => FileTooLarge,
+        ERRNO_HOSTUNREACH    => HostUnreachable,
+        //    IDRM           => "identifier removed",
+        //    ILSEQ          => "illegal byte sequence",
+        //    INPROGRESS     => "operation in progress",
+        ERRNO_INTR           => Interrupted,
+        ERRNO_INVAL          => InvalidInput,
+        ERRNO_IO             => Uncategorized,
+        //    ISCONN         => "socket is connected",
+        ERRNO_ISDIR          => IsADirectory,
+        ERRNO_LOOP           => FilesystemLoop,
+        //    MFILE          => "file descriptor value too large",
+        ERRNO_MLINK          => TooManyLinks,
+        //    MSGSIZE        => "message too large",
+        //    MULTIHOP       => /* reserved */,
+        ERRNO_NAMETOOLONG    => InvalidFilename,
+        ERRNO_NETDOWN        => NetworkDown,
+        //    NETRESET       => "connection aborted by network",
+        ERRNO_NETUNREACH     => NetworkUnreachable,
+        //    NFILE          => "too many files open in system",
+        //    NOBUFS         => "no buffer space available",
+        ERRNO_NODEV          => NotFound,
+        ERRNO_NOENT          => NotFound,
+        //    NOEXEC         => "executable file format error",
+        //    NOLCK          => "no locks available",
+        //    NOLINK         => /* reserved */,
+        ERRNO_NOMEM          => OutOfMemory,
+        //    NOMSG          => "no message of the desired type",
+        //    NOPROTOOPT     => "protocol not available",
+        ERRNO_NOSPC          => StorageFull,
+        ERRNO_NOSYS          => Unsupported,
+        ERRNO_NOTCONN        => NotConnected,
+        ERRNO_NOTDIR         => NotADirectory,
+        ERRNO_NOTEMPTY       => DirectoryNotEmpty,
+        //    NOTRECOVERABLE => "state not recoverable",
+        //    NOTSOCK        => "not a socket",
+        ERRNO_NOTSUP         => Unsupported,
+        //    NOTTY          => "inappropriate I/O control operation",
+        ERRNO_NXIO           => NotFound,
+        //    OVERFLOW       => "value too large to be stored in data type",
+        //    OWNERDEAD      => "previous owner died",
+        ERRNO_PERM           => PermissionDenied,
+        ERRNO_PIPE           => BrokenPipe,
+        //    PROTO          => "protocol error",
+        ERRNO_PROTONOSUPPORT => Unsupported,
+        //    PROTOTYPE      => "protocol wrong type for socket",
+        //    RANGE          => "result too large",
+        ERRNO_ROFS           => ReadOnlyFilesystem,
+        ERRNO_SPIPE          => NotSeekable,
+        ERRNO_SRCH           => NotFound,
+        //    STALE          => /* reserved */,
+        ERRNO_TIMEDOUT       => TimedOut,
+        ERRNO_TXTBSY         => ResourceBusy,
+        ERRNO_XDEV           => CrossesDevices,
+        ERRNO_NOTCAPABLE     => PermissionDenied,
+        _                    => Uncategorized,
+    }
+}
+
+pub fn abort_internal() -> ! {
+    unsafe { libc::abort() }
+}
+
+pub fn hashmap_random_keys() -> (u64, u64) {
+    let mut ret = (0u64, 0u64);
+    unsafe {
+        let base = &mut ret as *mut (u64, u64) as *mut u8;
+        let len = mem::size_of_val(&ret);
+        wasi::random_get(base, len).expect("random_get failure");
+    }
+    return ret;
+}
+
+#[inline]
+fn err2io(err: wasi::Errno) -> std_io::Error {
+    std_io::Error::from_raw_os_error(err.raw().into())
+}
diff --git a/library/std/src/sys/pal/wasi/net.rs b/library/std/src/sys/pal/wasi/net.rs
index 2239880ffbe..2098d05db0b 100644
--- a/library/std/src/sys/pal/wasi/net.rs
+++ b/library/std/src/sys/pal/wasi/net.rs
@@ -538,7 +538,4 @@ pub mod netc {
         pub sin6_flowinfo: u32,
         pub sin6_scope_id: u32,
     }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr {}
 }
diff --git a/library/std/src/sys/pal/wasi_preview2/mod.rs b/library/std/src/sys/pal/wasi_preview2/mod.rs
deleted file mode 100644
index b61695015bb..00000000000
--- a/library/std/src/sys/pal/wasi_preview2/mod.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-//! System bindings for the wasi preview 2 target.
-//!
-//! This is the next evolution of the original wasi target, and is intended to
-//! replace that target over time.
-//!
-//! To begin with, this target mirrors the wasi target 1 to 1, but over
-//! time this will change significantly.
-
-#[path = "../unix/alloc.rs"]
-pub mod alloc;
-#[path = "../wasi/args.rs"]
-pub mod args;
-#[path = "../unix/cmath.rs"]
-pub mod cmath;
-#[path = "../wasi/env.rs"]
-pub mod env;
-#[path = "../wasi/fd.rs"]
-pub mod fd;
-#[path = "../wasi/fs.rs"]
-pub mod fs;
-#[allow(unused)]
-#[path = "../wasm/atomics/futex.rs"]
-pub mod futex;
-#[path = "../wasi/io.rs"]
-pub mod io;
-
-#[path = "../wasi/net.rs"]
-pub mod net;
-#[path = "../wasi/os.rs"]
-pub mod os;
-#[path = "../unix/os_str.rs"]
-pub mod os_str;
-#[path = "../unix/path.rs"]
-pub mod path;
-#[path = "../unsupported/pipe.rs"]
-pub mod pipe;
-#[path = "../unsupported/process.rs"]
-pub mod process;
-#[path = "../wasi/stdio.rs"]
-pub mod stdio;
-#[path = "../wasi/thread.rs"]
-pub mod thread;
-#[path = "../unsupported/thread_local_dtor.rs"]
-pub mod thread_local_dtor;
-#[path = "../unsupported/thread_local_key.rs"]
-pub mod thread_local_key;
-#[path = "../wasi/time.rs"]
-pub mod time;
-
-cfg_if::cfg_if! {
-    if #[cfg(target_feature = "atomics")] {
-        compile_error!("The wasm32-wasi-preview2 target does not support atomics");
-    } else {
-        #[path = "../unsupported/locks/mod.rs"]
-        pub mod locks;
-        #[path = "../unsupported/once.rs"]
-        pub mod once;
-        #[path = "../unsupported/thread_parking.rs"]
-        pub mod thread_parking;
-    }
-}
-
-#[path = "../unsupported/common.rs"]
-#[deny(unsafe_op_in_unsafe_fn)]
-#[allow(unused)]
-mod common;
-pub use common::*;
-
-#[path = "../wasi/helpers.rs"]
-mod helpers;
-// These exports are listed individually to work around Rust's glob import
-// conflict rules. If we glob export `helpers` and `common` together, then
-// the compiler complains about conflicts.
-pub use helpers::abort_internal;
-pub use helpers::decode_error_kind;
-use helpers::err2io;
-pub use helpers::hashmap_random_keys;
-pub use helpers::is_interrupted;
diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs
index d53ea16005f..270eca37b14 100644
--- a/library/std/src/sys/pal/windows/alloc.rs
+++ b/library/std/src/sys/pal/windows/alloc.rs
@@ -95,7 +95,7 @@ static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
 #[inline]
 fn init_or_get_process_heap() -> c::HANDLE {
     let heap = HEAP.load(Ordering::Relaxed);
-    if heap.is_null() {
+    if core::intrinsics::unlikely(heap.is_null()) {
         // `HEAP` has not yet been successfully initialized
         let heap = unsafe { GetProcessHeap() };
         if !heap.is_null() {
@@ -115,6 +115,16 @@ fn init_or_get_process_heap() -> c::HANDLE {
     }
 }
 
+#[inline(never)]
+fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID {
+    let heap = init_or_get_process_heap();
+    if core::intrinsics::unlikely(heap.is_null()) {
+        return ptr::null_mut();
+    }
+    // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
+    unsafe { HeapAlloc(heap, flags, dwBytes) }
+}
+
 // Get a non-null handle to the default heap of the current process.
 // SAFETY: `HEAP` must have been successfully initialized.
 #[inline]
@@ -133,25 +143,17 @@ struct Header(*mut u8);
 // initialized.
 #[inline]
 unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 {
-    let heap = init_or_get_process_heap();
-    if heap.is_null() {
-        // Allocation has failed, could not get the current process heap.
-        return ptr::null_mut();
-    }
-
     // Allocated memory will be either zeroed or uninitialized.
     let flags = if zeroed { HEAP_ZERO_MEMORY } else { 0 };
 
     if layout.align() <= MIN_ALIGN {
-        // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
         // The returned pointer points to the start of an allocated block.
-        unsafe { HeapAlloc(heap, flags, layout.size()) as *mut u8 }
+        process_heap_alloc(flags, layout.size()) as *mut u8
     } else {
         // Allocate extra padding in order to be able to satisfy the alignment.
         let total = layout.align() + layout.size();
 
-        // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
-        let ptr = unsafe { HeapAlloc(heap, flags, total) as *mut u8 };
+        let ptr = process_heap_alloc(flags, total) as *mut u8;
         if ptr.is_null() {
             // Allocation has failed.
             return ptr::null_mut();
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index d55d9bace81..1a59ac9a9ca 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -7,17 +7,17 @@
 
 use crate::ffi::CStr;
 use crate::mem;
+use crate::num::NonZero;
 pub use crate::os::raw::c_int;
 use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void};
 use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
 use crate::ptr;
-use core::ffi::NonZero_c_ulong;
 
 mod windows_sys;
 pub use windows_sys::*;
 
 pub type DWORD = c_ulong;
-pub type NonZeroDWORD = NonZero_c_ulong;
+pub type NonZeroDWORD = NonZero<c_ulong>;
 pub type LARGE_INTEGER = c_longlong;
 #[cfg_attr(target_vendor = "uwp", allow(unused))]
 pub type LONG = c_long;
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 42484543686..2bdd3d96fa4 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -112,6 +112,13 @@ impl fmt::Debug for ReadDir {
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
+        if self.handle.0 == c::INVALID_HANDLE_VALUE {
+            // This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle.
+            // Simply return `None` because this is only the case when `FindFirstFileW` in
+            // the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means
+            // no matchhing files can be found.
+            return None;
+        }
         if let Some(first) = self.first.take() {
             if let Some(e) = DirEntry::new(&self.root, &first) {
                 return Some(Ok(e));
@@ -1068,6 +1075,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
     unsafe {
         let mut wfd = mem::zeroed();
         let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
+
         if find_handle != c::INVALID_HANDLE_VALUE {
             Ok(ReadDir {
                 handle: FindNextFileHandle(find_handle),
@@ -1075,7 +1083,31 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
                 first: Some(wfd),
             })
         } else {
-            Err(Error::last_os_error())
+            // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function
+            // if no matching files can be found, but not necessarily that the path to find the
+            // files in does not exist.
+            //
+            // Hence, a check for whether the path to search in exists is added when the last
+            // os error returned by Windows is `ERROR_FILE_NOT_FOUND` to handle this scenario.
+            // If that is the case, an empty `ReadDir` iterator is returned as it returns `None`
+            // in the initial `.next()` invocation because `ERROR_NO_MORE_FILES` would have been
+            // returned by the `FindNextFileW` function.
+            //
+            // See issue #120040: https://github.com/rust-lang/rust/issues/120040.
+            let last_error = api::get_last_error();
+            if last_error.code == c::ERROR_FILE_NOT_FOUND {
+                return Ok(ReadDir {
+                    handle: FindNextFileHandle(find_handle),
+                    root: Arc::new(root),
+                    first: None,
+                });
+            }
+
+            // Just return the error constructed from the raw OS error if the above is not the case.
+            //
+            // Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileW` function
+            // when the path to search in does not exist in the first place.
+            Err(Error::from_raw_os_error(last_error.code as i32))
         }
     }
 }
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 83fdcddecf2..0d604c0d3e5 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1034,7 +1034,16 @@ class RustBuild(object):
                 eprint('ERROR: vendoring required, but vendor directory does not exist.')
                 eprint('       Run `cargo vendor {}` to initialize the '
                       'vendor directory.'.format(sync_dirs))
-                eprint('Alternatively, use the pre-vendored `rustc-src` dist component.')
+                eprint('       Alternatively, use the pre-vendored `rustc-src` dist component.')
+                eprint('       To get a stable/beta/nightly version, download it from: ')
+                eprint('       '
+                'https://forge.rust-lang.org/infra/other-installation-methods.html#source-code')
+                eprint('       To get a specific commit version, download it using the below URL,')
+                eprint('       replacing <commit> with a specific commit checksum: ')
+                eprint('       '
+                'https://ci-artifacts.rust-lang.org/rustc-builds/<commit>/rustc-nightly-src.tar.xz')
+                eprint('       Once you have the source downloaded, place the vendor directory')
+                eprint('       from the archive in the root of the rust project.')
                 raise Exception("{} not found".format(vendor_dir))
 
             if not os.path.exists(cargo_dir):
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index e06bc3fb09a..ddbe18ab838 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -367,13 +367,10 @@ fn copy_self_contained_objects(
         let srcdir = builder
             .wasi_root(target)
             .unwrap_or_else(|| {
-                panic!(
-                    "Target {:?} does not have a \"wasi-root\" key in Config.toml",
-                    target.triple
-                )
+                panic!("Target {:?} does not have a \"wasi-root\" key", target.triple)
             })
             .join("lib")
-            .join(target.to_string().replace("-preview1", "").replace("-preview2", ""));
+            .join(target.to_string().replace("-preview1", ""));
         for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
             copy_and_stamp(
                 builder,
@@ -1116,16 +1113,11 @@ pub fn rustc_cargo_env(
 /// Pass down configuration from the LLVM build into the build of
 /// rustc_llvm and rustc_codegen_llvm.
 fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
-    let target_config = builder.config.target_config.get(&target);
-
     if builder.is_rust_llvm(target) {
         cargo.env("LLVM_RUSTLLVM", "1");
     }
     let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target });
     cargo.env("LLVM_CONFIG", &llvm_config);
-    if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
-        cargo.env("CFG_LLVM_ROOT", s);
-    }
 
     // Some LLVM linker flags (-L and -l) may be needed to link `rustc_llvm`. Its build script
     // expects these to be passed via the `LLVM_LINKER_FLAGS` env variable, separated by
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index dd9c68aba7f..5b434eddb71 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -14,7 +14,6 @@ use std::str::FromStr;
 use std::{fmt, fs, io};
 
 #[cfg(test)]
-#[path = "../../tests/setup.rs"]
 mod tests;
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
diff --git a/src/bootstrap/src/tests/setup.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs
index 3e4d66c7454..3e4d66c7454 100644
--- a/src/bootstrap/src/tests/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup/tests.rs
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 3770d0687b2..dac8393de6b 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -32,7 +32,6 @@ use clap::ValueEnum;
 use once_cell::sync::Lazy;
 
 #[cfg(test)]
-#[path = "../tests/builder.rs"]
 mod tests;
 
 pub struct Builder<'a> {
diff --git a/src/bootstrap/src/tests/builder.rs b/src/bootstrap/src/core/builder/tests.rs
index 700ebcf5e37..700ebcf5e37 100644
--- a/src/bootstrap/src/tests/builder.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index fcdd742e69c..c0dd1e12084 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -3,10 +3,6 @@
 //! This module implements parsing `config.toml` configuration files to tweak
 //! how the build runs.
 
-#[cfg(test)]
-#[path = "../../tests/config.rs"]
-mod tests;
-
 use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::collections::{HashMap, HashSet};
@@ -1203,7 +1199,7 @@ impl Config {
         Self::parse_inner(args, get_toml)
     }
 
-    fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
+    pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
         let mut flags = Flags::parse(&args);
         let mut config = Config::default_opts();
 
diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs
index 9c6861826d6..99412848abb 100644
--- a/src/bootstrap/src/core/config/mod.rs
+++ b/src/bootstrap/src/core/config/mod.rs
@@ -1,4 +1,6 @@
 pub(crate) mod config;
 pub(crate) mod flags;
+#[cfg(test)]
+mod tests;
 
 pub use config::*;
diff --git a/src/bootstrap/src/tests/config.rs b/src/bootstrap/src/core/config/tests.rs
index c65067f8e8f..201d11571c4 100644
--- a/src/bootstrap/src/tests/config.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -1,4 +1,4 @@
-use super::{Config, Flags};
+use super::{flags::Flags, Config};
 use crate::core::config::{LldMode, TomlConfig};
 
 use clap::CommandFactory;
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 1726e7aacbc..1336abf6c7a 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -88,7 +88,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (Some(Mode::Std), "no_sync", None),
     (Some(Mode::Std), "backtrace_in_libstd", None),
     /* Extra values not defined in the built-in targets yet, but used in std */
-    (Some(Mode::Std), "target_env", Some(&["libnx", "preview2"])),
+    (Some(Mode::Std), "target_env", Some(&["libnx"])),
     // (Some(Mode::Std), "target_os", Some(&[])),
     // #[cfg(bootstrap)] zkvm
     (Some(Mode::Std), "target_os", Some(&["zkvm"])),
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 327b4674acf..0d5e2600b73 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -2,6 +2,9 @@
 //! with the goal of keeping developers synchronized with important modifications in
 //! the bootstrap.
 
+#[cfg(test)]
+mod tests;
+
 #[derive(Clone, Debug)]
 pub struct ChangeInfo {
     /// Represents the ID of PR caused major change on bootstrap.
diff --git a/src/bootstrap/src/utils/change_tracker/tests.rs b/src/bootstrap/src/utils/change_tracker/tests.rs
new file mode 100644
index 00000000000..d2bfc07d172
--- /dev/null
+++ b/src/bootstrap/src/utils/change_tracker/tests.rs
@@ -0,0 +1,10 @@
+use crate::{find_recent_config_change_ids, CONFIG_CHANGE_HISTORY};
+
+#[test]
+fn test_find_recent_config_change_ids() {
+    // If change-id is greater than the most recent one, result should be empty.
+    assert!(find_recent_config_change_ids(usize::MAX).is_empty());
+
+    // There is no change-id equal to or less than 0, result should include the entire change history.
+    assert_eq!(find_recent_config_change_ids(0).len(), CONFIG_CHANGE_HISTORY.len());
+}
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 0c917c3d579..d1f713af917 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -21,7 +21,6 @@ use crate::LldMode;
 pub use crate::utils::dylib::{dylib_path, dylib_path_var};
 
 #[cfg(test)]
-#[path = "../tests/helpers.rs"]
 mod tests;
 
 /// A helper macro to `unwrap` a result except also print out details like:
diff --git a/src/bootstrap/src/tests/helpers.rs b/src/bootstrap/src/utils/helpers/tests.rs
index 2d626fad417..9cfaa3eb67b 100644
--- a/src/bootstrap/src/tests/helpers.rs
+++ b/src/bootstrap/src/utils/helpers/tests.rs
@@ -1,5 +1,14 @@
-use crate::utils::helpers::{check_cfg_arg, extract_beta_rev, hex_encode, make};
-use std::path::PathBuf;
+use crate::{
+    utils::helpers::{
+        check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
+    },
+    Config,
+};
+use std::{
+    fs::{self, remove_file, File},
+    io::Write,
+    path::PathBuf,
+};
 
 #[test]
 fn test_make() {
@@ -70,3 +79,38 @@ fn test_check_cfg_arg() {
         "--check-cfg=cfg(target_os,values(\"nixos\",\"nix2\"))"
     );
 }
+
+#[test]
+fn test_program_out_of_date() {
+    let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
+    let tempfile = config.tempdir().join(".tmp-stamp-file");
+    File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
+    assert!(tempfile.exists());
+
+    // up-to-date
+    assert!(!program_out_of_date(&tempfile, "dummy value"));
+    // out-of-date
+    assert!(program_out_of_date(&tempfile, ""));
+
+    remove_file(tempfile).unwrap();
+}
+
+#[test]
+fn test_symlink_dir() {
+    let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
+    let tempdir = config.tempdir().join(".tmp-dir");
+    let link_path = config.tempdir().join(".tmp-link");
+
+    fs::create_dir_all(&tempdir).unwrap();
+    symlink_dir(&config, &tempdir, &link_path).unwrap();
+
+    let link_source = fs::read_link(&link_path).unwrap();
+    assert_eq!(link_source, tempdir);
+
+    fs::remove_dir(tempdir).unwrap();
+
+    #[cfg(windows)]
+    fs::remove_dir(link_path).unwrap();
+    #[cfg(not(windows))]
+    fs::remove_file(link_path).unwrap();
+}
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 55eed95492d..0db61204f77 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -74,25 +74,6 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
 
       cksum=$(sha512sum $hash_key | \
         awk '{print $1}')
-
-      url="https://$CACHE_DOMAIN/docker/$cksum"
-
-      echo "Attempting to download $url"
-      rm -f /tmp/rustci_docker_cache
-      set +e
-      retry curl --max-time 600 -y 30 -Y 10 --connect-timeout 30 -f -L -C - \
-        -o /tmp/rustci_docker_cache "$url"
-
-      docker_archive_hash=$(sha512sum /tmp/rustci_docker_cache | awk '{print $1}')
-      echo "Downloaded archive hash: ${docker_archive_hash}"
-
-      echo "Loading images into docker"
-      # docker load sometimes hangs in the CI, so time out after 10 minutes with TERM,
-      # KILL after 12 minutes
-      loaded_images=$(/usr/bin/timeout -k 720 600 docker load -i /tmp/rustci_docker_cache \
-        | sed 's/.* sha/sha/')
-      set -e
-      printf "Downloaded containers:\n$loaded_images\n"
     fi
 
     dockerfile="$docker_dir/$image/Dockerfile"
@@ -103,46 +84,65 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
         context="$script_dir"
     fi
     echo "::group::Building docker image for $image"
-
-    # As of August 2023, Github Actions have updated Docker to 23.X,
-    # which uses the BuildKit by default. It currently throws aways all
-    # intermediate layers, which breaks our usage of S3 layer caching.
-    # Therefore we opt-in to the old build backend for now.
-    export DOCKER_BUILDKIT=0
-    retry docker \
-      build \
-      --rm \
-      -t rust-ci \
-      -f "$dockerfile" \
-      "$context"
-    echo "::endgroup::"
-
-    if [ "$CI" != "" ]; then
-      s3url="s3://$SCCACHE_BUCKET/docker/$cksum"
-      upload="aws s3 cp - $s3url"
-      digest=$(docker inspect rust-ci --format '{{.Id}}')
-      echo "Built container $digest"
-      if ! grep -q "$digest" <(echo "$loaded_images"); then
-        echo "Uploading finished image $digest to $url"
-        set +e
-        # Print image history for easier debugging of layer SHAs
-        docker history rust-ci
-        docker history -q rust-ci | \
-          grep -v missing | \
-          xargs docker save | \
-          gzip | \
-          $upload
-        set -e
-      else
-        echo "Looks like docker image is the same as before, not uploading"
-      fi
-      # Record the container image for reuse, e.g. by rustup.rs builds
-      info="$dist/image-$image.txt"
-      mkdir -p "$dist"
-      echo "$url" >"$info"
-      echo "$digest" >>"$info"
-      cat "$info"
+    echo "Image input"
+    cat $hash_key
+    echo "Image input checksum ${cksum}"
+
+    # Print docker version
+    docker --version
+
+    # On non-CI or PR jobs, we don't have permissions to write to the registry cache, so we should
+    # not use `docker login` nor caching.
+    if [[ "$CI" == "" ]] || [[ "$PR_CI_JOB" == "1" ]];
+    then
+        retry docker build --rm -t rust-ci -f "$dockerfile" "$context"
+    else
+        REGISTRY=ghcr.io
+        # Most probably rust-lang-ci, but in general the owner of the repository where CI runs
+        REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER}
+        # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
+        IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
+        # Tag used to cache the Docker build
+        # It seems that it cannot be the same as $IMAGE_TAG, otherwise it overwrites the cache
+        CACHE_IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci-cache:${cksum}
+
+        # Log into the Docker registry, so that we can read/write cache and the final image
+        echo ${DOCKER_TOKEN} | docker login ${REGISTRY} \
+            --username ${REGISTRY_USERNAME} \
+            --password-stdin
+
+        # Enable a new Docker driver so that --cache-from/to works with a registry backend
+        docker buildx create --use --driver docker-container
+
+        # Build the image using registry caching backend
+        retry docker \
+          buildx \
+          build \
+          --rm \
+          -t rust-ci \
+          -f "$dockerfile" \
+          --cache-from type=registry,ref=${CACHE_IMAGE_TAG} \
+          --cache-to type=registry,ref=${CACHE_IMAGE_TAG},compression=zstd \
+          --output=type=docker \
+          "$context"
+
+        # Print images for debugging purposes
+        docker images
+
+        # Tag the built image and push it to the registry
+        docker tag rust-ci "${IMAGE_TAG}"
+        docker push "${IMAGE_TAG}"
+
+        # Record the container registry tag/url for reuse, e.g. by rustup.rs builds
+        # It should be possible to run `docker pull <$IMAGE_TAG>` to download the image
+        info="$dist/image-$image.txt"
+        mkdir -p "$dist"
+        echo "${IMAGE_TAG}" > "$info"
+        cat "$info"
+
+        echo "To download the image, run docker pull ${IMAGE_TAG}"
     fi
+    echo "::endgroup::"
 elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
     if isCI; then
         echo Cannot run disabled images on CI!
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 68a3afc910f..ceee4690004 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -34,6 +34,7 @@ x--expand-yaml-anchors--remove:
     CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
     # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
     HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+    DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
   - &public-variables
     SCCACHE_BUCKET: rust-lang-ci-sccache2
@@ -301,6 +302,7 @@ on:
 
 permissions:
   contents: read
+  packages: write
 
 defaults:
   run:
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject bbffb074e16bef89772818b400b6c76a65eac12
+Subproject baafacc6d8701269dab1e1e333f3547fb54b5a5
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 3f9df2b9885c6741365da2e12ed6662cd0e827d
+Subproject 2e95fc2fd31d669947e993aa07ef10dc9828bee
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 8c77e8be9da1a9c70545556218d563c8d061f1f
+Subproject a0b119535e7740f68494c4f0582f7ad008b00cc
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject ddf5cb0e6ee54ba2dd84c8ca3e1314120014e20
+Subproject 179256a445d6144f5f371fdefb993f48f33978b
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 4af29d1a7f64f88a36539662c6a84fe1fbe6cde
+Subproject ec287e332777627185be4798ad22599ffe7b84a
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 990998ea704..1998b008dc8 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -59,7 +59,6 @@
     - [*-unknown-openbsd](platform-support/openbsd.md)
     - [\*-unknown-uefi](platform-support/unknown-uefi.md)
     - [wasm32-wasi-preview1-threads](platform-support/wasm32-wasi-preview1-threads.md)
-    - [wasm32-wasi-preview2](platform-support/wasm32-wasi-preview2.md)
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
     - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
     - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index fb751b7229e..f648a60b6c4 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -360,7 +360,6 @@ target | std | host | notes
 `thumbv7a-pc-windows-msvc` | ? |  |
 `thumbv7a-uwp-windows-msvc` | ✓ |  |
 `thumbv7neon-unknown-linux-musleabihf` | ? |  | Thumb2-mode ARMv7-A Linux with NEON, MUSL
-[`wasm32-wasi-preview2`](platform-support/wasm32-wasi-preview2.md) | ✓ |  | WebAssembly
 [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? |  | WebAssembly
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
 [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ? |  | x86 64-bit tvOS
diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
index a54abcb606e..e72bfb8bae7 100644
--- a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
+++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
@@ -50,6 +50,7 @@ cc = "${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc"
 [target.csky-unknown-linux-gnuabiv2hf]
 # ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
 cc = "${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc"
+```
 
 ### Build
 
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasi-preview2.md b/src/doc/rustc/src/platform-support/wasm32-wasi-preview2.md
deleted file mode 100644
index 837efd13d41..00000000000
--- a/src/doc/rustc/src/platform-support/wasm32-wasi-preview2.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# `wasm32-wasi-preview2`
-
-**Tier: 3**
-
-The `wasm32-wasi-preview2` target is a new and still (as of January 2024) an
-experimental target. This target is an extension to `wasm32-wasi-preview1` target,
-originally known as `wasm32-wasi`. It is the next evolution in the development of
-wasi (the [WebAssembly System Interface](https://wasi.dev)) that uses the WebAssembly
-[component model] to allow for a standardized set of syscalls that are intended to empower
-WebAssembly binaries with native host capabilities.
-
-[component model]: https://github.com/WebAssembly/component-model
-
-## Target maintainers
-
-- Alex Crichton, https://github.com/alexcrichton
-- Ryan Levick, https://github.com/rylev
-
-## Requirements
-
-This target is cross-compiled. The target supports `std` fully.
-
-## Platform requirements
-
-The WebAssembly runtime should support the wasi preview 2 API set.
-
-This target is not a stable target. This means that there are only a few engines
-which implement wasi preview 2, for example:
-
-* Wasmtime - `-W component-model`
diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis
index 624d8cc5cc5..5e0c21a13a9 100644
--- a/src/etc/natvis/libcore.natvis
+++ b/src/etc/natvis/libcore.natvis
@@ -41,40 +41,7 @@
     </Expand>
   </Type>
 
-  <Type Name="core::num::nonzero::NonZeroI8">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI16">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI32">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI64">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI128">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroIsize">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU8">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU16">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU32">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU64">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU128">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroUsize">
+  <Type Name="core::num::nonzero::NonZero&lt;*&gt;">
     <DisplayString>{__0}</DisplayString>
   </Type>
 
@@ -99,9 +66,9 @@
   </Type>
 
   <Type Name="core::pin::Pin&lt;*&gt;">
-    <DisplayString>Pin({(void*)pointer}: {pointer})</DisplayString>
+    <DisplayString>Pin({(void*)__pointer}: {__pointer})</DisplayString>
     <Expand>
-      <ExpandedItem>pointer</ExpandedItem>
+      <ExpandedItem>__pointer</ExpandedItem>
     </Expand>
   </Type>
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8706abda979..1e718c70c3c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -15,6 +15,7 @@ use rustc_ast::token::{Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
+use rustc_errors::{codes::*, struct_span_code_err, FatalError};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
@@ -1835,7 +1836,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
         TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
         TyKind::Array(ty, ref length) => {
             let length = match length {
-                hir::ArrayLen::Infer(_, _) => "_".to_string(),
+                hir::ArrayLen::Infer(..) => "_".to_string(),
                 hir::ArrayLen::Body(anon_const) => {
                     // NOTE(min_const_generics): We can't use `const_eval_poly` for constants
                     // as we currently do not supply the parent generics to anonymous constants
@@ -2271,7 +2272,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
         ty::Placeholder(..) => panic!("Placeholder"),
         ty::CoroutineWitness(..) => panic!("CoroutineWitness"),
         ty::Infer(..) => panic!("Infer"),
-        ty::Error(_) => rustc_errors::FatalError.raise(),
+        ty::Error(_) => FatalError.raise(),
     }
 }
 
@@ -2995,7 +2996,7 @@ fn clean_use_statement_inner<'tcx>(
         visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module();
 
     if pub_underscore && let Some(ref inline) = inline_attr {
-        rustc_errors::struct_span_code_err!(
+        struct_span_code_err!(
             cx.tcx.dcx(),
             inline.span(),
             E0780,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7cf385de6b7..9eb62c25892 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::emitter::{DynEmitter, HumanEmitter};
 use rustc_errors::json::JsonEmitter;
-use rustc_errors::TerminalUrl;
+use rustc_errors::{codes::*, TerminalUrl};
 use rustc_feature::UnstableFeatures;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 9c593aa85d9..c01a25534f9 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -638,7 +638,7 @@ ul.block, .block li {
 
 .sidebar-crate h2 a {
 	display: block;
-	margin: 0 calc(-24px + 0.25rem) 0 -0.5rem;
+	margin: 0 calc(-24px + 0.25rem) 0 -0.2rem;
 	/* Align the sidebar crate link with the search bar, which have different
 		font sizes.
 
@@ -653,7 +653,7 @@ ul.block, .block li {
 		x = ( 16px - 0.57rem ) / 2
 	*/
 	padding: calc( ( 16px - 0.57rem ) / 2 ) 0.25rem;
-	padding-left: 0.5rem;
+	padding-left: 0.2rem;
 }
 
 .sidebar-crate h2 .version {
@@ -661,8 +661,6 @@ ul.block, .block li {
 	font-weight: normal;
 	font-size: 1rem;
 	overflow-wrap: break-word;
-	/* opposite of the link padding, cut in half again */
-	margin-top: calc( ( -16px + 0.57rem ) / 2 );
 }
 
 .sidebar-crate + .version {
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index ac9c6f377b8..bda7b3c647e 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -101,6 +101,14 @@ const getVar = (function getVar(name) {
 });
 
 function switchTheme(newThemeName, saveTheme) {
+    const themeNames = getVar("themes").split(",").filter(t => t);
+    themeNames.push(...builtinThemes);
+
+    // Ensure that the new theme name is among the defined themes
+    if (themeNames.indexOf(newThemeName) === -1) {
+        return;
+    }
+
     // If this new value comes from a system setting or from the previously
     // saved theme, no need to save it.
     if (saveTheme) {
@@ -115,7 +123,7 @@ function switchTheme(newThemeName, saveTheme) {
             window.currentTheme = null;
         }
     } else {
-        const newHref = getVar("root-path") + newThemeName +
+        const newHref = getVar("root-path") + encodeURIComponent(newThemeName) +
             getVar("resource-suffix") + ".css";
         if (!window.currentTheme) {
             // If we're in the middle of loading, document.write blocks
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 658ed862ae7..8c10f14116a 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -3,7 +3,6 @@
     html_playground_url = "https://play.rust-lang.org/"
 )]
 #![feature(rustc_private)]
-#![feature(array_methods)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 4d32bbec914..5fa45ceeb39 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5606,6 +5606,7 @@ Released 2018-09-13
 [`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting
 [`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map
 [`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl
+[`suspicious_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_open_options
 [`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings
 [`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn
 [`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned
@@ -5814,6 +5815,7 @@ Released 2018-09-13
 [`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
 [`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
 [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
+[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
 [`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
 [`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
 [`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 3b62ae0524a..7f7aff92bf1 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -212,7 +212,7 @@ default configuration of Clippy. By default, any configuration will replace the
 * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
 * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
@@ -768,7 +768,19 @@ Additional dotfiles (files or directories starting with a dot) to allow
 * [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
 
 
+## `allowed-duplicate-crates`
+A list of crate names to allow duplicates of
+
+**Default Value:** `[]`
+
+---
+**Affected lints:**
+* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
+
+
 ## `enforce-iter-loop-reborrow`
+Whether to recommend using implicit into iter for reborrowed values.
+
 #### Example
 ```no_run
 let mut vec = vec![1, 2, 3];
@@ -793,7 +805,7 @@ for _ in &mut *rmvec {}
 
 
 ## `check-private-items`
-
+Whether to also run the listed lints on private items.
 
 **Default Value:** `false`
 
@@ -806,9 +818,10 @@ for _ in &mut *rmvec {}
 
 
 ## `pub-underscore-fields-behavior`
+Lint "public" fields in a struct that are prefixed with an underscore based on their
+exported visibility, or whether they are marked as "pub".
 
-
-**Default Value:** `"PublicallyExported"`
+**Default Value:** `"PubliclyExported"`
 
 ---
 **Affected lints:**
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 5477d9b83a7..4e9ddbf8259 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -2,7 +2,9 @@ use crate::msrvs::Msrv;
 use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename};
 use crate::ClippyConfiguration;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
 use rustc_session::Session;
+use rustc_span::edit_distance::edit_distance;
 use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
 use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};
 use serde::{Deserialize, Deserializer, Serialize};
@@ -26,7 +28,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
     "NaN", "NaNs",
     "OAuth", "GraphQL",
     "OCaml",
-    "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS",
+    "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry",
     "WebGL", "WebGL2", "WebGPU",
     "TensorFlow",
     "TrueType",
@@ -59,18 +61,25 @@ impl TryConf {
 #[derive(Debug)]
 struct ConfError {
     message: String,
+    suggestion: Option<Suggestion>,
     span: Span,
 }
 
 impl ConfError {
     fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self {
         let span = error.span().unwrap_or(0..file.source_len.0 as usize);
-        Self::spanned(file, error.message(), span)
+        Self::spanned(file, error.message(), None, span)
     }
 
-    fn spanned(file: &SourceFile, message: impl Into<String>, span: Range<usize>) -> Self {
+    fn spanned(
+        file: &SourceFile,
+        message: impl Into<String>,
+        suggestion: Option<Suggestion>,
+        span: Range<usize>,
+    ) -> Self {
         Self {
             message: message.into(),
+            suggestion,
             span: Span::new(
                 file.start_pos + BytePos::from_usize(span.start),
                 file.start_pos + BytePos::from_usize(span.end),
@@ -147,16 +156,18 @@ macro_rules! define_Conf {
                     match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
                         Err(e) => {
                             let e: FieldError = e;
-                            errors.push(ConfError::spanned(self.0, e.0, name.span()));
+                            errors.push(ConfError::spanned(self.0, e.error, e.suggestion, name.span()));
                         }
                         $(Ok(Field::$name) => {
-                            $(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), name.span()));)?
+                            $(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), None, name.span()));)?
                             let raw_value = map.next_value::<toml::Spanned<toml::Value>>()?;
                             let value_span = raw_value.span();
                             match <$ty>::deserialize(raw_value.into_inner()) {
-                                Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), value_span)),
+                                Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), None, value_span)),
                                 Ok(value) => match $name {
-                                    Some(_) => errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), name.span())),
+                                    Some(_) => {
+                                        errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
+                                    }
                                     None => {
                                         $name = Some(value);
                                         // $new_conf is the same as one of the defined `$name`s, so
@@ -165,7 +176,7 @@ macro_rules! define_Conf {
                                             Some(_) => errors.push(ConfError::spanned(self.0, concat!(
                                                 "duplicate field `", stringify!($new_conf),
                                                 "` (provided as `", stringify!($name), "`)"
-                                            ), name.span())),
+                                            ), None, name.span())),
                                             None => $new_conf = $name.clone(),
                                         })?
                                     },
@@ -523,7 +534,11 @@ define_Conf! {
     ///
     /// Additional dotfiles (files or directories starting with a dot) to allow
     (allowed_dotfiles: FxHashSet<String> = FxHashSet::default()),
-    /// Lint: EXPLICIT_ITER_LOOP
+    /// Lint: MULTIPLE_CRATE_VERSIONS.
+    ///
+    /// A list of crate names to allow duplicates of
+    (allowed_duplicate_crates: FxHashSet<String> = FxHashSet::default()),
+    /// Lint: EXPLICIT_ITER_LOOP.
     ///
     /// Whether to recommend using implicit into iter for reborrowed values.
     ///
@@ -543,15 +558,15 @@ define_Conf! {
     /// for _ in &mut *rmvec {}
     /// ```
     (enforce_iter_loop_reborrow: bool = false),
-    /// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC
+    /// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC.
     ///
     /// Whether to also run the listed lints on private items.
     (check_private_items: bool = false),
-    /// Lint: PUB_UNDERSCORE_FIELDS
+    /// Lint: PUB_UNDERSCORE_FIELDS.
     ///
     /// Lint "public" fields in a struct that are prefixed with an underscore based on their
     /// exported visibility, or whether they are marked as "pub".
-    (pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PublicallyExported),
+    (pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported),
 }
 
 /// Search for the configuration file.
@@ -669,10 +684,16 @@ impl Conf {
 
         // all conf errors are non-fatal, we just use the default conf in case of error
         for error in errors {
-            sess.dcx().span_err(
+            let mut diag = sess.dcx().struct_span_err(
                 error.span,
                 format!("error reading Clippy's configuration file: {}", error.message),
             );
+
+            if let Some(sugg) = error.suggestion {
+                diag.span_suggestion(error.span, sugg.message, sugg.suggestion, Applicability::MaybeIncorrect);
+            }
+
+            diag.emit();
         }
 
         for warning in warnings {
@@ -689,19 +710,31 @@ impl Conf {
 const SEPARATOR_WIDTH: usize = 4;
 
 #[derive(Debug)]
-struct FieldError(String);
+struct FieldError {
+    error: String,
+    suggestion: Option<Suggestion>,
+}
+
+#[derive(Debug)]
+struct Suggestion {
+    message: &'static str,
+    suggestion: &'static str,
+}
 
 impl std::error::Error for FieldError {}
 
 impl Display for FieldError {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.pad(&self.0)
+        f.pad(&self.error)
     }
 }
 
 impl serde::de::Error for FieldError {
     fn custom<T: Display>(msg: T) -> Self {
-        Self(msg.to_string())
+        Self {
+            error: msg.to_string(),
+            suggestion: None,
+        }
     }
 
     fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
@@ -723,7 +756,20 @@ impl serde::de::Error for FieldError {
                 write!(msg, "{:SEPARATOR_WIDTH$}{field:column_width$}", " ").unwrap();
             }
         }
-        Self(msg)
+
+        let suggestion = expected
+            .iter()
+            .filter_map(|expected| {
+                let dist = edit_distance(field, expected, 4)?;
+                Some((dist, expected))
+            })
+            .min_by_key(|&(dist, _)| dist)
+            .map(|(_, suggestion)| Suggestion {
+                message: "perhaps you meant",
+                suggestion,
+            });
+
+        Self { error: msg, suggestion }
     }
 }
 
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index f5dcb16d670..533e375a310 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -11,6 +11,7 @@ extern crate rustc_ast;
 extern crate rustc_data_structures;
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
+extern crate rustc_errors;
 extern crate rustc_session;
 extern crate rustc_span;
 
diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs
index baee09629ac..435aa9244c5 100644
--- a/src/tools/clippy/clippy_config/src/types.rs
+++ b/src/tools/clippy/clippy_config/src/types.rs
@@ -129,6 +129,6 @@ unimplemented_serialize! {
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
 pub enum PubUnderscoreFieldsBehaviour {
-    PublicallyExported,
+    PubliclyExported,
     AllPubFields,
 }
diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml
index ce738e3f4ec..5ec67554e7d 100644
--- a/src/tools/clippy/clippy_dev/Cargo.toml
+++ b/src/tools/clippy/clippy_dev/Cargo.toml
@@ -4,11 +4,11 @@ version = "0.0.1"
 edition = "2021"
 
 [dependencies]
-aho-corasick = "0.7"
+aho-corasick = "1.0"
 clap = "4.1.4"
 indoc = "1.0"
 itertools = "0.11"
-opener = "0.5"
+opener = "0.6"
 shell-escape = "0.1"
 walkdir = "2.3"
 
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 6b76a44debf..2222abff7ad 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -504,9 +504,8 @@ fn replace_ident_like(contents: &str, replacements: &[(&str, &str)]) -> Option<S
     }
 
     let searcher = AhoCorasickBuilder::new()
-        .dfa(true)
         .match_kind(aho_corasick::MatchKind::LeftmostLongest)
-        .build_with_size::<u16, _, _>(replacements.iter().map(|&(x, _)| x.as_bytes()))
+        .build(replacements.iter().map(|&(x, _)| x.as_bytes()))
         .unwrap();
 
     let mut result = String::with_capacity(contents.len() + 1024);
@@ -928,7 +927,7 @@ fn remove_line_splices(s: &str) -> String {
         .and_then(|s| s.strip_suffix('"'))
         .unwrap_or_else(|| panic!("expected quoted string, found `{s}`"));
     let mut res = String::with_capacity(s.len());
-    unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, ch| {
+    unescape::unescape_unicode(s, unescape::Mode::Str, &mut |range, ch| {
         if ch.is_ok() {
             res.push_str(&s[range]);
         }
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 8cba35f3d87..416e9a680dd 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 arrayvec = { version = "0.7", default-features = false }
-cargo_metadata = "0.15.3"
+cargo_metadata = "0.18"
 clippy_config = { path = "../clippy_config" }
 clippy_utils = { path = "../clippy_utils" }
 declare_clippy_lint = { path = "../declare_clippy_lint" }
diff --git a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
index 657d52d0e9e..1102c7fb236 100644
--- a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
+++ b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
@@ -14,10 +14,10 @@ declare_clippy_lint! {
     /// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
     ///
     /// ### Why is this bad?
-    /// `Arc<T>` is an Atomic `RC<T>` and guarantees that updates to the reference counter are
-    /// Atomic. This is useful in multiprocessing scenarios. To send an `Arc<T>` across processes
-    /// and make use of the atomic ref counter, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E),
-    /// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
+    /// `Arc<T>` is a thread-safe `Rc<T>` and guarantees that updates to the reference counter
+    /// use atomic operations. To send an `Arc<T>` across thread boundaries and
+    /// share ownership between multiple threads, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety),
+    /// so either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
     ///
     /// ### Example
     /// ```no_run
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
index 1417e230aee..ff4dffd0607 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -67,6 +67,11 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
         );
 
         if let ExprKind::Block(block, _) = &cond.kind {
+            if !block.span.eq_ctxt(expr.span) {
+                // If the block comes from a macro, or as an argument to a macro,
+                // do not lint.
+                return;
+            }
             if block.rules == BlockCheckMode::DefaultBlock {
                 if block.stmts.is_empty() {
                     if let Some(ex) = &block.expr {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/mod.rs b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
index fea6924d89e..d8107f61f37 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
@@ -6,6 +6,7 @@ mod wildcard_dependencies;
 use cargo_metadata::MetadataCommand;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_lint_allowed;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_lint::{LateContext, LateLintPass, Lint};
 use rustc_session::impl_lint_pass;
@@ -128,6 +129,8 @@ declare_clippy_lint! {
     /// ### Known problems
     /// Because this can be caused purely by the dependencies
     /// themselves, it's not always possible to fix this issue.
+    /// In those cases, you can allow that specific crate using
+    /// the `allowed_duplicate_crates` configuration option.
     ///
     /// ### Example
     /// ```toml
@@ -163,6 +166,7 @@ declare_clippy_lint! {
 }
 
 pub struct Cargo {
+    pub allowed_duplicate_crates: FxHashSet<String>,
     pub ignore_publish: bool,
 }
 
@@ -208,7 +212,7 @@ impl LateLintPass<'_> for Cargo {
         {
             match MetadataCommand::new().exec() {
                 Ok(metadata) => {
-                    multiple_crate_versions::check(cx, &metadata);
+                    multiple_crate_versions::check(cx, &metadata, &self.allowed_duplicate_crates);
                 },
                 Err(e) => {
                     for lint in WITH_DEPS_LINTS {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs b/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
index ec681adb7ae..3f30a77fcfe 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
@@ -3,27 +3,40 @@
 use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId};
 use clippy_utils::diagnostics::span_lint;
 use itertools::Itertools;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_lint::LateContext;
 use rustc_span::DUMMY_SP;
 
 use super::MULTIPLE_CRATE_VERSIONS;
 
-pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {
+pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, allowed_duplicate_crates: &FxHashSet<String>) {
     let local_name = cx.tcx.crate_name(LOCAL_CRATE);
     let mut packages = metadata.packages.clone();
     packages.sort_by(|a, b| a.name.cmp(&b.name));
 
     if let Some(resolve) = &metadata.resolve
         && let Some(local_id) = packages.iter().find_map(|p| {
-            if p.name == local_name.as_str() {
+            // p.name contains the original crate names with dashes intact
+            // local_name contains the crate name as a namespace, with the dashes converted to underscores
+            // the code below temporarily rectifies this discrepancy
+            if p.name
+                .as_bytes()
+                .iter()
+                .map(|b| if b == &b'-' { &b'_' } else { b })
+                .eq(local_name.as_str().as_bytes())
+            {
                 Some(&p.id)
             } else {
                 None
             }
         })
     {
-        for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
+        for (name, group) in &packages
+            .iter()
+            .filter(|p| !allowed_duplicate_crates.contains(&p.name))
+            .group_by(|p| &p.name)
+        {
             let group: Vec<&Package> = group.collect();
 
             if group.len() <= 1 {
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 20230106d53..639edd8da30 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -439,6 +439,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::methods::STR_SPLIT_AT_NEWLINE_INFO,
     crate::methods::SUSPICIOUS_COMMAND_ARG_SPACE_INFO,
     crate::methods::SUSPICIOUS_MAP_INFO,
+    crate::methods::SUSPICIOUS_OPEN_OPTIONS_INFO,
     crate::methods::SUSPICIOUS_SPLITN_INFO,
     crate::methods::SUSPICIOUS_TO_OWNED_INFO,
     crate::methods::TYPE_ID_ON_BOX_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
index 2472e2ee76f..e617c19eff0 100644
--- a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::last_path_segment;
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::{last_path_segment, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -42,12 +42,14 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
             && ty.span.ctxt() == ctxt
         {
             let mut applicability = Applicability::MachineApplicable;
-            let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability);
+            let Some(path) = std_or_core(cx) else { return };
+            let path = format!("{path}::iter::empty");
+            let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability, &path);
             span_lint_and_sugg(
                 cx,
                 DEFAULT_INSTEAD_OF_ITER_EMPTY,
                 expr.span,
-                "`std::iter::empty()` is the more idiomatic way",
+                &format!("`{path}()` is the more idiomatic way"),
                 "try",
                 sugg,
                 applicability,
@@ -61,6 +63,7 @@ fn make_sugg(
     ty_path: &rustc_hir::QPath<'_>,
     ctxt: SyntaxContext,
     applicability: &mut Applicability,
+    path: &str,
 ) -> String {
     if let Some(last) = last_path_segment(ty_path).args
         && let Some(iter_ty) = last.args.iter().find_map(|arg| match arg {
@@ -69,10 +72,10 @@ fn make_sugg(
         })
     {
         format!(
-            "std::iter::empty::<{}>()",
+            "{path}::<{}>()",
             snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0
         )
     } else {
-        "std::iter::empty()".to_owned()
+        format!("{path}()")
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index 712bc075650..c4437a3c4b3 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
+use clippy_utils::numeric_literal;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::{get_parent_node, numeric_literal};
 use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_stmt, Visitor};
-use rustc_hir::{Block, Body, Expr, ExprKind, FnRetTy, HirId, ItemKind, Lit, Node, Stmt, StmtKind};
+use rustc_hir::{Block, Body, ConstContext, Expr, ExprKind, FnRetTy, HirId, Lit, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
@@ -50,11 +50,11 @@ declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]);
 
 impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback {
     fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
-        let is_parent_const = if let Some(Node::Item(item)) = get_parent_node(cx.tcx, body.id().hir_id) {
-            matches!(item.kind, ItemKind::Const(..))
-        } else {
-            false
-        };
+        let hir = cx.tcx.hir();
+        let is_parent_const = matches!(
+            hir.body_const_context(hir.body_owner_def_id(body.id())),
+            Some(ConstContext::Const { inline: false } | ConstContext::Static(_))
+        );
         let mut visitor = NumericFallbackVisitor::new(cx, is_parent_const);
         visitor.visit_body(body);
     }
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index df596338b95..6144ec7b3ca 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy};
-use clippy_utils::{is_lint_allowed, match_def_path, paths};
+use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, paths};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
@@ -450,6 +450,7 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
         && let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq)
         && let Some(def_id) = trait_ref.trait_def_id()
         && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
+        && !has_non_exhaustive_attr(cx.tcx, *adt)
         && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
         && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
         // If all of our fields implement `Eq`, we can implement `Eq` too
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index 8b018220c17..8dde4f227ed 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -6,7 +6,7 @@ use clippy_utils::diagnostics::span_lint;
 use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::HumanEmitter;
-use rustc_errors::DiagCtxt;
+use rustc_errors::{DiagCtxt, DiagnosticBuilder};
 use rustc_lint::LateContext;
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_parse::parser::ForceCollect;
@@ -53,7 +53,7 @@ pub fn check(
                 let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
                     Ok(p) => p,
                     Err(errs) => {
-                        errs.into_iter().for_each(|err| err.cancel());
+                        errs.into_iter().for_each(DiagnosticBuilder::cancel);
                         return (false, test_attr_spans);
                     },
                 };
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index fa1f98ba013..1933a00891b 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -6,8 +6,8 @@ use clippy_utils::source::snippet_opt;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_path, Visitor};
 use rustc_hir::{
-    GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path, PathSegment, Ty,
-    TyKind,
+    FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path,
+    PathSegment, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -197,10 +197,13 @@ fn convert_to_from(
         // fn into([mut] self) -> T  ->  fn into([mut] v: T) -> T
         //               ~~~~                          ~~~~
         (self_ident.span, format!("val: {from}")),
+    ];
+
+    if let FnRetTy::Return(_) = sig.decl.output {
         // fn into(self) -> T  ->  fn into(self) -> Self
         //                  ~                       ~~~~
-        (sig.decl.output.span(), String::from("Self")),
-    ];
+        suggestions.push((sig.decl.output.span(), String::from("Self")));
+    }
 
     let mut finder = SelfFinder {
         cx,
diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs
index fb7b82ec304..1127f00abde 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs
@@ -53,7 +53,9 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
         // List of spans to lint. (lint_span, first_span)
         let mut lint_spans = Vec::new();
 
-        let Ok(impls) = cx.tcx.crate_inherent_impls(()) else { return };
+        let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
+            return;
+        };
         let inherent_impls = cx
             .tcx
             .with_stable_hashing_context(|hcx| impls.inherent_impls.to_sorted(&hcx, true));
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index efdd3925949..feb4d188f39 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -574,6 +574,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         warn_on_all_wildcard_imports,
         check_private_items,
         pub_underscore_fields_behavior,
+        ref allowed_duplicate_crates,
 
         blacklisted_names: _,
         cyclomatic_complexity_threshold: _,
@@ -719,7 +720,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(needless_update::NeedlessUpdate));
     store.register_late_pass(|_| Box::new(needless_borrowed_ref::NeedlessBorrowedRef));
     store.register_late_pass(|_| Box::new(borrow_deref_ref::BorrowDerefRef));
-    store.register_late_pass(|_| Box::new(no_effect::NoEffect));
+    store.register_late_pass(|_| Box::<no_effect::NoEffect>::default());
     store.register_late_pass(|_| Box::new(temporary_assignment::TemporaryAssignment));
     store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv())));
     store.register_late_pass(move |_| {
@@ -947,6 +948,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| {
         Box::new(cargo::Cargo {
             ignore_publish: cargo_ignore_publish,
+            allowed_duplicate_crates: allowed_duplicate_crates.clone(),
         })
     });
     store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index c245eaf1ab4..920a887a6fd 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(
             vec.span,
             "it looks like the same item is being pushed into this Vec",
             None,
-            &format!("try using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
+            &format!("consider using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
         );
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index c22f76484d0..fa4f4a47e38 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lin
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_non_aggregate_primitive_type;
-use clippy_utils::{is_default_equivalent, is_res_lang_ctor, path_res, peel_ref_operators};
+use clippy_utils::{is_default_equivalent, is_res_lang_ctor, path_res, peel_ref_operators, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
 use rustc_hir::{Expr, ExprKind};
@@ -128,6 +128,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
         // check if replacement is mem::MaybeUninit::uninit().assume_init()
         && cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id)
     {
+        let Some(top_crate) = std_or_core(cx) else { return };
         let mut applicability = Applicability::MachineApplicable;
         span_lint_and_sugg(
             cx,
@@ -136,7 +137,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
             "replacing with `mem::MaybeUninit::uninit().assume_init()`",
             "consider using",
             format!(
-                "std::ptr::read({})",
+                "{top_crate}::ptr::read({})",
                 snippet_with_applicability(cx, dest.span, "", &mut applicability)
             ),
             applicability,
@@ -149,6 +150,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
         && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id()
     {
         if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) {
+            let Some(top_crate) = std_or_core(cx) else { return };
             let mut applicability = Applicability::MachineApplicable;
             span_lint_and_sugg(
                 cx,
@@ -157,7 +159,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
                 "replacing with `mem::uninitialized()`",
                 "consider using",
                 format!(
-                    "std::ptr::read({})",
+                    "{top_crate}::ptr::read({})",
                     snippet_with_applicability(cx, dest.span, "", &mut applicability)
                 ),
                 applicability,
@@ -184,14 +186,17 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
         return;
     }
     if is_default_equivalent(cx, src) && !in_external_macro(cx.tcx.sess, expr_span) {
+        let Some(top_crate) = std_or_core(cx) else { return };
         span_lint_and_then(
             cx,
             MEM_REPLACE_WITH_DEFAULT,
             expr_span,
-            "replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`",
+            &format!(
+                "replacing a value of type `T` with `T::default()` is better expressed using `{top_crate}::mem::take`"
+            ),
             |diag| {
                 if !expr_span.from_expansion() {
-                    let suggestion = format!("std::mem::take({})", snippet(cx, dest.span, ""));
+                    let suggestion = format!("{top_crate}::mem::take({})", snippet(cx, dest.span, ""));
 
                     diag.span_suggestion(
                         expr_span,
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 70abe4891d9..4c7c56e7174 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::{get_expr_use_or_unification_node, is_no_std_crate, is_res_lang_ctor, path_res};
+use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core};
 
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
@@ -58,10 +58,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
         return;
     }
 
+    let Some(top_crate) = std_or_core(cx) else { return };
     if let Some(i) = item {
         let sugg = format!(
-            "{}::iter::once({}{})",
-            if is_no_std_crate(cx) { "core" } else { "std" },
+            "{top_crate}::iter::once({}{})",
             iter_type.ref_prefix(),
             snippet(cx, i.span, "...")
         );
@@ -81,11 +81,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
             expr.span,
             &format!("`{method_name}` call on an empty collection"),
             "try",
-            if is_no_std_crate(cx) {
-                "core::iter::empty()".to_string()
-            } else {
-                "std::iter::empty()".to_string()
-            },
+            format!("{top_crate}::iter::empty()"),
             Applicability::MaybeIncorrect,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs b/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
index 02f28779cf6..aa1ec60d434 100644
--- a/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
@@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_a
                     )
                     .span_suggestion(
                         expr_span,
-                        "if this is intentional, try using `Path::new` instead",
+                        "if this is intentional, consider using `Path::new`",
                         format!("PathBuf::from({arg_str})"),
                         Applicability::Unspecified,
                     );
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index 04bdbc1ea25..bf437db7e72 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -50,7 +50,7 @@ pub fn check(
         super::MANUAL_SATURATING_ARITHMETIC,
         expr.span,
         "manual saturating arithmetic",
-        &format!("try using `saturating_{arith}`"),
+        &format!("consider using `saturating_{arith}`"),
         format!(
             "{}.saturating_{arith}({})",
             snippet_with_applicability(cx, arith_lhs.span, "..", &mut applicability),
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
index f9f636bbbf7..27e17b43b01 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -113,9 +113,15 @@ fn handle_path(
     if let Some(path_def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()
         && match_def_path(cx, path_def_id, &paths::CLONE_TRAIT_METHOD)
     {
-        // FIXME: It would be better to infer the type to check if it's copyable or not
-        // to suggest to use `.copied()` instead of `.cloned()` where applicable.
-        lint_path(cx, e.span, recv.span);
+        // The `copied` and `cloned` methods are only available on `&T` and `&mut T` in `Option`
+        // and `Result`.
+        if let ty::Adt(_, args) = cx.typeck_results().expr_ty(recv).kind()
+            && let args = args.as_slice()
+            && let Some(ty) = args.iter().find_map(|generic_arg| generic_arg.as_type())
+            && ty.is_ref()
+        {
+            lint_path(cx, e.span, recv.span, is_copy(cx, ty.peel_refs()));
+        }
     }
 }
 
@@ -139,17 +145,19 @@ fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
     );
 }
 
-fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span) {
+fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {
     let mut applicability = Applicability::MachineApplicable;
 
+    let replacement = if is_copy { "copied" } else { "cloned" };
+
     span_lint_and_sugg(
         cx,
         MAP_CLONE,
         replace,
         "you are explicitly cloning with `.map()`",
-        "consider calling the dedicated `cloned` method",
+        &format!("consider calling the dedicated `{replacement}` method"),
         format!(
-            "{}.cloned()",
+            "{}.{replacement}()",
             snippet_with_applicability(cx, root, "..", &mut applicability),
         ),
         applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 89ea3597dc0..03bcf108914 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -2829,6 +2829,44 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Checks for the suspicious use of `OpenOptions::create()`
+    /// without an explicit `OpenOptions::truncate()`.
+    ///
+    /// ### Why is this bad?
+    /// `create()` alone will either create a new file or open an
+    /// existing file. If the file already exists, it will be
+    /// overwritten when written to, but the file will not be
+    /// truncated by default.
+    /// If less data is written to the file
+    /// than it already contains, the remainder of the file will
+    /// remain unchanged, and the end of the file will contain old
+    /// data.
+    /// In most cases, one should either use `create_new` to ensure
+    /// the file is created from scratch, or ensure `truncate` is
+    /// called so that the truncation behaviour is explicit. `truncate(true)`
+    /// will ensure the file is entirely overwritten with new data, whereas
+    /// `truncate(false)` will explicitely keep the default behavior.
+    ///
+    /// ### Example
+    /// ```rust,no_run
+    /// use std::fs::OpenOptions;
+    ///
+    /// OpenOptions::new().create(true);
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// use std::fs::OpenOptions;
+    ///
+    /// OpenOptions::new().create(true).truncate(true);
+    /// ```
+    #[clippy::version = "1.75.0"]
+    pub SUSPICIOUS_OPEN_OPTIONS,
+    suspicious,
+    "suspicious combination of options for opening a file"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     ///* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
     /// calls on `PathBuf` that can cause overwrites.
     ///
@@ -4033,6 +4071,7 @@ impl_lint_pass!(Methods => [
     MAP_ERR_IGNORE,
     MUT_MUTEX_LOCK,
     NONSENSICAL_OPEN_OPTIONS,
+    SUSPICIOUS_OPEN_OPTIONS,
     PATH_BUF_PUSH_OVERWRITE,
     RANGE_ZIP_WITH_LEN,
     REPEAT_ONCE,
diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
index 65c986dcacc..77484ab91a9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
@@ -1,46 +1,74 @@
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_data_structures::fx::FxHashMap;
+
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
+use clippy_utils::ty::{is_type_diagnostic_item, match_type};
+use clippy_utils::{match_any_def_paths, paths};
 use rustc_ast::ast::LitKind;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
 use rustc_span::source_map::Spanned;
 use rustc_span::{sym, Span};
 
-use super::NONSENSICAL_OPEN_OPTIONS;
+use super::{NONSENSICAL_OPEN_OPTIONS, SUSPICIOUS_OPEN_OPTIONS};
+
+fn is_open_options(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
+    is_type_diagnostic_item(cx, ty, sym::FsOpenOptions) || match_type(cx, ty, &paths::TOKIO_IO_OPEN_OPTIONS)
+}
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
     if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
         && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
-        && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::FsOpenOptions)
+        && is_open_options(cx, cx.tcx.type_of(impl_id).instantiate_identity())
     {
         let mut options = Vec::new();
-        get_open_options(cx, recv, &mut options);
-        check_open_options(cx, &options, e.span);
+        if get_open_options(cx, recv, &mut options) {
+            check_open_options(cx, &options, e.span);
+        }
     }
 }
 
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[derive(Eq, PartialEq, Clone, Debug)]
 enum Argument {
-    True,
-    False,
+    Set(bool),
     Unknown,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Eq, PartialEq, Hash, Clone)]
 enum OpenOption {
-    Write,
+    Append,
+    Create,
+    CreateNew,
     Read,
     Truncate,
-    Create,
-    Append,
+    Write,
+}
+impl std::fmt::Display for OpenOption {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            OpenOption::Append => write!(f, "append"),
+            OpenOption::Create => write!(f, "create"),
+            OpenOption::CreateNew => write!(f, "create_new"),
+            OpenOption::Read => write!(f, "read"),
+            OpenOption::Truncate => write!(f, "truncate"),
+            OpenOption::Write => write!(f, "write"),
+        }
+    }
 }
 
-fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) {
-    if let ExprKind::MethodCall(path, receiver, arguments, _) = argument.kind {
+/// Collects information about a method call chain on `OpenOptions`.
+/// Returns false if an unexpected expression kind was found "on the way",
+/// and linting should then be avoided.
+fn get_open_options(
+    cx: &LateContext<'_>,
+    argument: &Expr<'_>,
+    options: &mut Vec<(OpenOption, Argument, Span)>,
+) -> bool {
+    if let ExprKind::MethodCall(path, receiver, arguments, span) = argument.kind {
         let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
 
         // Only proceed if this is a call on some object of type std::fs::OpenOptions
-        if is_type_diagnostic_item(cx, obj_ty, sym::FsOpenOptions) && !arguments.is_empty() {
+        if !arguments.is_empty() && is_open_options(cx, obj_ty) {
             let argument_option = match arguments[0].kind {
                 ExprKind::Lit(span) => {
                     if let Spanned {
@@ -48,11 +76,12 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
                         ..
                     } = span
                     {
-                        if *lit { Argument::True } else { Argument::False }
+                        Argument::Set(*lit)
                     } else {
                         // The function is called with a literal which is not a boolean literal.
                         // This is theoretically possible, but not very likely.
-                        return;
+                        // We'll ignore it for now
+                        return get_open_options(cx, receiver, options);
                     }
                 },
                 _ => Argument::Unknown,
@@ -60,106 +89,77 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
 
             match path.ident.as_str() {
                 "create" => {
-                    options.push((OpenOption::Create, argument_option));
+                    options.push((OpenOption::Create, argument_option, span));
+                },
+                "create_new" => {
+                    options.push((OpenOption::CreateNew, argument_option, span));
                 },
                 "append" => {
-                    options.push((OpenOption::Append, argument_option));
+                    options.push((OpenOption::Append, argument_option, span));
                 },
                 "truncate" => {
-                    options.push((OpenOption::Truncate, argument_option));
+                    options.push((OpenOption::Truncate, argument_option, span));
                 },
                 "read" => {
-                    options.push((OpenOption::Read, argument_option));
+                    options.push((OpenOption::Read, argument_option, span));
                 },
                 "write" => {
-                    options.push((OpenOption::Write, argument_option));
+                    options.push((OpenOption::Write, argument_option, span));
+                },
+                _ => {
+                    // Avoid linting altogether if this method is from a trait.
+                    // This might be a user defined extension trait with a method like `truncate_write`
+                    // which would be a false positive
+                    if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(argument.hir_id)
+                        && cx.tcx.trait_of_item(method_def_id).is_some()
+                    {
+                        return false;
+                    }
                 },
-                _ => (),
             }
 
-            get_open_options(cx, receiver, options);
+            get_open_options(cx, receiver, options)
+        } else {
+            false
         }
+    } else if let ExprKind::Call(callee, _) = argument.kind
+        && let ExprKind::Path(path) = callee.kind
+        && let Some(did) = cx.qpath_res(&path, callee.hir_id).opt_def_id()
+    {
+        match_any_def_paths(
+            cx,
+            did,
+            &[
+                &paths::TOKIO_IO_OPEN_OPTIONS_NEW,
+                &paths::OPEN_OPTIONS_NEW,
+                &paths::FILE_OPTIONS,
+                &paths::TOKIO_FILE_OPTIONS,
+            ],
+        )
+        .is_some()
+    } else {
+        false
     }
 }
 
-fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)], span: Span) {
-    let (mut create, mut append, mut truncate, mut read, mut write) = (false, false, false, false, false);
-    let (mut create_arg, mut append_arg, mut truncate_arg, mut read_arg, mut write_arg) =
-        (false, false, false, false, false);
-    // This code is almost duplicated (oh, the irony), but I haven't found a way to
-    // unify it.
-
-    for option in options {
-        match *option {
-            (OpenOption::Create, arg) => {
-                if create {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `create` is called more than once",
-                    );
-                } else {
-                    create = true;
-                }
-                create_arg = create_arg || (arg == Argument::True);
-            },
-            (OpenOption::Append, arg) => {
-                if append {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `append` is called more than once",
-                    );
-                } else {
-                    append = true;
-                }
-                append_arg = append_arg || (arg == Argument::True);
-            },
-            (OpenOption::Truncate, arg) => {
-                if truncate {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `truncate` is called more than once",
-                    );
-                } else {
-                    truncate = true;
-                }
-                truncate_arg = truncate_arg || (arg == Argument::True);
-            },
-            (OpenOption::Read, arg) => {
-                if read {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `read` is called more than once",
-                    );
-                } else {
-                    read = true;
-                }
-                read_arg = read_arg || (arg == Argument::True);
-            },
-            (OpenOption::Write, arg) => {
-                if write {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `write` is called more than once",
-                    );
-                } else {
-                    write = true;
-                }
-                write_arg = write_arg || (arg == Argument::True);
-            },
+fn check_open_options(cx: &LateContext<'_>, settings: &[(OpenOption, Argument, Span)], span: Span) {
+    // The args passed to these methods, if they have been called
+    let mut options = FxHashMap::default();
+    for (option, arg, sp) in settings {
+        if let Some((_, prev_span)) = options.insert(option.clone(), (arg.clone(), *sp)) {
+            span_lint(
+                cx,
+                NONSENSICAL_OPEN_OPTIONS,
+                prev_span,
+                &format!("the method `{}` is called more than once", &option),
+            );
         }
     }
 
-    if read && truncate && read_arg && truncate_arg && !(write && write_arg) {
+    if let Some((Argument::Set(true), _)) = options.get(&OpenOption::Read)
+        && let Some((Argument::Set(true), _)) = options.get(&OpenOption::Truncate)
+        && let None | Some((Argument::Set(false), _)) = options.get(&OpenOption::Write)
+    {
         span_lint(
             cx,
             NONSENSICAL_OPEN_OPTIONS,
@@ -167,7 +167,10 @@ fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)],
             "file opened with `truncate` and `read`",
         );
     }
-    if append && truncate && append_arg && truncate_arg {
+
+    if let Some((Argument::Set(true), _)) = options.get(&OpenOption::Append)
+        && let Some((Argument::Set(true), _)) = options.get(&OpenOption::Truncate)
+    {
         span_lint(
             cx,
             NONSENSICAL_OPEN_OPTIONS,
@@ -175,4 +178,29 @@ fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)],
             "file opened with `append` and `truncate`",
         );
     }
+
+    if let Some((Argument::Set(true), create_span)) = options.get(&OpenOption::Create)
+        && let None = options.get(&OpenOption::Truncate)
+        && let None | Some((Argument::Set(false), _)) = options.get(&OpenOption::Append)
+    {
+        span_lint_and_then(
+            cx,
+            SUSPICIOUS_OPEN_OPTIONS,
+            *create_span,
+            "file opened with `create`, but `truncate` behavior not defined",
+            |diag| {
+                diag.span_suggestion(
+                    create_span.shrink_to_hi(),
+                    "add",
+                    ".truncate(true)".to_string(),
+                    rustc_errors::Applicability::MaybeIncorrect,
+                )
+                .help("if you intend to overwrite an existing file entirely, call `.truncate(true)`")
+                .help(
+                    "if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`",
+                )
+                .help("alternatively, use `.append(true)` to append to the file instead of overwriting it");
+            },
+        );
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 756dbe62d84..88e2af15658 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -97,7 +97,7 @@ pub(super) fn check(
         };
         let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" };
         let hint = format!("{}.{method_hint}()", snippet(cx, as_ref_recv.span, ".."));
-        let suggestion = format!("try using {method_hint} instead");
+        let suggestion = format!("consider using {method_hint}");
 
         let msg = format!("called `{current_method}` on an `Option` value");
         span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_or_err_ok.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_or_err_ok.rs
index 91e39d5a1cd..4e424d4c066 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_or_err_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_or_err_ok.rs
@@ -33,7 +33,7 @@ pub(super) fn check<'tcx>(
             OPTION_MAP_OR_ERR_OK,
             expr.span,
             msg,
-            "try using `ok_or` instead",
+            "consider using `ok_or`",
             format!("{self_snippet}.ok_or({err_snippet})"),
             Applicability::MachineApplicable,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs
index ff4d8cc9e3e..193deafccf6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs
@@ -72,7 +72,7 @@ pub(super) fn check<'tcx>(
                 OPTION_MAP_OR_NONE,
                 expr.span,
                 msg,
-                "try using `map` instead",
+                "consider using `map`",
                 format!("{self_snippet}.map({arg_snippet} {func_snippet})"),
                 Applicability::MachineApplicable,
             );
@@ -85,7 +85,7 @@ pub(super) fn check<'tcx>(
             OPTION_MAP_OR_NONE,
             expr.span,
             msg,
-            "try using `and_then` instead",
+            "consider using `and_then`",
             format!("{self_snippet}.and_then({func_snippet})"),
             Applicability::MachineApplicable,
         );
@@ -97,7 +97,7 @@ pub(super) fn check<'tcx>(
             RESULT_MAP_OR_INTO_OPTION,
             expr.span,
             msg,
-            "try using `ok` instead",
+            "consider using `ok`",
             format!("{self_snippet}.ok()"),
             Applicability::MachineApplicable,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs b/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs
index bc16a112816..3b0dc506305 100644
--- a/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/result_map_or_else_none.rs
@@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(
             RESULT_MAP_OR_INTO_OPTION,
             expr.span,
             msg,
-            "try using `ok` instead",
+            "consider using `ok`",
             format!("{self_snippet}.ok()"),
             Applicability::MachineApplicable,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
index 6339011c92f..ef1baa6c988 100644
--- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
@@ -63,7 +63,7 @@ pub(super) fn check<'tcx>(
                     SEARCH_IS_SOME,
                     method_span.with_hi(expr.span.hi()),
                     &msg,
-                    "use `any()` instead",
+                    "consider using",
                     format!(
                         "any({})",
                         any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
@@ -77,7 +77,7 @@ pub(super) fn check<'tcx>(
                     SEARCH_IS_SOME,
                     expr.span,
                     &msg,
-                    "use `!_.any()` instead",
+                    "consider using",
                     format!(
                         "!{iter}.any({})",
                         any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
@@ -118,7 +118,7 @@ pub(super) fn check<'tcx>(
                         SEARCH_IS_SOME,
                         method_span.with_hi(expr.span.hi()),
                         &msg,
-                        "use `contains()` instead",
+                        "consider using",
                         format!("contains({find_arg})"),
                         applicability,
                     );
@@ -132,7 +132,7 @@ pub(super) fn check<'tcx>(
                         SEARCH_IS_SOME,
                         expr.span,
                         &msg,
-                        "use `!_.contains()` instead",
+                        "consider using",
                         format!("!{string}.contains({find_arg})"),
                         applicability,
                     );
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
index 3983f0c0cab..363b1f2b812 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs
@@ -57,7 +57,7 @@ pub(super) fn check(
                 SINGLE_CHAR_PATTERN,
                 arg.span,
                 "single-character string constant used as pattern",
-                "try using a `char` instead",
+                "consider using a `char`",
                 hint,
                 applicability,
             );
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
index e2b389e96da..c3ad4db3875 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
@@ -32,7 +32,7 @@ pub(super) fn check<'tcx>(
             UNNECESSARY_JOIN,
             span.with_hi(expr.span.hi()),
             r#"called `.collect::<Vec<String>>().join("")` on an iterator"#,
-            "try using",
+            "consider using",
             "collect::<String>()".to_owned(),
             applicability,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
index 696e5e74d60..6911da69b94 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -203,7 +203,7 @@ pub(super) fn check<'tcx>(
             cx,
             UNNECESSARY_SORT_BY,
             expr.span,
-            "use Vec::sort_by_key here instead",
+            "consider using `sort_by_key`",
             "try",
             format!(
                 "{}.sort{}_by_key(|{}| {})",
@@ -226,7 +226,7 @@ pub(super) fn check<'tcx>(
             cx,
             UNNECESSARY_SORT_BY,
             expr.span,
-            "use Vec::sort here instead",
+            "consider using `sort`",
             "try",
             format!(
                 "{}.sort{}()",
diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
index 66727e5a29d..514015af045 100644
--- a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
@@ -1,7 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::walk_ptrs_ty_depth;
-use clippy_utils::{get_parent_expr, is_diag_trait_item, match_def_path, paths, peel_blocks};
+use clippy_utils::{
+    get_parent_expr, is_diag_trait_item, match_def_path, path_to_local_id, paths, peel_blocks, strip_pat_refs,
+};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -108,9 +110,12 @@ fn check_qpath(cx: &LateContext<'_>, qpath: hir::QPath<'_>, hir_id: hir::HirId)
 
 fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
     match arg.kind {
-        hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
+        hir::ExprKind::Closure(&hir::Closure { body, .. })
             // If it's a closure, we need to check what is called.
-            let closure_body = cx.tcx.hir().body(body);
+            if let closure_body = cx.tcx.hir().body(body)
+                && let [param] = closure_body.params
+                && let hir::PatKind::Binding(_, local_id, ..) = strip_pat_refs(param.pat).kind =>
+        {
             let closure_expr = peel_blocks(closure_body.value);
             match closure_expr.kind {
                 hir::ExprKind::MethodCall(method, obj, [], _) => {
@@ -122,14 +127,17 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
                         // no autoderefs
                         && !cx.typeck_results().expr_adjustments(obj).iter()
                             .any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
+                        && path_to_local_id(obj, local_id)
                     {
                         true
                     } else {
                         false
                     }
                 },
-                hir::ExprKind::Call(call, [_]) => {
-                    if let hir::ExprKind::Path(qpath) = call.kind {
+                hir::ExprKind::Call(call, [recv]) => {
+                    if let hir::ExprKind::Path(qpath) = call.kind
+                        && path_to_local_id(recv, local_id)
+                    {
                         check_qpath(cx, qpath, call.hir_id)
                     } else {
                         false
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 64ef709e2fa..d2eef6ae433 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -5,16 +5,15 @@ use clippy_utils::visitors::for_each_expr_with_closures;
 use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_qpath, FnKind, Visitor};
+use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     BlockCheckMode, Body, Closure, Expr, ExprKind, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node,
-    PatKind, QPath,
+    PatKind,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::associated_body;
-use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath};
 use rustc_session::impl_lint_pass;
@@ -234,12 +233,29 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
         }
     }
 
-    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
-        cx.tcx.hir().visit_all_item_likes_in_crate(&mut FnNeedsMutVisitor {
-            cx,
-            used_fn_def_ids: &mut self.used_fn_def_ids,
-        });
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        // #11182; do not lint if mutability is required elsewhere
+        if let ExprKind::Path(..) = expr.kind
+            && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id)
+            && let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(expr).kind()
+            && let Some(def_id) = def_id.as_local()
+        {
+            if let Node::Expr(e) = parent
+                && let ExprKind::Call(call, _) = e.kind
+                && call.hir_id == expr.hir_id
+            {
+                return;
+            }
 
+            // We don't need to check each argument individually as you cannot coerce a function
+            // taking `&mut` -> `&`, for some reason, so if we've gotten this far we know it's
+            // passed as a `fn`-like argument (or is unified) and should ignore every "unused"
+            // argument entirely
+            self.used_fn_def_ids.insert(def_id);
+        }
+    }
+
+    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
         for (fn_def_id, unused) in self
             .fn_def_ids_to_maybe_unused_mut
             .iter()
@@ -501,48 +517,3 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
         }
     }
 }
-
-/// A final pass to check for paths referencing this function that require the argument to be
-/// `&mut`, basically if the function is ever used as a `fn`-like argument.
-struct FnNeedsMutVisitor<'a, 'tcx> {
-    cx: &'a LateContext<'tcx>,
-    used_fn_def_ids: &'a mut FxHashSet<LocalDefId>,
-}
-
-impl<'tcx> Visitor<'tcx> for FnNeedsMutVisitor<'_, 'tcx> {
-    type NestedFilter = OnlyBodies;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.cx.tcx.hir()
-    }
-
-    fn visit_qpath(&mut self, qpath: &'tcx QPath<'tcx>, hir_id: HirId, _: Span) {
-        walk_qpath(self, qpath, hir_id);
-
-        let Self { cx, used_fn_def_ids } = self;
-
-        // #11182; do not lint if mutability is required elsewhere
-        if let Node::Expr(expr) = cx.tcx.hir_node(hir_id)
-            && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id)
-            && let ty::FnDef(def_id, _) = cx
-                .tcx
-                .typeck(cx.tcx.hir().enclosing_body_owner(hir_id))
-                .expr_ty(expr)
-                .kind()
-            && let Some(def_id) = def_id.as_local()
-        {
-            if let Node::Expr(e) = parent
-                && let ExprKind::Call(call, _) = e.kind
-                && call.hir_id == expr.hir_id
-            {
-                return;
-            }
-
-            // We don't need to check each argument individually as you cannot coerce a function
-            // taking `&mut` -> `&`, for some reason, so if we've gotten this far we know it's
-            // passed as a `fn`-like argument (or is unified) and should ignore every "unused"
-            // argument entirely
-            used_fn_def_ids.insert(def_id);
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 6bbe427ea29..0d234f7f9b5 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -1,16 +1,18 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::has_drop;
-use clippy_utils::{get_parent_node, is_lint_allowed, peel_blocks};
+use clippy_utils::{any_parent_is_automatically_derived, get_parent_node, is_lint_allowed, path_to_local, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, ItemKind, Node, PatKind, Stmt, StmtKind, UnsafeSource,
+    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, Node, PatKind, Stmt,
+    StmtKind, UnsafeSource,
 };
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::declare_lint_pass;
+use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 use std::ops::Deref;
 
 declare_clippy_lint! {
@@ -74,94 +76,125 @@ declare_clippy_lint! {
     "outer expressions with no effect"
 }
 
-declare_lint_pass!(NoEffect => [NO_EFFECT, UNNECESSARY_OPERATION, NO_EFFECT_UNDERSCORE_BINDING]);
+#[derive(Default)]
+pub struct NoEffect {
+    underscore_bindings: HirIdMap<Span>,
+    local_bindings: Vec<Vec<HirId>>,
+}
+
+impl_lint_pass!(NoEffect => [NO_EFFECT, UNNECESSARY_OPERATION, NO_EFFECT_UNDERSCORE_BINDING]);
 
 impl<'tcx> LateLintPass<'tcx> for NoEffect {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
-        if check_no_effect(cx, stmt) {
+        if self.check_no_effect(cx, stmt) {
             return;
         }
         check_unnecessary_operation(cx, stmt);
     }
-}
 
-fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
-    if let StmtKind::Semi(expr) = stmt.kind {
-        // move `expr.span.from_expansion()` ahead
-        if expr.span.from_expansion() {
-            return false;
+    fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) {
+        self.local_bindings.push(Vec::default());
+    }
+
+    fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) {
+        for hir_id in self.local_bindings.pop().unwrap() {
+            if let Some(span) = self.underscore_bindings.remove(&hir_id) {
+                span_lint_hir(
+                    cx,
+                    NO_EFFECT_UNDERSCORE_BINDING,
+                    hir_id,
+                    span,
+                    "binding to `_` prefixed variable with no side-effect",
+                );
+            }
         }
-        let expr = peel_blocks(expr);
+    }
 
-        if is_operator_overridden(cx, expr) {
-            // Return `true`, to prevent `check_unnecessary_operation` from
-            // linting on this statement as well.
-            return true;
+    fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+        if let Some(def_id) = path_to_local(expr) {
+            self.underscore_bindings.remove(&def_id);
         }
-        if has_no_effect(cx, expr) {
-            span_lint_hir_and_then(
-                cx,
-                NO_EFFECT,
-                expr.hir_id,
-                stmt.span,
-                "statement with no effect",
-                |diag| {
-                    for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
-                        if let Node::Item(item) = parent.1
-                            && let ItemKind::Fn(..) = item.kind
-                            && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
-                            && let [.., final_stmt] = block.stmts
-                            && final_stmt.hir_id == stmt.hir_id
-                        {
-                            let expr_ty = cx.typeck_results().expr_ty(expr);
-                            let mut ret_ty = cx
-                                .tcx
-                                .fn_sig(item.owner_id)
-                                .instantiate_identity()
-                                .output()
-                                .skip_binder();
+    }
+}
+
+impl NoEffect {
+    fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
+        if let StmtKind::Semi(expr) = stmt.kind {
+            // move `expr.span.from_expansion()` ahead
+            if expr.span.from_expansion() {
+                return false;
+            }
+            let expr = peel_blocks(expr);
 
-                            // Remove `impl Future<Output = T>` to get `T`
-                            if cx.tcx.ty_is_opaque_future(ret_ty)
-                                && let Some(true_ret_ty) = cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty)
+            if is_operator_overridden(cx, expr) {
+                // Return `true`, to prevent `check_unnecessary_operation` from
+                // linting on this statement as well.
+                return true;
+            }
+            if has_no_effect(cx, expr) {
+                span_lint_hir_and_then(
+                    cx,
+                    NO_EFFECT,
+                    expr.hir_id,
+                    stmt.span,
+                    "statement with no effect",
+                    |diag| {
+                        for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
+                            if let Node::Item(item) = parent.1
+                                && let ItemKind::Fn(..) = item.kind
+                                && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
+                                && let [.., final_stmt] = block.stmts
+                                && final_stmt.hir_id == stmt.hir_id
                             {
-                                ret_ty = true_ret_ty;
-                            }
+                                let expr_ty = cx.typeck_results().expr_ty(expr);
+                                let mut ret_ty = cx
+                                    .tcx
+                                    .fn_sig(item.owner_id)
+                                    .instantiate_identity()
+                                    .output()
+                                    .skip_binder();
+
+                                // Remove `impl Future<Output = T>` to get `T`
+                                if cx.tcx.ty_is_opaque_future(ret_ty)
+                                    && let Some(true_ret_ty) =
+                                        cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty)
+                                {
+                                    ret_ty = true_ret_ty;
+                                }
 
-                            if !ret_ty.is_unit() && ret_ty == expr_ty {
-                                diag.span_suggestion(
-                                    stmt.span.shrink_to_lo(),
-                                    "did you mean to return it?",
-                                    "return ",
-                                    Applicability::MaybeIncorrect,
-                                );
+                                if !ret_ty.is_unit() && ret_ty == expr_ty {
+                                    diag.span_suggestion(
+                                        stmt.span.shrink_to_lo(),
+                                        "did you mean to return it?",
+                                        "return ",
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                }
                             }
                         }
-                    }
-                },
-            );
-            return true;
-        }
-    } else if let StmtKind::Local(local) = stmt.kind {
-        if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id)
-            && let Some(init) = local.init
-            && local.els.is_none()
-            && !local.pat.span.from_expansion()
-            && has_no_effect(cx, init)
-            && let PatKind::Binding(_, _, ident, _) = local.pat.kind
-            && ident.name.to_ident_string().starts_with('_')
-        {
-            span_lint_hir(
-                cx,
-                NO_EFFECT_UNDERSCORE_BINDING,
-                init.hir_id,
-                stmt.span,
-                "binding to `_` prefixed variable with no side-effect",
-            );
-            return true;
+                    },
+                );
+                return true;
+            }
+        } else if let StmtKind::Local(local) = stmt.kind {
+            if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id)
+                && let Some(init) = local.init
+                && local.els.is_none()
+                && !local.pat.span.from_expansion()
+                && has_no_effect(cx, init)
+                && let PatKind::Binding(_, hir_id, ident, _) = local.pat.kind
+                && ident.name.to_ident_string().starts_with('_')
+                && !any_parent_is_automatically_derived(cx.tcx, local.hir_id)
+            {
+                if let Some(l) = self.local_bindings.last_mut() {
+                    l.push(hir_id);
+                    self.underscore_bindings.insert(hir_id, ident.span);
+                }
+                return true;
+            }
         }
+        false
     }
-    false
 }
 
 fn is_operator_overridden(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 929efb6c574..96ea063aa74 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -1,11 +1,11 @@
 use super::ARITHMETIC_SIDE_EFFECTS;
 use clippy_utils::consts::{constant, constant_simple, Constant};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::type_diagnostic_name;
+use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
@@ -88,37 +88,44 @@ impl ArithmeticSideEffects {
     }
 
     /// Verifies built-in types that have specific allowed operations
-    fn has_specific_allowed_type_and_operation(
-        cx: &LateContext<'_>,
-        lhs_ty: Ty<'_>,
+    fn has_specific_allowed_type_and_operation<'tcx>(
+        cx: &LateContext<'tcx>,
+        lhs_ty: Ty<'tcx>,
         op: &Spanned<hir::BinOpKind>,
-        rhs_ty: Ty<'_>,
+        rhs_ty: Ty<'tcx>,
     ) -> bool {
         let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
-        let is_non_zero_u = |symbol: Option<Symbol>| {
-            matches!(
-                symbol,
-                Some(
-                    sym::NonZeroU128
-                        | sym::NonZeroU16
-                        | sym::NonZeroU32
-                        | sym::NonZeroU64
-                        | sym::NonZeroU8
-                        | sym::NonZeroUsize
-                )
-            )
+        let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| {
+            let tcx = cx.tcx;
+
+            let ty::Adt(adt, substs) = ty.kind() else { return false };
+
+            if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
+                return false;
+            };
+
+            let int_type = substs.type_at(0);
+            let unsigned_int_types = [
+                tcx.types.u8,
+                tcx.types.u16,
+                tcx.types.u32,
+                tcx.types.u64,
+                tcx.types.u128,
+                tcx.types.usize,
+            ];
+
+            unsigned_int_types.contains(&int_type)
         };
         let is_sat_or_wrap = |ty: Ty<'_>| {
-            let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating);
-            let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping);
-            is_sat || is_wrap
+            is_type_diagnostic_item(cx, ty, sym::Saturating) || is_type_diagnostic_item(cx, ty, sym::Wrapping)
         };
 
-        // If the RHS is NonZeroU*, then division or module by zero will never occur
-        if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem {
+        // If the RHS is `NonZero<u*>`, then division or module by zero will never occur.
+        if is_non_zero_u(cx, rhs_ty) && is_div_or_rem {
             return true;
         }
-        // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module
+
+        // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module.
         if is_sat_or_wrap(lhs_ty) {
             return !is_div_or_rem;
         }
diff --git a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
index 9db2e24630a..a69989e400b 100644
--- a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
@@ -1,13 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_opt;
+use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 
 use super::PTR_EQ;
 
-static LINT_MSG: &str = "use `std::ptr::eq` when comparing raw pointers";
-
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     expr: &'tcx Expr<'_>,
@@ -26,13 +25,14 @@ pub(super) fn check<'tcx>(
             && let Some(left_snip) = snippet_opt(cx, left_var.span)
             && let Some(right_snip) = snippet_opt(cx, right_var.span)
         {
+            let Some(top_crate) = std_or_core(cx) else { return };
             span_lint_and_sugg(
                 cx,
                 PTR_EQ,
                 expr.span,
-                LINT_MSG,
+                &format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
                 "try",
-                format!("std::ptr::eq({left_snip}, {right_snip})"),
+                format!("{top_crate}::ptr::eq({left_snip}, {right_snip})"),
                 Applicability::MachineApplicable,
             );
         }
diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs
index 00465ce4381..88b5a6cfe2a 100644
--- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs
+++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs
@@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields {
         };
 
         let is_visible = |field: &FieldDef<'_>| match self.behavior {
-            PubUnderscoreFieldsBehaviour::PublicallyExported => cx.effective_visibilities.is_reachable(field.def_id),
+            PubUnderscoreFieldsBehaviour::PubliclyExported => cx.effective_visibilities.is_reachable(field.def_id),
             PubUnderscoreFieldsBehaviour::AllPubFields => {
                 // If there is a visibility span then the field is marked pub in some way.
                 !field.vis_span.is_empty()
diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
index 62f3c09aa7e..650324d4249 100644
--- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
@@ -1,11 +1,13 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::get_enclosing_block;
 use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
 use clippy_utils::source::snippet;
-use clippy_utils::visitors::for_each_expr;
-use core::ops::ControlFlow;
-use hir::{Expr, ExprKind, Local, PatKind, PathSegment, QPath, StmtKind};
+
+use hir::{Expr, ExprKind, HirId, Local, PatKind, PathSegment, QPath, StmtKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::def::Res;
+use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
@@ -49,57 +51,40 @@ declare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]);
 
 impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &hir::Block<'tcx>) {
-        for (idx, stmt) in block.stmts.iter().enumerate() {
-            if !stmt.span.from_expansion()
-                // matches `let v = Vec::new();`
-                && let StmtKind::Local(local) = stmt.kind
-                && let Local { pat, init: Some(init), .. } = local
-                && let PatKind::Binding(_, _, ident, _) = pat.kind
+        for stmt in block.stmts {
+            if stmt.span.from_expansion() {
+                return;
+            }
+
+            if let StmtKind::Local(local) = stmt.kind
+                && let Local {
+                    pat, init: Some(init), ..
+                } = local
+                && let PatKind::Binding(_, id, ident, _) = pat.kind
                 && let Some(vec_init_kind) = get_vec_init_kind(cx, init)
             {
-                let visitor = |expr: &Expr<'_>| {
-                    if let ExprKind::MethodCall(path, _, [arg], _) = expr.kind
-                        && let PathSegment {
-                            ident: read_or_read_exact,
-                            ..
-                        } = *path
-                        && matches!(read_or_read_exact.as_str(), "read" | "read_exact")
-                        && let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
-                        && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind
-                        && let [inner_seg] = inner_path.segments
-                        && ident.name == inner_seg.ident.name
-                    {
-                        ControlFlow::Break(())
-                    } else {
-                        ControlFlow::Continue(())
-                    }
+                let mut visitor = ReadVecVisitor {
+                    local_id: id,
+                    read_zero_expr: None,
+                    has_resize: false,
                 };
 
-                let (read_found, next_stmt_span) = if let Some(next_stmt) = block.stmts.get(idx + 1) {
-                    // case { .. stmt; stmt; .. }
-                    (for_each_expr(next_stmt, visitor).is_some(), next_stmt.span)
-                } else if let Some(e) = block.expr {
-                    // case { .. stmt; expr }
-                    (for_each_expr(e, visitor).is_some(), e.span)
-                } else {
+                let Some(enclosing_block) = get_enclosing_block(cx, id) else {
                     return;
                 };
+                visitor.visit_block(enclosing_block);
 
-                if read_found && !next_stmt_span.from_expansion() {
+                if let Some(expr) = visitor.read_zero_expr {
                     let applicability = Applicability::MaybeIncorrect;
                     match vec_init_kind {
                         VecInitKind::WithConstCapacity(len) => {
                             span_lint_and_sugg(
                                 cx,
                                 READ_ZERO_BYTE_VEC,
-                                next_stmt_span,
+                                expr.span,
                                 "reading zero byte data to `Vec`",
                                 "try",
-                                format!(
-                                    "{}.resize({len}, 0); {}",
-                                    ident.as_str(),
-                                    snippet(cx, next_stmt_span, "..")
-                                ),
+                                format!("{}.resize({len}, 0); {}", ident.as_str(), snippet(cx, expr.span, "..")),
                                 applicability,
                             );
                         },
@@ -108,25 +93,20 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
                             span_lint_and_sugg(
                                 cx,
                                 READ_ZERO_BYTE_VEC,
-                                next_stmt_span,
+                                expr.span,
                                 "reading zero byte data to `Vec`",
                                 "try",
                                 format!(
                                     "{}.resize({}, 0); {}",
                                     ident.as_str(),
                                     snippet(cx, e.span, ".."),
-                                    snippet(cx, next_stmt_span, "..")
+                                    snippet(cx, expr.span, "..")
                                 ),
                                 applicability,
                             );
                         },
                         _ => {
-                            span_lint(
-                                cx,
-                                READ_ZERO_BYTE_VEC,
-                                next_stmt_span,
-                                "reading zero byte data to `Vec`",
-                            );
+                            span_lint(cx, READ_ZERO_BYTE_VEC, expr.span, "reading zero byte data to `Vec`");
                         },
                     }
                 }
@@ -134,3 +114,47 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
         }
     }
 }
+
+struct ReadVecVisitor<'tcx> {
+    local_id: HirId,
+    read_zero_expr: Option<&'tcx Expr<'tcx>>,
+    has_resize: bool,
+}
+
+impl<'tcx> Visitor<'tcx> for ReadVecVisitor<'tcx> {
+    fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {
+        if let ExprKind::MethodCall(path, receiver, args, _) = e.kind {
+            let PathSegment { ident, .. } = *path;
+
+            match ident.as_str() {
+                "read" | "read_exact" => {
+                    let [arg] = args else { return };
+                    if let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
+                        && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind
+                        && let [inner_seg] = inner_path.segments
+                        && let Res::Local(res_id) = inner_seg.res
+                        && self.local_id == res_id
+                    {
+                        self.read_zero_expr = Some(e);
+                        return;
+                    }
+                },
+                "resize" => {
+                    // If the Vec is resized, then it's a valid read
+                    if let ExprKind::Path(QPath::Resolved(_, inner_path)) = receiver.kind
+                        && let Res::Local(res_id) = inner_path.res
+                        && self.local_id == res_id
+                    {
+                        self.has_resize = true;
+                        return;
+                    }
+                },
+                _ => {},
+            }
+        }
+
+        if !self.has_resize && self.read_zero_expr.is_none() {
+            walk_expr(self, e);
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs
index 2cd3e57f885..6540626f7d5 100644
--- a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs
+++ b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs
@@ -5,6 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Block, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::{ExpnKind, MacroKind, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -39,6 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if !block.span.from_expansion()
             && let Some(expr) = block.expr
+            && !from_attr_macro(expr.span)
             && let t_expr = cx.typeck_results().expr_ty(expr)
             && t_expr.is_unit()
             && let mut app = Applicability::MachineApplicable
@@ -63,3 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned {
         }
     }
 }
+
+fn from_attr_macro(span: Span) -> bool {
+    matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Attr, _))
+}
diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
index 8e181c3ccc7..03877420774 100644
--- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::{is_from_proc_macro, is_in_test_function};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::LocalDefId;
@@ -88,16 +88,18 @@ impl<'tcx> LateLintPass<'tcx> for SingleCallFn {
         };
         cx.tcx.hir().visit_all_item_likes_in_crate(&mut v);
 
-        for usage in self.def_id_to_usage.values() {
+        for (&def_id, usage) in &self.def_id_to_usage {
             let single_call_fn_span = usage.0;
             if let [caller_span] = *usage.1 {
-                span_lint_and_help(
+                span_lint_hir_and_then(
                     cx,
                     SINGLE_CALL_FN,
+                    cx.tcx.local_def_id_to_hir_id(def_id),
                     single_call_fn_span,
                     "this function is only used once",
-                    Some(caller_span),
-                    "used here",
+                    |diag| {
+                        diag.span_help(caller_span, "used here");
+                    },
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index e4054393d0a..768623b5d03 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -390,6 +390,14 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'
     }
 }
 
+fn get_ty_res(ty: Ty<'_>) -> Option<Res> {
+    match ty.kind {
+        TyKind::Path(QPath::Resolved(_, path)) => Some(path.res),
+        TyKind::Path(QPath::TypeRelative(ty, _)) => get_ty_res(*ty),
+        _ => None,
+    }
+}
+
 // FIXME: ComparableTraitRef does not support nested bounds needed for associated_type_bounds
 fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
     ComparableTraitRef(
@@ -401,10 +409,8 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
             .filter_map(|segment| {
                 // get trait bound type arguments
                 Some(segment.args?.args.iter().filter_map(|arg| {
-                    if let GenericArg::Type(ty) = arg
-                        && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
-                    {
-                        return Some(path.res);
+                    if let GenericArg::Type(ty) = arg {
+                        return get_ty_res(**ty);
                     }
                     None
                 }))
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
index 7d31c375f8c..2a6c2481254 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_INT_TO_CHAR;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::sugg;
+use clippy_utils::{std_or_core, sugg};
 use rustc_ast as ast;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
@@ -25,6 +25,7 @@ pub(super) fn check<'tcx>(
                 e.span,
                 &format!("transmute from a `{from_ty}` to a `char`"),
                 |diag| {
+                    let Some(top_crate) = std_or_core(cx) else { return };
                     let arg = sugg::Sugg::hir(cx, arg, "..");
                     let arg = if let ty::Int(_) = from_ty.kind() {
                         arg.as_ty(ast::UintTy::U32.name_str())
@@ -34,7 +35,7 @@ pub(super) fn check<'tcx>(
                     diag.span_suggestion(
                         e.span,
                         "consider using",
-                        format!("std::char::from_u32({arg}).unwrap()"),
+                        format!("{top_crate}::char::from_u32({arg}).unwrap()"),
                         Applicability::Unspecified,
                     );
                 },
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
index 5df645491ff..97068efd43c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
@@ -16,40 +16,55 @@ pub(super) fn check<'tcx>(
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
 ) -> bool {
-    let (ty::Int(_) | ty::Uint(_), Some(to_ty_adt)) = (&from_ty.kind(), to_ty.ty_adt_def()) else {
+    let tcx = cx.tcx;
+
+    let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
         return false;
     };
-    let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_adt.did()) else {
+
+    if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
         return false;
     };
 
-    if !matches!(
-        to_type_sym,
-        sym::NonZeroU8
-            | sym::NonZeroU16
-            | sym::NonZeroU32
-            | sym::NonZeroU64
-            | sym::NonZeroU128
-            | sym::NonZeroI8
-            | sym::NonZeroI16
-            | sym::NonZeroI32
-            | sym::NonZeroI64
-            | sym::NonZeroI128
-    ) {
+    // FIXME: This can be simplified once `NonZero<T>` is stable.
+    let coercable_types = [
+        ("NonZeroU8", tcx.types.u8),
+        ("NonZeroU16", tcx.types.u16),
+        ("NonZeroU32", tcx.types.u32),
+        ("NonZeroU64", tcx.types.u64),
+        ("NonZeroU128", tcx.types.u128),
+        ("NonZeroUsize", tcx.types.usize),
+        ("NonZeroI8", tcx.types.i8),
+        ("NonZeroI16", tcx.types.i16),
+        ("NonZeroI32", tcx.types.i32),
+        ("NonZeroI64", tcx.types.i64),
+        ("NonZeroI128", tcx.types.i128),
+        ("NonZeroIsize", tcx.types.isize),
+    ];
+
+    let int_type = substs.type_at(0);
+
+    let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
+        if *t == int_type && *t == from_ty {
+            Some(nonzero_alias)
+        } else {
+            None
+        }
+    }) else {
         return false;
-    }
+    };
 
     span_lint_and_then(
         cx,
         TRANSMUTE_INT_TO_NON_ZERO,
         e.span,
-        &format!("transmute from a `{from_ty}` to a `{to_type_sym}`"),
+        &format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
         |diag| {
             let arg = sugg::Sugg::hir(cx, arg, "..");
             diag.span_suggestion(
                 e.span,
                 "consider using",
-                format!("{to_type_sym}::{}({arg})", sym::new_unchecked),
+                format!("{nonzero_alias}::{}({arg})", sym::new_unchecked),
                 Applicability::Unspecified,
             );
         },
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
index 98e9ea2d775..6c885ebdea1 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
@@ -1,7 +1,7 @@
 use super::{TRANSMUTE_BYTES_TO_STR, TRANSMUTE_PTR_TO_PTR};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet;
-use clippy_utils::sugg;
+use clippy_utils::{std_or_core, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
@@ -25,6 +25,8 @@ pub(super) fn check<'tcx>(
             && let ty::Uint(ty::UintTy::U8) = slice_ty.kind()
             && from_mutbl == to_mutbl
         {
+            let Some(top_crate) = std_or_core(cx) else { return true };
+
             let postfix = if *from_mutbl == Mutability::Mut { "_mut" } else { "" };
 
             let snippet = snippet(cx, arg.span, "..");
@@ -36,9 +38,9 @@ pub(super) fn check<'tcx>(
                 &format!("transmute from a `{from_ty}` to a `{to_ty}`"),
                 "consider using",
                 if const_context {
-                    format!("std::str::from_utf8_unchecked{postfix}({snippet})")
+                    format!("{top_crate}::str::from_utf8_unchecked{postfix}({snippet})")
                 } else {
-                    format!("std::str::from_utf8{postfix}({snippet}).unwrap()")
+                    format!("{top_crate}::str::from_utf8{postfix}({snippet}).unwrap()")
                 },
                 Applicability::MaybeIncorrect,
             );
diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
index 1cf6cf8548a..7a7bb9f9c94 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
@@ -37,12 +37,6 @@ pub(super) fn check_cast<'tcx>(
     let inherited = Inherited::new(cx.tcx, local_def_id);
     let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, local_def_id);
 
-    // If we already have errors, we can't be sure we can pointer cast.
-    assert!(
-        !fn_ctxt.errors_reported_since_creation(),
-        "Newly created FnCtxt contained errors"
-    );
-
     if let Ok(check) = cast::CastCheck::new(
         &fn_ctxt,
         e,
@@ -53,17 +47,7 @@ pub(super) fn check_cast<'tcx>(
         DUMMY_SP,
         hir::Constness::NotConst,
     ) {
-        let res = check.do_check(&fn_ctxt);
-
-        // do_check's documentation says that it might return Ok and create
-        // errors in the fcx instead of returning Err in some cases. Those cases
-        // should be filtered out before getting here.
-        assert!(
-            !fn_ctxt.errors_reported_since_creation(),
-            "`fn_ctxt` contained errors after cast check!"
-        );
-
-        res.ok()
+        check.do_check(&fn_ctxt).ok()
     } else {
         None
     }
diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
index b418db53ea4..209035804e4 100644
--- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
@@ -167,7 +167,15 @@ fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: Loca
                     false
                 }
             },
-            ExprKind::MethodCall(segment, _receiver, &[_arg], _) if segment.ident.name == name.name => {
+            ExprKind::MethodCall(segment, receiver, &[_arg], _) if segment.ident.name == name.name => {
+                if let Some(ty) = cx.typeck_results().expr_ty_opt(receiver)
+                    && let Some(ty_id) = get_ty_def_id(ty)
+                    && self_arg != ty_id
+                {
+                    // Since this called on a different type, the lint should not be
+                    // triggered here.
+                    return;
+                }
                 if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
                     && let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
                     && trait_id == trait_def_id
diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
index 1de9adfcb96..adc66e15ff5 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -1,9 +1,10 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::{is_trait_method, is_try, match_trait_method, paths};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths};
+use hir::{ExprKind, PatKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
+use rustc_span::{sym, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -45,126 +46,219 @@ declare_clippy_lint! {
 
 declare_lint_pass!(UnusedIoAmount => [UNUSED_IO_AMOUNT]);
 
+#[derive(Copy, Clone)]
+enum IoOp {
+    AsyncWrite(bool),
+    AsyncRead(bool),
+    SyncRead(bool),
+    SyncWrite(bool),
+}
+
 impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
-    fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
-        let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = s.kind else {
-            return;
-        };
+    /// We perform the check on the block level.
+    /// If we want to catch match and if expressions that act as returns of the block
+    ///   we need to check them at `check_expr` or `check_block` as they are not stmts
+    ///   but we can't check them at `check_expr` because we need the broader context
+    ///   because we should do this only for the final expression of the block, and not for
+    ///   `StmtKind::Local` which binds values => the io amount is used.
+    ///
+    /// To check for unused io amount in stmts, we only consider `StmtKind::Semi`.
+    /// `StmtKind::Local` is not considered because it binds values => the io amount is used.
+    /// `StmtKind::Expr` is not considered because requires unit type => the io amount is used.
+    /// `StmtKind::Item` is not considered because it's not an expression.
+    ///
+    /// We then check the individual expressions via `check_expr`. We use the same logic for
+    /// semi expressions and the final expression as we need to check match and if expressions
+    /// for binding of the io amount to `Ok(_)`.
+    ///
+    /// We explicitly check for the match source to be Normal as it needs special logic
+    /// to consider the arms, and we want to avoid breaking the logic for situations where things
+    /// get desugared to match.
+    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) {
+        for stmt in block.stmts {
+            if let hir::StmtKind::Semi(exp) = stmt.kind {
+                check_expr(cx, exp);
+            }
+        }
 
-        match expr.kind {
-            hir::ExprKind::Match(res, _, _) if is_try(cx, expr).is_some() => {
-                if let hir::ExprKind::Call(func, [ref arg_0, ..]) = res.kind {
-                    if matches!(
-                        func.kind,
-                        hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
-                    ) {
-                        check_map_error(cx, arg_0, expr);
+        if let Some(exp) = block.expr
+            && matches!(exp.kind, hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _))
+        {
+            check_expr(cx, exp);
+        }
+    }
+}
+
+fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
+    match expr.kind {
+        hir::ExprKind::If(cond, _, _)
+            if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind
+                && pattern_is_ignored_ok(cx, pat)
+                && let Some(op) = should_lint(cx, init) =>
+        {
+            emit_lint(cx, cond.span, op, &[pat.span]);
+        },
+        hir::ExprKind::Match(expr, arms, hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
+            let found_arms: Vec<_> = arms
+                .iter()
+                .filter_map(|arm| {
+                    if pattern_is_ignored_ok(cx, arm.pat) {
+                        Some(arm.span)
+                    } else {
+                        None
                     }
-                } else {
-                    check_map_error(cx, res, expr);
-                }
-            },
-            hir::ExprKind::MethodCall(path, arg_0, ..) => match path.ident.as_str() {
-                "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" | "is_ok" | "is_err" => {
-                    check_map_error(cx, arg_0, expr);
-                },
-                _ => (),
-            },
-            _ => (),
+                })
+                .collect();
+            if !found_arms.is_empty() {
+                emit_lint(cx, expr.span, op, found_arms.as_slice());
+            }
+        },
+        _ if let Some(op) = should_lint(cx, expr) => {
+            emit_lint(cx, expr.span, op, &[]);
+        },
+        _ => {},
+    };
+}
+
+fn should_lint<'a>(cx: &LateContext<'a>, mut inner: &'a hir::Expr<'a>) -> Option<IoOp> {
+    inner = unpack_match(inner);
+    inner = unpack_try(inner);
+    inner = unpack_call_chain(inner);
+    inner = unpack_await(inner);
+    // we type-check it to get whether it's a read/write or their vectorized forms
+    // and keep only the ones that are produce io amount
+    check_io_mode(cx, inner)
+}
+
+fn pattern_is_ignored_ok(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> bool {
+    // the if checks whether we are in a result Ok( ) pattern
+    // and the return checks whether it is unhandled
+
+    if let PatKind::TupleStruct(ref path, inner_pat, ddp) = pat.kind
+        // we check against Result::Ok to avoid linting on Err(_) or something else.
+        && is_res_lang_ctor(cx, cx.qpath_res(path, pat.hir_id), hir::LangItem::ResultOk)
+    {
+        return match (inner_pat, ddp.as_opt_usize()) {
+            // Ok(_) pattern
+            ([inner_pat], None) if matches!(inner_pat.kind, PatKind::Wild) => true,
+            // Ok(..) pattern
+            ([], Some(0)) => true,
+            _ => false,
+        };
+    }
+    false
+}
+
+fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
+    while let hir::ExprKind::MethodCall(path, receiver, ..) = expr.kind {
+        if matches!(
+            path.ident.as_str(),
+            "unwrap" | "expect" | "unwrap_or" | "unwrap_or_else" | "ok" | "is_ok" | "is_err" | "or_else" | "or"
+        ) {
+            expr = receiver;
+        } else {
+            break;
         }
     }
+    expr
+}
+
+fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
+    while let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind
+        && matches!(
+            func.kind,
+            hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
+        )
+    {
+        expr = arg_0;
+    }
+    expr
+}
+
+fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
+    while let hir::ExprKind::Match(res, _, _) = expr.kind {
+        expr = res;
+    }
+    expr
 }
 
 /// If `expr` is an (e).await, return the inner expression "e" that's being
 /// waited on.  Otherwise return None.
-fn try_remove_await<'a>(expr: &'a hir::Expr<'a>) -> Option<&hir::Expr<'a>> {
+fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
     if let hir::ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
         if let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind {
             if matches!(
                 func.kind,
                 hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..))
             ) {
-                return Some(arg_0);
+                return arg_0;
             }
         }
     }
-
-    None
+    expr
 }
 
-fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
-    let mut call = call;
-    while let hir::ExprKind::MethodCall(path, receiver, ..) = call.kind {
-        if matches!(path.ident.as_str(), "or" | "or_else" | "ok") {
-            call = receiver;
-        } else {
-            break;
-        }
-    }
+/// Check whether the current expr is a function call for an IO operation
+fn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option<IoOp> {
+    let hir::ExprKind::MethodCall(path, ..) = call.kind else {
+        return None;
+    };
 
-    if let Some(call) = try_remove_await(call) {
-        check_method_call(cx, call, expr, true);
-    } else {
-        check_method_call(cx, call, expr, false);
+    let vectorized = match path.ident.as_str() {
+        "write_vectored" | "read_vectored" => true,
+        "write" | "read" => false,
+        _ => {
+            return None;
+        },
+    };
+
+    match (
+        is_trait_method(cx, call, sym::IoRead),
+        is_trait_method(cx, call, sym::IoWrite),
+        match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCREADEXT)
+            || match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCREADEXT),
+        match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCWRITEEXT)
+            || match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCWRITEEXT),
+    ) {
+        (true, _, _, _) => Some(IoOp::SyncRead(vectorized)),
+        (_, true, _, _) => Some(IoOp::SyncWrite(vectorized)),
+        (_, _, true, _) => Some(IoOp::AsyncRead(vectorized)),
+        (_, _, _, true) => Some(IoOp::AsyncWrite(vectorized)),
+        _ => None,
     }
 }
 
-fn check_method_call(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>, is_await: bool) {
-    if let hir::ExprKind::MethodCall(path, ..) = call.kind {
-        let symbol = path.ident.as_str();
-        let read_trait = if is_await {
-            match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCREADEXT)
-                || match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCREADEXT)
-        } else {
-            is_trait_method(cx, call, sym::IoRead)
-        };
-        let write_trait = if is_await {
-            match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCWRITEEXT)
-                || match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCWRITEEXT)
-        } else {
-            is_trait_method(cx, call, sym::IoWrite)
-        };
+fn emit_lint(cx: &LateContext<'_>, span: Span, op: IoOp, wild_cards: &[Span]) {
+    let (msg, help) = match op {
+        IoOp::AsyncRead(false) => (
+            "read amount is not handled",
+            Some("use `AsyncReadExt::read_exact` instead, or handle partial reads"),
+        ),
+        IoOp::SyncRead(false) => (
+            "read amount is not handled",
+            Some("use `Read::read_exact` instead, or handle partial reads"),
+        ),
+        IoOp::SyncWrite(false) => (
+            "written amount is not handled",
+            Some("use `Write::write_all` instead, or handle partial writes"),
+        ),
+        IoOp::AsyncWrite(false) => (
+            "written amount is not handled",
+            Some("use `AsyncWriteExt::write_all` instead, or handle partial writes"),
+        ),
+        IoOp::SyncRead(true) | IoOp::AsyncRead(true) => ("read amount is not handled", None),
+        IoOp::SyncWrite(true) | IoOp::AsyncWrite(true) => ("written amount is not handled", None),
+    };
 
-        match (read_trait, write_trait, symbol, is_await) {
-            (true, _, "read", false) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "read amount is not handled",
-                None,
-                "use `Read::read_exact` instead, or handle partial reads",
-            ),
-            (true, _, "read", true) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "read amount is not handled",
-                None,
-                "use `AsyncReadExt::read_exact` instead, or handle partial reads",
-            ),
-            (true, _, "read_vectored", _) => {
-                span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "read amount is not handled");
-            },
-            (_, true, "write", false) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "written amount is not handled",
-                None,
-                "use `Write::write_all` instead, or handle partial writes",
-            ),
-            (_, true, "write", true) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "written amount is not handled",
-                None,
-                "use `AsyncWriteExt::write_all` instead, or handle partial writes",
-            ),
-            (_, true, "write_vectored", _) => {
-                span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "written amount is not handled");
-            },
-            _ => (),
+    span_lint_and_then(cx, UNUSED_IO_AMOUNT, span, msg, |diag| {
+        if let Some(help_str) = help {
+            diag.help(help_str);
         }
-    }
+        for span in wild_cards {
+            diag.span_note(
+                *span,
+                "the result is consumed here, but the amount of I/O bytes remains unhandled",
+            );
+        }
+    });
 }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
index 5ddedb24b15..4822970e47e 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {
                                         ident.span,
                                         "non-standard lint formulation",
                                         None,
-                                        &format!("try using `{}` instead", formulation.correction),
+                                        &format!("consider using `{}`", formulation.correction),
                                     );
                                 }
                                 return;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 4fb615e1d57..c62ae8d718d 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -71,7 +71,9 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
         SimplifiedType::Str,
     ]
     .iter()
-    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied());
+    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter())
+    .flatten()
+    .copied();
     for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
         let lang_item_path = cx.get_def_path(item_def_id);
         if path_syms.starts_with(&lang_item_path) {
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index ad8619f0d3d..2d0c2cf1253 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -1,5 +1,6 @@
 use rustc_ast::{ast, attr};
 use rustc_errors::Applicability;
+use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
 use rustc_span::sym;
 use std::str::FromStr;
@@ -159,3 +160,14 @@ pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
         .filter_map(ast::Attribute::meta_item_list)
         .any(|l| attr::list_contains_name(&l, sym::hidden))
 }
+
+pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
+    adt.is_variant_list_non_exhaustive()
+        || tcx.has_attr(adt.did(), sym::non_exhaustive)
+        || adt.variants().iter().any(|variant_def| {
+            variant_def.is_field_list_non_exhaustive() || tcx.has_attr(variant_def.def_id, sym::non_exhaustive)
+        })
+        || adt
+            .all_fields()
+            .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive))
+}
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 979b117db25..4fa93ad23c3 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -134,7 +134,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     /// Checks whether two blocks are the same.
     #[expect(clippy::similar_names)]
     fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool {
-        use TokenKind::{BlockComment, LineComment, Semi, Whitespace};
+        use TokenKind::{Semi, Whitespace};
         if left.stmts.len() != right.stmts.len() {
             return false;
         }
@@ -177,7 +177,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 return false;
             }
             if !eq_span_tokens(self.inner.cx, lstart..lstmt_span.lo, rstart..rstmt_span.lo, |t| {
-                !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)
+                !matches!(t, Whitespace | Semi)
             }) {
                 return false;
             }
@@ -212,7 +212,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             return false;
         }
         eq_span_tokens(self.inner.cx, lstart..lend, rstart..rend, |t| {
-            !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)
+            !matches!(t, Whitespace | Semi)
         })
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index ebe520b27eb..4e499ff4cc6 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -536,7 +536,12 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
         "f32" => SimplifiedType::Float(FloatTy::F32),
         "f64" => SimplifiedType::Float(FloatTy::F64),
         #[allow(trivial_casts)]
-        _ => return Result::<_, rustc_errors::ErrorGuaranteed>::Ok(&[] as &[_]).into_iter().flatten().copied(),
+        _ => {
+            return Result::<_, rustc_errors::ErrorGuaranteed>::Ok(&[] as &[_])
+                .into_iter()
+                .flatten()
+                .copied();
+        },
     };
 
     tcx.incoherent_impls(ty).into_iter().flatten().copied()
@@ -1712,7 +1717,6 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
         PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
         PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
         PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
-        PatKind::Lit(..) | PatKind::Range(..) => true,
         PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
         PatKind::Or(pats) => {
             // TODO: should be the honest check, that pats is exhaustive set
@@ -1736,7 +1740,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
                 },
             }
         },
-        PatKind::Err(_) => true,
+        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) => true,
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 0a820a1754c..0051f784514 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -26,6 +26,7 @@ pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
 pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"];
 pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
 pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
+pub const FILE_OPTIONS: [&str; 4] = ["std", "fs", "File", "options"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
@@ -50,6 +51,7 @@ pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
 pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
 pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
 pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
+pub const OPEN_OPTIONS_NEW: [&str; 4] = ["std", "fs", "OpenOptions", "new"];
 pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
 pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
 pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
@@ -89,9 +91,15 @@ pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol",
 pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
 pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const TOKIO_FILE_OPTIONS: [&str; 5] = ["tokio", "fs", "file", "File", "options"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const TOKIO_IO_ASYNCREADEXT: [&str; 5] = ["tokio", "io", "util", "async_read_ext", "AsyncReadExt"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const TOKIO_IO_ASYNCWRITEEXT: [&str; 5] = ["tokio", "io", "util", "async_write_ext", "AsyncWriteExt"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const TOKIO_IO_OPEN_OPTIONS: [&str; 4] = ["tokio", "fs", "open_options", "OpenOptions"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const TOKIO_IO_OPEN_OPTIONS_NEW: [&str; 5] = ["tokio", "fs", "open_options", "OpenOptions", "new"];
 pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
 pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
 pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "iter"];
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 59ebe685c11..11bb16ff6c5 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -219,7 +219,8 @@ pub fn implements_trait<'tcx>(
 
 /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
 ///
-/// The `callee_id` argument is used to determine whether this is a function call in a `const fn` environment, used for checking const traits.
+/// The `callee_id` argument is used to determine whether this is a function call in a `const fn`
+/// environment, used for checking const traits.
 pub fn implements_trait_with_env<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 2589d46e7da..d2d56e59ee3 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-01-11"
+channel = "nightly-2024-01-25"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr
new file mode 100644
index 00000000000..8f0ca764924
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr
@@ -0,0 +1,6 @@
+error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9
+  |
+  = note: `-D clippy::multiple-crate-versions` implied by `-D warnings`
+  = help: to override `-D warnings` add `#[allow(clippy::multiple_crate_versions)]`
+
+error: could not compile `multiple-crate-versions` (bin "multiple-crate-versions") due to 1 previous error
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml
new file mode 100644
index 00000000000..d39ad6c909a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml
@@ -0,0 +1,14 @@
+# Should not lint for dev or build dependencies. See issue 5041.
+
+[package]
+# purposefully separated by - instead of _
+name = "multiple-crate-versions"
+version = "0.1.0"
+publish = false
+
+[workspace]
+
+# One of the versions of winapi is only a dev dependency: allowed
+[dependencies]
+winapi = "0.2"
+ansi_term = "=0.11.0"
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs
new file mode 100644
index 00000000000..4bc61dd6299
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs
@@ -0,0 +1,3 @@
+#![warn(clippy::multiple_crate_versions)]
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml
new file mode 100644
index 00000000000..79317659ac0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "multiple_crate_versions"
+version = "0.1.0"
+publish = false
+
+[workspace]
+
+[dependencies]
+winapi = "0.2"
+ansi_term = "=0.11.0"
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml
new file mode 100644
index 00000000000..121361de2fe
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml
@@ -0,0 +1 @@
+allowed-duplicate-crates = ["winapi"]
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs
new file mode 100644
index 00000000000..4bc61dd6299
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs
@@ -0,0 +1,3 @@
+#![warn(clippy::multiple_crate_versions)]
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/check_formulation.stderr b/src/tools/clippy/tests/ui-internal/check_formulation.stderr
index 96fa617601f..42a872d9a83 100644
--- a/src/tools/clippy/tests/ui-internal/check_formulation.stderr
+++ b/src/tools/clippy/tests/ui-internal/check_formulation.stderr
@@ -4,7 +4,7 @@ error: non-standard lint formulation
 LL |     /// Check for lint formulations that are correct
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try using `Checks for` instead
+   = help: consider using `Checks for`
    = note: `-D clippy::almost-standard-lint-formulation` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::almost_standard_lint_formulation)]`
 
@@ -14,7 +14,7 @@ error: non-standard lint formulation
 LL |     /// Detects uses of incorrect formulations
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try using `Checks for` instead
+   = help: consider using `Checks for`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
index 03556823a8f..5ca183d41a9 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
@@ -1,5 +1,5 @@
 error: use of a disallowed method `rustc_lint::context::LintContext::span_lint`
-  --> $DIR/disallow_struct_span_lint.rs:14:5
+  --> $DIR/disallow_span_lint.rs:14:5
    |
 LL |     cx.span_lint(lint, span, msg, |_| {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,10 +8,10 @@ LL |     cx.span_lint(lint, span, msg, |_| {});
    = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
 
 error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
-  --> $DIR/disallow_struct_span_lint.rs:24:5
+  --> $DIR/disallow_span_lint.rs:24:5
    |
 LL |     tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/pub_underscore_fields/exported/clippy.toml b/src/tools/clippy/tests/ui-toml/pub_underscore_fields/exported/clippy.toml
index 94a0d3554bc..9e472bd14ba 100644
--- a/src/tools/clippy/tests/ui-toml/pub_underscore_fields/exported/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/pub_underscore_fields/exported/clippy.toml
@@ -1 +1 @@
-pub-underscore-fields-behavior = "PublicallyExported"
\ No newline at end of file
+pub-underscore-fields-behavior = "PubliclyExported"
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_unknown_key/clippy.toml
index b77b4580051..2b63f6e5c26 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/clippy.toml
@@ -3,6 +3,9 @@ foobar = 42
 # so is this one
 barfoo = 53
 
+# when using underscores instead of dashes, suggest the correct one
+allow_mixed_uninlined_format_args = true
+
 # that one is ignored
 [third-party]
 clippy-feature = "nightly"
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs
index 38009627757..49139b60a9f 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs
@@ -1,3 +1,4 @@
+//@no-rustfix
 //@error-in-other-file: unknown field `foobar`, expected one of
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index ed4fb84df1a..fc683e514ba 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-private-module-inception
            allow-unwrap-in-tests
            allowed-dotfiles
+           allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -87,6 +88,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-private-module-inception
            allow-unwrap-in-tests
            allowed-dotfiles
+           allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -150,5 +152,82 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
 LL | barfoo = 53
    | ^^^^^^
 
-error: aborting due to 2 previous errors
+error: error reading Clippy's configuration file: unknown field `allow_mixed_uninlined_format_args`, expected one of
+           absolute-paths-allowed-crates
+           absolute-paths-max-segments
+           accept-comment-above-attributes
+           accept-comment-above-statement
+           allow-dbg-in-tests
+           allow-expect-in-tests
+           allow-mixed-uninlined-format-args
+           allow-one-hash-in-raw-strings
+           allow-print-in-tests
+           allow-private-module-inception
+           allow-unwrap-in-tests
+           allowed-dotfiles
+           allowed-duplicate-crates
+           allowed-idents-below-min-chars
+           allowed-scripts
+           arithmetic-side-effects-allowed
+           arithmetic-side-effects-allowed-binary
+           arithmetic-side-effects-allowed-unary
+           array-size-threshold
+           avoid-breaking-exported-api
+           await-holding-invalid-types
+           blacklisted-names
+           cargo-ignore-publish
+           check-private-items
+           cognitive-complexity-threshold
+           cyclomatic-complexity-threshold
+           disallowed-macros
+           disallowed-methods
+           disallowed-names
+           disallowed-types
+           doc-valid-idents
+           enable-raw-pointer-heuristic-for-send
+           enforce-iter-loop-reborrow
+           enforced-import-renames
+           enum-variant-name-threshold
+           enum-variant-size-threshold
+           excessive-nesting-threshold
+           future-size-threshold
+           ignore-interior-mutability
+           large-error-threshold
+           literal-representation-threshold
+           matches-for-let-else
+           max-fn-params-bools
+           max-include-file-size
+           max-struct-bools
+           max-suggested-slice-pattern-length
+           max-trait-bounds
+           min-ident-chars-threshold
+           missing-docs-in-crate-items
+           msrv
+           pass-by-value-size-limit
+           pub-underscore-fields-behavior
+           semicolon-inside-block-ignore-singleline
+           semicolon-outside-block-ignore-multiline
+           single-char-binding-names-threshold
+           stack-size-threshold
+           standard-macro-braces
+           struct-field-name-threshold
+           suppress-restriction-lint-in-const
+           third-party
+           too-large-for-stack
+           too-many-arguments-threshold
+           too-many-lines-threshold
+           trivial-copy-size-limit
+           type-complexity-threshold
+           unnecessary-box-size
+           unreadable-literal-lint-fractions
+           upper-case-acronyms-aggressive
+           vec-box-size-threshold
+           verbose-bit-mask-threshold
+           warn-on-all-wildcard-imports
+  --> $DIR/$DIR/clippy.toml:7:1
+   |
+LL | allow_mixed_uninlined_format_args = true
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: perhaps you meant: `allow-mixed-uninlined-format-args`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs
index c5879557516..ac544737099 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs
@@ -11,8 +11,8 @@ use quote::{quote, quote_spanned};
 use syn::spanned::Spanned;
 use syn::token::Star;
 use syn::{
-    parse_macro_input, parse_quote, FnArg, ImplItem, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature,
-    TraitItem, Type,
+    parse_macro_input, parse_quote, FnArg, ImplItem, ItemFn, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType,
+    Signature, TraitItem, Type,
 };
 
 #[proc_macro_attribute]
@@ -95,3 +95,33 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea
 
     TokenStream::from(quote!(#item))
 }
+
+#[proc_macro_attribute]
+pub fn fake_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    let mut item = parse_macro_input!(item as ItemFn);
+    let span = item.block.brace_token.span;
+
+    if item.sig.asyncness.is_some() {
+        item.sig.asyncness = None;
+    }
+
+    let crate_name = quote! { fake_crate };
+    let block = item.block;
+    item.block = syn::parse_quote_spanned! {
+        span =>
+        {
+            #crate_name::block_on(async {
+                #block
+            })
+        }
+    };
+
+    quote! {
+        mod #crate_name {
+            pub fn block_on<F: ::std::future::Future>(_fut: F) {}
+        }
+
+        #item
+    }
+    .into()
+}
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
index 2ab441bbd0c..efef60567a9 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
@@ -85,4 +85,18 @@ fn block_in_match_expr(num: i32) -> i32 {
     }
 }
 
+// issue #12162
+macro_rules! timed {
+    ($name:expr, $body:expr $(,)?) => {{
+        let __scope = ();
+        $body
+    }};
+}
+
+fn issue_12162() {
+    if timed!("check this!", false) {
+        println!();
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
index dd5ae4fb486..8bd8a939eb1 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
@@ -85,4 +85,18 @@ fn block_in_match_expr(num: i32) -> i32 {
     }
 }
 
+// issue #12162
+macro_rules! timed {
+    ($name:expr, $body:expr $(,)?) => {{
+        let __scope = ();
+        $body
+    }};
+}
+
+fn issue_12162() {
+    if timed!("check this!", false) {
+        println!();
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs
index 44f8b2eabce..9af81f6f7cd 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.rs
@@ -9,17 +9,16 @@ fn simple_examples() {
 
     // Simple
     if true {
-        //~^ ERROR: all if blocks contain the same code at the start
         println!("Hello World!");
         println!("I'm branch nr: 1");
     } else {
         println!("Hello World!");
         println!("I'm branch nr: 2");
     }
+    //~^^^^^^^ ERROR: all if blocks contain the same code at the start
 
     // Else if
     if x == 0 {
-        //~^ ERROR: all if blocks contain the same code at the start
         let y = 9;
         println!("The value y was set to: `{}`", y);
         let _z = y;
@@ -38,6 +37,7 @@ fn simple_examples() {
 
         println!("Ha, Pascal allows you to start the array where you want")
     }
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: all if blocks contain the same code at the start
 
     // Return a value
     let _ = if x == 7 {
@@ -60,7 +60,6 @@ fn simple_but_suggestion_is_invalid() {
     // Can't be automatically moved because used_value_name is getting used again
     let used_value_name = 19;
     if x == 10 {
-        //~^ ERROR: all if blocks contain the same code at the start
         let used_value_name = "Different type";
         println!("Str: {}", used_value_name);
         let _ = 1;
@@ -69,6 +68,7 @@ fn simple_but_suggestion_is_invalid() {
         println!("Str: {}", used_value_name);
         let _ = 2;
     }
+    //~^^^^^^^^^ ERROR: all if blocks contain the same code at the start
     let _ = used_value_name;
 
     // This can be automatically moved as `can_be_overridden` is not used again
@@ -101,11 +101,11 @@ fn check_if_same_than_else_mask() {
     }
 
     if x == 2019 {
-        //~^ ERROR: this `if` has identical blocks
         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
     } else {
         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 }
 
 #[allow(clippy::vec_init_then_push)]
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 9d4d42fb689..317d1577226 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
@@ -2,7 +2,6 @@ error: all if blocks contain the same code at the start
   --> $DIR/shared_at_top.rs:11:5
    |
 LL | /     if true {
-LL | |
 LL | |         println!("Hello World!");
    | |_________________________________^
    |
@@ -21,7 +20,6 @@ error: all if blocks contain the same code at the start
   --> $DIR/shared_at_top.rs:21:5
    |
 LL | /     if x == 0 {
-LL | |
 LL | |         let y = 9;
 LL | |         println!("The value y was set to: `{}`", y);
 LL | |         let _z = y;
@@ -54,7 +52,6 @@ error: all if blocks contain the same code at the start
   --> $DIR/shared_at_top.rs:62:5
    |
 LL | /     if x == 10 {
-LL | |
 LL | |         let used_value_name = "Different type";
 LL | |         println!("Str: {}", used_value_name);
    | |_____________________________________________^
@@ -105,13 +102,12 @@ error: this `if` has identical blocks
    |
 LL |       if x == 2019 {
    |  __________________^
-LL | |
 LL | |         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/shared_at_top.rs:106:12
+  --> $DIR/shared_at_top.rs:105:12
    |
 LL |       } else {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs
index 2aeacb89c0c..b63819d7c39 100644
--- a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs
+++ b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.rs
@@ -107,9 +107,9 @@ fn valid_examples() {
 
     // Let's test empty blocks
     if false {
-        //~^ ERROR: this `if` has identical blocks
     } else {
     }
+    //~^^^ ERROR: this `if` has identical blocks
 }
 
 /// This makes sure that the `if_same_then_else` masks the `shared_code_in_if_blocks` lint
@@ -119,7 +119,6 @@ fn trigger_other_lint() {
 
     // Same block
     if x == 0 {
-        //~^ ERROR: this `if` has identical blocks
         let u = 19;
         println!("How are u today?");
         let _ = "This is a string";
@@ -128,6 +127,7 @@ fn trigger_other_lint() {
         println!("How are u today?");
         let _ = "This is a string";
     }
+    //~^^^^^^^^^ ERROR: this `if` has identical blocks
 
     // Only same expression
     let _ = if x == 6 { 7 } else { 7 };
@@ -138,28 +138,24 @@ fn trigger_other_lint() {
         println!("Well I'm the most important block");
         "I'm a pretty string"
     } else if x == 68 {
-        //~^ ERROR: this `if` has identical blocks
         println!("I'm a doppelgänger");
-        // Don't listen to my clone below
 
         if y == 90 { "=^.^=" } else { ":D" }
     } else {
-        // Don't listen to my clone above
         println!("I'm a doppelgänger");
 
         if y == 90 { "=^.^=" } else { ":D" }
     };
+    //~^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if x == 0 {
         println!("I'm single");
     } else if x == 68 {
-        //~^ ERROR: this `if` has identical blocks
         println!("I'm a doppelgänger");
-        // Don't listen to my clone below
     } else {
-        // Don't listen to my clone above
         println!("I'm a doppelgänger");
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 }
 
 fn main() {}
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 fcbf12235aa..0daf2ff6967 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
@@ -3,12 +3,11 @@ error: this `if` has identical blocks
    |
 LL |       if false {
    |  ______________^
-LL | |
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:111:12
+  --> $DIR/valid_if_blocks.rs:110:12
    |
 LL |       } else {
    |  ____________^
@@ -25,7 +24,6 @@ error: this `if` has identical blocks
    |
 LL |       if x == 0 {
    |  _______________^
-LL | |
 LL | |         let u = 19;
 LL | |         println!("How are u today?");
 LL | |         let _ = "This is a string";
@@ -33,7 +31,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:126:12
+  --> $DIR/valid_if_blocks.rs:125:12
    |
 LL |       } else {
    |  ____________^
@@ -60,20 +58,17 @@ error: this `if` has identical blocks
    |
 LL |       } else if x == 68 {
    |  _______________________^
-LL | |
 LL | |         println!("I'm a doppelgänger");
-LL | |         // Don't listen to my clone below
 LL | |
 LL | |         if y == 90 { "=^.^=" } else { ":D" }
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:146:12
+  --> $DIR/valid_if_blocks.rs:144:12
    |
 LL |       } else {
    |  ____________^
-LL | |         // Don't listen to my clone above
 LL | |         println!("I'm a doppelgänger");
 LL | |
 LL | |         if y == 90 { "=^.^=" } else { ":D" }
@@ -81,22 +76,19 @@ LL | |     };
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/valid_if_blocks.rs:155:23
+  --> $DIR/valid_if_blocks.rs:153:23
    |
 LL |       } else if x == 68 {
    |  _______________________^
-LL | |
 LL | |         println!("I'm a doppelgänger");
-LL | |         // Don't listen to my clone below
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:159:12
+  --> $DIR/valid_if_blocks.rs:155:12
    |
 LL |       } else {
    |  ____________^
-LL | |         // Don't listen to my clone above
 LL | |         println!("I'm a doppelgänger");
 LL | |     }
    | |_____^
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr
index 00b65f00d78..67589d1a8ab 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-9041.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-9041.stderr
@@ -2,7 +2,7 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/ice-9041.rs:5:19
    |
 LL |     things.iter().find(|p| is_thing_ready(p)).is_some()
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|p| is_thing_ready(&p))`
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|p| is_thing_ready(&p))`
    |
    = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.fixed b/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.fixed
new file mode 100644
index 00000000000..7300bd9bd2a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.fixed
@@ -0,0 +1,28 @@
+#![warn(clippy::default_instead_of_iter_empty)]
+#![allow(dead_code)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[derive(Default)]
+struct Iter {
+    iter: core::iter::Empty<usize>,
+}
+
+fn main() {
+    // Do lint.
+    let _ = core::iter::empty::<usize>();
+    let _foo: core::iter::Empty<usize> = core::iter::empty();
+
+    // Do not lint.
+    let _ = Iter::default();
+}
diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.rs b/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.rs
new file mode 100644
index 00000000000..0bc5c7169d1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.rs
@@ -0,0 +1,28 @@
+#![warn(clippy::default_instead_of_iter_empty)]
+#![allow(dead_code)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[derive(Default)]
+struct Iter {
+    iter: core::iter::Empty<usize>,
+}
+
+fn main() {
+    // Do lint.
+    let _ = core::iter::Empty::<usize>::default();
+    let _foo: core::iter::Empty<usize> = core::iter::Empty::default();
+
+    // Do not lint.
+    let _ = Iter::default();
+}
diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.stderr b/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.stderr
new file mode 100644
index 00000000000..747a31ecbf3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty_no_std.stderr
@@ -0,0 +1,17 @@
+error: `core::iter::empty()` is the more idiomatic way
+  --> $DIR/default_instead_of_iter_empty_no_std.rs:23:13
+   |
+LL |     let _ = core::iter::Empty::<usize>::default();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty::<usize>()`
+   |
+   = note: `-D clippy::default-instead-of-iter-empty` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]`
+
+error: `core::iter::empty()` is the more idiomatic way
+  --> $DIR/default_instead_of_iter_empty_no_std.rs:24:42
+   |
+LL |     let _foo: core::iter::Empty<usize> = core::iter::Empty::default();
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty()`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
index c364c683057..e7038082c08 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
@@ -216,4 +216,44 @@ mod type_already_inferred {
     }
 }
 
+mod issue12159 {
+    #![allow(non_upper_case_globals, clippy::exhaustive_structs)]
+    pub struct Foo;
+
+    static F: i32 = 1;
+    impl Foo {
+        const LIFE_u8: u8 = 42;
+        const LIFE_i8: i8 = 42;
+        const LIFE_u16: u16 = 42;
+        const LIFE_i16: i16 = 42;
+        const LIFE_u32: u32 = 42;
+        const LIFE_i32: i32 = 42;
+        const LIFE_u64: u64 = 42;
+        const LIFE_i64: i64 = 42;
+        const LIFE_u128: u128 = 42;
+        const LIFE_i128: i128 = 42;
+        const LIFE_usize: usize = 42;
+        const LIFE_isize: isize = 42;
+        const LIFE_f32: f32 = 42.;
+        const LIFE_f64: f64 = 42.;
+
+        const fn consts() {
+            const LIFE_u8: u8 = 42;
+            const LIFE_i8: i8 = 42;
+            const LIFE_u16: u16 = 42;
+            const LIFE_i16: i16 = 42;
+            const LIFE_u32: u32 = 42;
+            const LIFE_i32: i32 = 42;
+            const LIFE_u64: u64 = 42;
+            const LIFE_i64: i64 = 42;
+            const LIFE_u128: u128 = 42;
+            const LIFE_i128: i128 = 42;
+            const LIFE_usize: usize = 42;
+            const LIFE_isize: isize = 42;
+            const LIFE_f32: f32 = 42.;
+            const LIFE_f64: f64 = 42.;
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
index ffa7b961d1c..d8eeda70491 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
@@ -216,4 +216,44 @@ mod type_already_inferred {
     }
 }
 
+mod issue12159 {
+    #![allow(non_upper_case_globals, clippy::exhaustive_structs)]
+    pub struct Foo;
+
+    static F: i32 = 1;
+    impl Foo {
+        const LIFE_u8: u8 = 42;
+        const LIFE_i8: i8 = 42;
+        const LIFE_u16: u16 = 42;
+        const LIFE_i16: i16 = 42;
+        const LIFE_u32: u32 = 42;
+        const LIFE_i32: i32 = 42;
+        const LIFE_u64: u64 = 42;
+        const LIFE_i64: i64 = 42;
+        const LIFE_u128: u128 = 42;
+        const LIFE_i128: i128 = 42;
+        const LIFE_usize: usize = 42;
+        const LIFE_isize: isize = 42;
+        const LIFE_f32: f32 = 42.;
+        const LIFE_f64: f64 = 42.;
+
+        const fn consts() {
+            const LIFE_u8: u8 = 42;
+            const LIFE_i8: i8 = 42;
+            const LIFE_u16: u16 = 42;
+            const LIFE_i16: i16 = 42;
+            const LIFE_u32: u32 = 42;
+            const LIFE_i32: i32 = 42;
+            const LIFE_u64: u64 = 42;
+            const LIFE_i64: i64 = 42;
+            const LIFE_u128: u128 = 42;
+            const LIFE_i128: i128 = 42;
+            const LIFE_usize: usize = 42;
+            const LIFE_isize: isize = 42;
+            const LIFE_f32: f32 = 42.;
+            const LIFE_f64: f64 = 42.;
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
index a7f5d3ec7cd..aa7a95405e0 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
@@ -121,4 +121,36 @@ pub fn _from_mod() -> _hidden::InPubFn {
 #[derive(PartialEq)]
 struct InternalTy;
 
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub struct MissingEqNonExhaustive {
+    foo: u32,
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub struct MissingEqNonExhaustive1 {
+    foo: u32,
+    #[non_exhaustive]
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub enum MissingEqNonExhaustive2 {
+    Foo,
+    Bar,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub enum MissingEqNonExhaustive3 {
+    Foo,
+    #[non_exhaustive]
+    Bar,
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
index 476d2aee23a..90ac7a7989e 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
@@ -121,4 +121,36 @@ pub fn _from_mod() -> _hidden::InPubFn {
 #[derive(PartialEq)]
 struct InternalTy;
 
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub struct MissingEqNonExhaustive {
+    foo: u32,
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub struct MissingEqNonExhaustive1 {
+    foo: u32,
+    #[non_exhaustive]
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub enum MissingEqNonExhaustive2 {
+    Foo,
+    Bar,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub enum MissingEqNonExhaustive3 {
+    Foo,
+    #[non_exhaustive]
+    Bar,
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index bff46e55722..16f7bafd44b 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -64,7 +64,7 @@ fn test_units() {
 /// NaN NaNs
 /// OAuth GraphQL
 /// OCaml
-/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
+/// OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
 /// WebGL WebGL2 WebGPU
 /// TensorFlow
 /// TrueType
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 4e162a97dee..4058b2bad74 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -64,7 +64,7 @@ fn test_units() {
 /// NaN NaNs
 /// OAuth GraphQL
 /// OCaml
-/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
+/// OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
 /// WebGL WebGL2 WebGPU
 /// TensorFlow
 /// TrueType
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index 18d285693e6..4a68505ee0b 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -89,4 +89,12 @@ fn msrv_1_41() {
     }
 }
 
+fn issue_12138() {
+    struct Hello;
+
+    impl From<Hello> for () {
+        fn from(val: Hello) {}
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index 779ef709e92..bf3ed0c2b64 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -89,4 +89,12 @@ fn msrv_1_41() {
     }
 }
 
+fn issue_12138() {
+    struct Hello;
+
+    impl Into<()> for Hello {
+        fn into(self) {}
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index 784843ce5fd..f1370ed844f 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -86,5 +86,19 @@ LL ~         fn from(val: Vec<T>) -> Self {
 LL ~             FromOverInto(val)
    |
 
-error: aborting due to 6 previous errors
+error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
+  --> $DIR/from_over_into.rs:95:5
+   |
+LL |     impl Into<()> for Hello {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see
+           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence
+help: replace the `Into` implementation with `From<issue_12138::Hello>`
+   |
+LL ~     impl From<Hello> for () {
+LL ~         fn from(val: Hello) {}
+   |
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/if_same_then_else.rs b/src/tools/clippy/tests/ui/if_same_then_else.rs
index e84b20e9fef..d53e1383d84 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else.rs
@@ -21,7 +21,6 @@ fn foo() -> bool {
 
 fn if_same_then_else() {
     if true {
-        //~^ ERROR: this `if` has identical blocks
         Foo { bar: 42 };
         0..10;
         ..;
@@ -38,6 +37,7 @@ fn if_same_then_else() {
         0..=10;
         foo();
     }
+    //~^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         Foo { bar: 42 };
@@ -64,19 +64,11 @@ fn if_same_then_else() {
         foo();
     }
 
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        0.0
-    } else {
-        0.0
-    };
+    let _ = if true { 0.0 } else { 0.0 };
+    //~^ ERROR: this `if` has identical blocks
 
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        -0.0
-    } else {
-        -0.0
-    };
+    let _ = if true { -0.0 } else { -0.0 };
+    //~^ ERROR: this `if` has identical blocks
 
     let _ = if true { 0.0 } else { -0.0 };
 
@@ -87,15 +79,10 @@ fn if_same_then_else() {
         foo();
     }
 
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        42
-    } else {
-        42
-    };
+    let _ = if true { 42 } else { 42 };
+    //~^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         let bar = if true { 42 } else { 43 };
 
         while foo() {
@@ -110,6 +97,7 @@ fn if_same_then_else() {
         }
         bar + 1;
     }
+    //~^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         let _ = match 42 {
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 fb33e94e6c3..281f30f88b4 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else.stderr
@@ -3,16 +3,16 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         Foo { bar: 42 };
 LL | |         0..10;
+LL | |         ..;
 ...  |
 LL | |         foo();
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:32:12
+  --> $DIR/if_same_then_else.rs:31:12
    |
 LL |       } else {
    |  ____________^
@@ -29,75 +29,54 @@ LL | |     }
 error: this `if` has identical blocks
   --> $DIR/if_same_then_else.rs:67:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         0.0
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { 0.0 } else { 0.0 };
+   |                     ^^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:70:12
+  --> $DIR/if_same_then_else.rs:67:34
    |
-LL |       } else {
-   |  ____________^
-LL | |         0.0
-LL | |     };
-   | |_____^
+LL |     let _ = if true { 0.0 } else { 0.0 };
+   |                                  ^^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:74:21
+  --> $DIR/if_same_then_else.rs:70:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         -0.0
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { -0.0 } else { -0.0 };
+   |                     ^^^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:77:12
+  --> $DIR/if_same_then_else.rs:70:35
    |
-LL |       } else {
-   |  ____________^
-LL | |         -0.0
-LL | |     };
-   | |_____^
+LL |     let _ = if true { -0.0 } else { -0.0 };
+   |                                   ^^^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:90:21
+  --> $DIR/if_same_then_else.rs:82:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         42
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { 42 } else { 42 };
+   |                     ^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:93:12
+  --> $DIR/if_same_then_else.rs:82:33
    |
-LL |       } else {
-   |  ____________^
-LL | |         42
-LL | |     };
-   | |_____^
+LL |     let _ = if true { 42 } else { 42 };
+   |                                 ^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:97:13
+  --> $DIR/if_same_then_else.rs:85:13
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         let bar = if true { 42 } else { 43 };
 LL | |
+LL | |         while foo() {
 ...  |
 LL | |         bar + 1;
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:105:12
+  --> $DIR/if_same_then_else.rs:92:12
    |
 LL |       } else {
    |  ____________^
@@ -110,7 +89,7 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:250:14
+  --> $DIR/if_same_then_else.rs:238:14
    |
 LL |           if x {
    |  ______________^
@@ -119,7 +98,7 @@ LL | |         } else {
    | |_________^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:252:16
+  --> $DIR/if_same_then_else.rs:240:16
    |
 LL |           } else {
    |  ________________^
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs
index 0b171f21d0c..e23c77b0827 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs
@@ -13,7 +13,6 @@
 
 fn if_same_then_else2() -> Result<&'static str, ()> {
     if true {
-        //~^ ERROR: this `if` has identical blocks
         for _ in &[42] {
             let foo: &Option<_> = &Some::<u8>(42);
             if foo.is_some() {
@@ -32,20 +31,21 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
             }
         }
     }
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         if let Some(a) = Some(42) {}
     } else {
         if let Some(a) = Some(42) {}
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         if let (1, .., 3) = (1, 2, 3) {}
     } else {
         if let (1, .., 3) = (1, 2, 3) {}
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         if let (1, .., 3) = (1, 2, 3) {}
@@ -90,19 +90,15 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
     }
 
     // Same NaNs
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        f32::NAN
-    } else {
-        f32::NAN
-    };
+    let _ = if true { f32::NAN } else { f32::NAN };
+    //~^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         Ok("foo")?;
     } else {
         Ok("foo")?;
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         let foo = "";
@@ -122,13 +118,13 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
         let foo = "bar";
         return Ok(&foo[0..]);
     } else if true {
-        //~^ ERROR: this `if` has identical blocks
         let foo = "";
         return Ok(&foo[0..]);
     } else {
         let foo = "";
         return Ok(&foo[0..]);
     }
+    //~^^^^^^^ ERROR: this `if` has identical blocks
 
     // False positive `if_same_then_else`: `let (x, y)` vs. `let (y, x)`; see issue #3559.
     if true {
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 fe68ef2711b..4e7a7c87dc5 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
@@ -3,16 +3,16 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         for _ in &[42] {
 LL | |             let foo: &Option<_> = &Some::<u8>(42);
+LL | |             if foo.is_some() {
 ...  |
 LL | |         }
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:25:12
+  --> $DIR/if_same_then_else2.rs:24:12
    |
 LL |       } else {
    |  ____________^
@@ -31,13 +31,12 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         if let Some(a) = Some(42) {}
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:39:12
+  --> $DIR/if_same_then_else2.rs:38:12
    |
 LL |       } else {
    |  ____________^
@@ -50,13 +49,12 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         if let (1, .., 3) = (1, 2, 3) {}
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:46:12
+  --> $DIR/if_same_then_else2.rs:45:12
    |
 LL |       } else {
    |  ____________^
@@ -67,34 +65,26 @@ LL | |     }
 error: this `if` has identical blocks
   --> $DIR/if_same_then_else2.rs:93:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         f32::NAN
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { f32::NAN } else { f32::NAN };
+   |                     ^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:96:12
+  --> $DIR/if_same_then_else2.rs:93:39
    |
-LL |       } else {
-   |  ____________^
-LL | |         f32::NAN
-LL | |     };
-   | |_____^
+LL |     let _ = if true { f32::NAN } else { f32::NAN };
+   |                                       ^^^^^^^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:100:13
+  --> $DIR/if_same_then_else2.rs:96:13
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         Ok("foo")?;
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:103:12
+  --> $DIR/if_same_then_else2.rs:98:12
    |
 LL |       } else {
    |  ____________^
@@ -103,18 +93,17 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:124:20
+  --> $DIR/if_same_then_else2.rs:120:20
    |
 LL |       } else if true {
    |  ____________________^
-LL | |
 LL | |         let foo = "";
 LL | |         return Ok(&foo[0..]);
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:128:12
+  --> $DIR/if_same_then_else2.rs:123:12
    |
 LL |       } else {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.fixed b/src/tools/clippy/tests/ui/ineffective_open_options.fixed
index 3af8f3c5aaa..88489dc46bb 100644
--- a/src/tools/clippy/tests/ui/ineffective_open_options.fixed
+++ b/src/tools/clippy/tests/ui/ineffective_open_options.fixed
@@ -26,16 +26,23 @@ fn main() {
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(true)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(false)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap();
-    let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .truncate(true)
+        .write(true)
+        .open("dump.json")
+        .unwrap();
 }
diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.rs b/src/tools/clippy/tests/ui/ineffective_open_options.rs
index 4eaf6293c40..db8bca3e2ac 100644
--- a/src/tools/clippy/tests/ui/ineffective_open_options.rs
+++ b/src/tools/clippy/tests/ui/ineffective_open_options.rs
@@ -26,16 +26,23 @@ fn main() {
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(true)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(false)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap();
-    let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .truncate(true)
+        .write(true)
+        .open("dump.json")
+        .unwrap();
 }
diff --git a/src/tools/clippy/tests/ui/join_absolute_paths.stderr b/src/tools/clippy/tests/ui/join_absolute_paths.stderr
index 0c2f89d9978..ab4d189ca3a 100644
--- a/src/tools/clippy/tests/ui/join_absolute_paths.stderr
+++ b/src/tools/clippy/tests/ui/join_absolute_paths.stderr
@@ -11,7 +11,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join("sh");
    |               ~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from("/sh");
    |     ~~~~~~~~~~~~~~~~~~~~
@@ -27,7 +27,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join("\user");
    |               ~~~~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from("\\user");
    |     ~~~~~~~~~~~~~~~~~~~~~~~
@@ -43,7 +43,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join("sh");
    |               ~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from("/sh");
    |     ~~~~~~~~~~~~~~~~~~~~
@@ -59,7 +59,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join(r#"sh"#);
    |               ~~~~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from(r#"/sh"#);
    |     ~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.stderr b/src/tools/clippy/tests/ui/manual_ok_or.stderr
index b277d22e59b..89df6cdbedb 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.stderr
+++ b/src/tools/clippy/tests/ui/manual_ok_or.stderr
@@ -17,7 +17,7 @@ error: called `map_or(Err(_), Ok)` on an `Option` value
   --> $DIR/manual_ok_or.rs:14:5
    |
 LL |     foo.map_or(Err("error"), Ok);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok_or` instead: `foo.ok_or("error")`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `foo.ok_or("error")`
    |
    = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]`
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr
index dc36a5ee7c6..3ce108b1ca8 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.stderr
@@ -2,7 +2,7 @@ error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:6:13
    |
 LL |     let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`
    |
    = note: `-D clippy::manual-saturating-arithmetic` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]`
@@ -11,13 +11,13 @@ error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:7:13
    |
 LL |     let _ = 1u32.checked_add(1).unwrap_or(u32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:8:13
    |
 LL |     let _ = 1u8.checked_add(1).unwrap_or(255);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u8.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u8.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:9:13
@@ -26,49 +26,49 @@ LL |       let _ = 1u128
    |  _____________^
 LL | |         .checked_add(1)
 LL | |         .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455);
-   | |_______________________________________________________________________^ help: try using `saturating_add`: `1u128.saturating_add(1)`
+   | |_______________________________________________________________________^ help: consider using `saturating_add`: `1u128.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:14:13
    |
 LL |     let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_mul`: `1u32.saturating_mul(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_mul`: `1u32.saturating_mul(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:16:13
    |
 LL |     let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:17:13
    |
 LL |     let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:18:13
    |
 LL |     let _ = 1u8.checked_sub(1).unwrap_or(0);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u8.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u8.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:22:13
    |
 LL |     let _ = 1i32.checked_add(1).unwrap_or(i32::max_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:23:13
    |
 LL |     let _ = 1i32.checked_add(1).unwrap_or(i32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:24:13
    |
 LL |     let _ = 1i8.checked_add(1).unwrap_or(127);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i8.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:25:13
@@ -77,25 +77,25 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_add(1)
 LL | |         .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);
-   | |_______________________________________________________________________^ help: try using `saturating_add`: `1i128.saturating_add(1)`
+   | |_______________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:28:13
    |
 LL |     let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:29:13
    |
 LL |     let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:30:13
    |
 LL |     let _ = 1i8.checked_add(-1).unwrap_or(-128);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i8.saturating_add(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:31:13
@@ -104,25 +104,25 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_add(-1)
 LL | |         .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
-   | |________________________________________________________________________^ help: try using `saturating_add`: `1i128.saturating_add(-1)`
+   | |________________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:38:13
    |
 LL |     let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:39:13
    |
 LL |     let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:40:13
    |
 LL |     let _ = 1i8.checked_sub(1).unwrap_or(-128);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i8.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:41:13
@@ -131,25 +131,25 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_sub(1)
 LL | |         .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
-   | |________________________________________________________________________^ help: try using `saturating_sub`: `1i128.saturating_sub(1)`
+   | |________________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:44:13
    |
 LL |     let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:45:13
    |
 LL |     let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:46:13
    |
 LL |     let _ = 1i8.checked_sub(-1).unwrap_or(127);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i8.saturating_sub(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:47:13
@@ -158,7 +158,7 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_sub(-1)
 LL | |         .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);
-   | |_______________________________________________________________________^ help: try using `saturating_sub`: `1i128.saturating_sub(-1)`
+   | |_______________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(-1)`
 
 error: aborting due to 24 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_clone.fixed b/src/tools/clippy/tests/ui/map_clone.fixed
index 08b155a1aea..395eea69294 100644
--- a/src/tools/clippy/tests/ui/map_clone.fixed
+++ b/src/tools/clippy/tests/ui/map_clone.fixed
@@ -69,15 +69,48 @@ fn main() {
     //~^ ERROR: you are explicitly cloning with `.map()`
     let y = x.cloned();
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
     let y = x.cloned();
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Option<u32> = Some(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Option<u32> = Some(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // Testing with `Result` now.
     let x: Result<String, ()> = Ok(String::new());
     let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
     let y = x.cloned();
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
     let y = x.cloned();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Result<u32, ()> = Ok(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Result<u32, ()> = Ok(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // We ensure that no warning is emitted here because `useless_asref` is taking over.
     let x = Some(String::new());
diff --git a/src/tools/clippy/tests/ui/map_clone.rs b/src/tools/clippy/tests/ui/map_clone.rs
index 901d9b278b4..82a103edf5a 100644
--- a/src/tools/clippy/tests/ui/map_clone.rs
+++ b/src/tools/clippy/tests/ui/map_clone.rs
@@ -69,15 +69,48 @@ fn main() {
     //~^ ERROR: you are explicitly cloning with `.map()`
     let y = x.map(Clone::clone);
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
     let y = x.map(String::clone);
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Option<u32> = Some(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.map(|x| u32::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.map(|x| Clone::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Option<u32> = Some(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // Testing with `Result` now.
     let x: Result<String, ()> = Ok(String::new());
     let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
     let y = x.map(|x| String::clone(x));
     //~^ ERROR: you are explicitly cloning with `.map()`
-    let y = x.map(|x| String::clone(x));
+    //~| HELP: consider calling the dedicated `cloned` method
+    let y = x.map(|x| Clone::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Result<u32, ()> = Ok(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.map(|x| u32::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.map(|x| Clone::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Result<u32, ()> = Ok(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // We ensure that no warning is emitted here because `useless_asref` is taking over.
     let x = Some(String::new());
diff --git a/src/tools/clippy/tests/ui/map_clone.stderr b/src/tools/clippy/tests/ui/map_clone.stderr
index 9d7e9317b58..2c86a67fab8 100644
--- a/src/tools/clippy/tests/ui/map_clone.stderr
+++ b/src/tools/clippy/tests/ui/map_clone.stderr
@@ -50,22 +50,46 @@ LL |     let y = x.map(Clone::clone);
    |             ^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
 
 error: you are explicitly cloning with `.map()`
-  --> $DIR/map_clone.rs:72:13
+  --> $DIR/map_clone.rs:73:13
    |
 LL |     let y = x.map(String::clone);
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
 
 error: you are explicitly cloning with `.map()`
-  --> $DIR/map_clone.rs:78:13
+  --> $DIR/map_clone.rs:79:13
    |
-LL |     let y = x.map(|x| String::clone(x));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
+LL |     let y = x.map(|x| u32::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
 
 error: you are explicitly cloning with `.map()`
-  --> $DIR/map_clone.rs:80:13
+  --> $DIR/map_clone.rs:82:13
+   |
+LL |     let y = x.map(|x| Clone::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
+
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:94:13
    |
 LL |     let y = x.map(|x| String::clone(x));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
 
-error: aborting due to 11 previous errors
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:97:13
+   |
+LL |     let y = x.map(|x| Clone::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
+
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:103:13
+   |
+LL |     let y = x.map(|x| u32::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
+
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:106:13
+   |
+LL |     let y = x.map(|x| Clone::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
+
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.rs b/src/tools/clippy/tests/ui/match_same_arms2.rs
index 525a355f403..3428ff45906 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.rs
+++ b/src/tools/clippy/tests/ui/match_same_arms2.rs
@@ -13,7 +13,6 @@ fn foo() -> bool {
 fn match_same_arms() {
     let _ = match 42 {
         42 => {
-            //~^ ERROR: this match arm has an identical body to the `_` wildcard arm
             foo();
             let mut a = 42 + [23].len() as i32;
             if true {
@@ -32,6 +31,7 @@ fn match_same_arms() {
             a
         },
     };
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm
 
     let _ = match 42 {
         42 => foo(),
@@ -146,13 +146,13 @@ fn match_same_arms() {
             empty!(0);
         },
         1 => {
-            //~^ ERROR: this match arm has an identical body to another arm
             empty!(0);
         },
         x => {
             empty!(x);
         },
     }
+    //~^^^^^^^ ERROR: this match arm has an identical body to another arm
 
     match_expr_like_matches_macro_priority();
 }
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.stderr b/src/tools/clippy/tests/ui/match_same_arms2.stderr
index 40b20c7e16d..512ca7413a7 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms2.stderr
@@ -2,9 +2,9 @@ error: this match arm has an identical body to the `_` wildcard arm
   --> $DIR/match_same_arms2.rs:15:9
    |
 LL | /         42 => {
-LL | |
 LL | |             foo();
 LL | |             let mut a = 42 + [23].len() as i32;
+LL | |             if true {
 ...  |
 LL | |             a
 LL | |         },
@@ -12,7 +12,7 @@ LL | |         },
    |
    = help: or try changing either arm body
 note: `_` wildcard arm here
-  --> $DIR/match_same_arms2.rs:25:9
+  --> $DIR/match_same_arms2.rs:24:9
    |
 LL | /         _ => {
 LL | |             foo();
@@ -122,7 +122,6 @@ LL |           1 => {
    |           ^ help: try merging the arm patterns: `1 | 0`
    |  _________|
    | |
-LL | |
 LL | |             empty!(0);
 LL | |         },
    | |_________^
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.fixed b/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
new file mode 100644
index 00000000000..c970f2ba281
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
@@ -0,0 +1,82 @@
+#![allow(unused)]
+#![warn(
+    clippy::all,
+    clippy::style,
+    clippy::mem_replace_option_with_none,
+    clippy::mem_replace_with_default
+)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::mem;
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn replace_option_with_none() {
+    let mut an_option = Some(1);
+    let _ = an_option.take();
+    let an_option = &mut Some(1);
+    let _ = an_option.take();
+}
+
+fn replace_with_default() {
+    let mut refstr = "hello";
+    let _ = core::mem::take(&mut refstr);
+
+    let mut slice: &[i32] = &[1, 2, 3];
+    let _ = core::mem::take(&mut slice);
+}
+
+// lint is disabled for primitives because in this case `take`
+// has no clear benefit over `replace` and sometimes is harder to read
+fn dont_lint_primitive() {
+    let mut pbool = true;
+    let _ = mem::replace(&mut pbool, false);
+
+    let mut pint = 5;
+    let _ = mem::replace(&mut pint, 0);
+}
+
+fn main() {
+    replace_option_with_none();
+    replace_with_default();
+    dont_lint_primitive();
+}
+
+fn issue9824() {
+    struct Foo<'a>(Option<&'a str>);
+    impl<'a> core::ops::Deref for Foo<'a> {
+        type Target = Option<&'a str>;
+
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<'a> core::ops::DerefMut for Foo<'a> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    struct Bar {
+        opt: Option<u8>,
+        val: u8,
+    }
+
+    let mut f = Foo(Some("foo"));
+    let mut b = Bar { opt: Some(1), val: 12 };
+
+    // replace option with none
+    let _ = f.0.take();
+    let _ = (*f).take();
+    let _ = b.opt.take();
+    // replace with default
+    let _ = mem::replace(&mut b.val, u8::default());
+}
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.rs b/src/tools/clippy/tests/ui/mem_replace_no_std.rs
new file mode 100644
index 00000000000..673d5c7b4f4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.rs
@@ -0,0 +1,82 @@
+#![allow(unused)]
+#![warn(
+    clippy::all,
+    clippy::style,
+    clippy::mem_replace_option_with_none,
+    clippy::mem_replace_with_default
+)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::mem;
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn replace_option_with_none() {
+    let mut an_option = Some(1);
+    let _ = mem::replace(&mut an_option, None);
+    let an_option = &mut Some(1);
+    let _ = mem::replace(an_option, None);
+}
+
+fn replace_with_default() {
+    let mut refstr = "hello";
+    let _ = mem::replace(&mut refstr, "");
+
+    let mut slice: &[i32] = &[1, 2, 3];
+    let _ = mem::replace(&mut slice, &[]);
+}
+
+// lint is disabled for primitives because in this case `take`
+// has no clear benefit over `replace` and sometimes is harder to read
+fn dont_lint_primitive() {
+    let mut pbool = true;
+    let _ = mem::replace(&mut pbool, false);
+
+    let mut pint = 5;
+    let _ = mem::replace(&mut pint, 0);
+}
+
+fn main() {
+    replace_option_with_none();
+    replace_with_default();
+    dont_lint_primitive();
+}
+
+fn issue9824() {
+    struct Foo<'a>(Option<&'a str>);
+    impl<'a> core::ops::Deref for Foo<'a> {
+        type Target = Option<&'a str>;
+
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<'a> core::ops::DerefMut for Foo<'a> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    struct Bar {
+        opt: Option<u8>,
+        val: u8,
+    }
+
+    let mut f = Foo(Some("foo"));
+    let mut b = Bar { opt: Some(1), val: 12 };
+
+    // replace option with none
+    let _ = mem::replace(&mut f.0, None);
+    let _ = mem::replace(&mut *f, None);
+    let _ = mem::replace(&mut b.opt, None);
+    // replace with default
+    let _ = mem::replace(&mut b.val, u8::default());
+}
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.stderr b/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
new file mode 100644
index 00000000000..744fb5a1587
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
@@ -0,0 +1,50 @@
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:24:13
+   |
+LL |     let _ = mem::replace(&mut an_option, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
+   |
+   = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:26:13
+   |
+LL |     let _ = mem::replace(an_option, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
+
+error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
+  --> $DIR/mem_replace_no_std.rs:31:13
+   |
+LL |     let _ = mem::replace(&mut refstr, "");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)`
+   |
+   = note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
+
+error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
+  --> $DIR/mem_replace_no_std.rs:34:13
+   |
+LL |     let _ = mem::replace(&mut slice, &[]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:77:13
+   |
+LL |     let _ = mem::replace(&mut f.0, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:78:13
+   |
+LL |     let _ = mem::replace(&mut *f, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:79:13
+   |
+LL |     let _ = mem::replace(&mut b.opt, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs
index 777b1e52c2d..dabeda72f0c 100644
--- a/src/tools/clippy/tests/ui/no_effect.rs
+++ b/src/tools/clippy/tests/ui/no_effect.rs
@@ -181,6 +181,8 @@ fn main() {
     //~^ ERROR: binding to `_` prefixed variable with no side-effect
     let _cat = [2, 4, 6, 8][2];
     //~^ ERROR: binding to `_` prefixed variable with no side-effect
+    let _issue_12166 = 42;
+    let underscore_variable_above_can_be_used_dont_lint = _issue_12166;
 
     #[allow(clippy::no_effect)]
     0;
diff --git a/src/tools/clippy/tests/ui/no_effect.stderr b/src/tools/clippy/tests/ui/no_effect.stderr
index f5ba234b4cb..8140ba1feee 100644
--- a/src/tools/clippy/tests/ui/no_effect.stderr
+++ b/src/tools/clippy/tests/ui/no_effect.stderr
@@ -152,31 +152,31 @@ LL |     FooString { s: s };
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:175:5
+  --> $DIR/no_effect.rs:175:9
    |
 LL |     let _unused = 1;
-   |     ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^
    |
    = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]`
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:178:5
+  --> $DIR/no_effect.rs:178:9
    |
 LL |     let _penguin = || println!("Some helpful closure");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:180:5
+  --> $DIR/no_effect.rs:180:9
    |
 LL |     let _duck = Struct { field: 0 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:182:5
+  --> $DIR/no_effect.rs:182:9
    |
 LL |     let _cat = [2, 4, 6, 8][2];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^
 
 error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/open_options.rs b/src/tools/clippy/tests/ui/open_options.rs
index 0cdc5bf2bb5..4acb3780df4 100644
--- a/src/tools/clippy/tests/ui/open_options.rs
+++ b/src/tools/clippy/tests/ui/open_options.rs
@@ -1,7 +1,18 @@
+#![allow(unused_must_use)]
+#![warn(clippy::nonsensical_open_options)]
+
 use std::fs::OpenOptions;
 
-#[allow(unused_must_use)]
-#[warn(clippy::nonsensical_open_options)]
+trait OpenOptionsExt {
+    fn truncate_write(&mut self, opt: bool) -> &mut Self;
+}
+
+impl OpenOptionsExt for OpenOptions {
+    fn truncate_write(&mut self, opt: bool) -> &mut Self {
+        self.truncate(opt).write(opt)
+    }
+}
+
 fn main() {
     OpenOptions::new().read(true).truncate(true).open("foo.txt");
     //~^ ERROR: file opened with `truncate` and `read`
@@ -11,12 +22,31 @@ fn main() {
 
     OpenOptions::new().read(true).read(false).open("foo.txt");
     //~^ ERROR: the method `read` is called more than once
-    OpenOptions::new().create(true).create(false).open("foo.txt");
-    //~^ ERROR: the method `create` is called more than once
+    OpenOptions::new()
+        .create(true)
+        .truncate(true) // Ensure we don't trigger suspicious open options by having create without truncate
+        .create(false)
+        //~^ ERROR: the method `create` is called more than once
+        .open("foo.txt");
     OpenOptions::new().write(true).write(false).open("foo.txt");
     //~^ ERROR: the method `write` is called more than once
     OpenOptions::new().append(true).append(false).open("foo.txt");
     //~^ ERROR: the method `append` is called more than once
     OpenOptions::new().truncate(true).truncate(false).open("foo.txt");
     //~^ ERROR: the method `truncate` is called more than once
+
+    std::fs::File::options().read(true).read(false).open("foo.txt");
+    //~^ ERROR: the method `read` is called more than once
+
+    let mut options = std::fs::OpenOptions::new();
+    options.read(true);
+    options.read(false);
+    // Possible future improvement: recognize open options method call chains across statements.
+    options.open("foo.txt");
+
+    let mut options = std::fs::OpenOptions::new();
+    options.truncate(true);
+    options.create(true).open("foo.txt");
+
+    OpenOptions::new().create(true).truncate_write(true).open("foo.txt");
 }
diff --git a/src/tools/clippy/tests/ui/open_options.stderr b/src/tools/clippy/tests/ui/open_options.stderr
index 7ac826f52fa..4f84d1d09f9 100644
--- a/src/tools/clippy/tests/ui/open_options.stderr
+++ b/src/tools/clippy/tests/ui/open_options.stderr
@@ -1,5 +1,5 @@
 error: file opened with `truncate` and `read`
-  --> $DIR/open_options.rs:6:5
+  --> $DIR/open_options.rs:17:5
    |
 LL |     OpenOptions::new().read(true).truncate(true).open("foo.txt");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,40 +8,46 @@ LL |     OpenOptions::new().read(true).truncate(true).open("foo.txt");
    = help: to override `-D warnings` add `#[allow(clippy::nonsensical_open_options)]`
 
 error: file opened with `append` and `truncate`
-  --> $DIR/open_options.rs:9:5
+  --> $DIR/open_options.rs:20:5
    |
 LL |     OpenOptions::new().append(true).truncate(true).open("foo.txt");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the method `read` is called more than once
-  --> $DIR/open_options.rs:12:5
+  --> $DIR/open_options.rs:23:35
    |
 LL |     OpenOptions::new().read(true).read(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                   ^^^^^^^^^^^
 
 error: the method `create` is called more than once
-  --> $DIR/open_options.rs:14:5
+  --> $DIR/open_options.rs:28:10
    |
-LL |     OpenOptions::new().create(true).create(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         .create(false)
+   |          ^^^^^^^^^^^^^
 
 error: the method `write` is called more than once
-  --> $DIR/open_options.rs:16:5
+  --> $DIR/open_options.rs:31:36
    |
 LL |     OpenOptions::new().write(true).write(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                    ^^^^^^^^^^^^
 
 error: the method `append` is called more than once
-  --> $DIR/open_options.rs:18:5
+  --> $DIR/open_options.rs:33:37
    |
 LL |     OpenOptions::new().append(true).append(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                     ^^^^^^^^^^^^^
 
 error: the method `truncate` is called more than once
-  --> $DIR/open_options.rs:20:5
+  --> $DIR/open_options.rs:35:39
    |
 LL |     OpenOptions::new().truncate(true).truncate(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                       ^^^^^^^^^^^^^^^
+
+error: the method `read` is called more than once
+  --> $DIR/open_options.rs:38:41
+   |
+LL |     std::fs::File::options().read(true).read(false).open("foo.txt");
+   |                                         ^^^^^^^^^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/open_options_fixable.fixed b/src/tools/clippy/tests/ui/open_options_fixable.fixed
new file mode 100644
index 00000000000..90a129a9bdf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/open_options_fixable.fixed
@@ -0,0 +1,7 @@
+use std::fs::OpenOptions;
+#[allow(unused_must_use)]
+#[warn(clippy::suspicious_open_options)]
+fn main() {
+    OpenOptions::new().create(true).truncate(true).open("foo.txt");
+    //~^ ERROR: file opened with `create`, but `truncate` behavior not defined
+}
diff --git a/src/tools/clippy/tests/ui/open_options_fixable.rs b/src/tools/clippy/tests/ui/open_options_fixable.rs
new file mode 100644
index 00000000000..3a9e522ba15
--- /dev/null
+++ b/src/tools/clippy/tests/ui/open_options_fixable.rs
@@ -0,0 +1,7 @@
+use std::fs::OpenOptions;
+#[allow(unused_must_use)]
+#[warn(clippy::suspicious_open_options)]
+fn main() {
+    OpenOptions::new().create(true).open("foo.txt");
+    //~^ ERROR: file opened with `create`, but `truncate` behavior not defined
+}
diff --git a/src/tools/clippy/tests/ui/open_options_fixable.stderr b/src/tools/clippy/tests/ui/open_options_fixable.stderr
new file mode 100644
index 00000000000..e327661713b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/open_options_fixable.stderr
@@ -0,0 +1,14 @@
+error: file opened with `create`, but `truncate` behavior not defined
+  --> $DIR/open_options_fixable.rs:5:24
+   |
+LL |     OpenOptions::new().create(true).open("foo.txt");
+   |                        ^^^^^^^^^^^^- help: add: `.truncate(true)`
+   |
+   = help: if you intend to overwrite an existing file entirely, call `.truncate(true)`
+   = help: if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`
+   = help: alternatively, use `.append(true)` to append to the file instead of overwriting it
+   = note: `-D clippy::suspicious-open-options` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::suspicious_open_options)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
index 9d173e409ab..036b8c749e4 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
@@ -2,7 +2,7 @@ error: called `.as_ref().map(Deref::deref)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:11:13
    |
 LL |     let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.clone().as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.clone().as_deref()`
    |
    = note: `-D clippy::option-as-ref-deref` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_deref)]`
@@ -15,103 +15,103 @@ LL |       let _ = opt.clone()
 LL | |         .as_ref().map(
 LL | |             Deref::deref
 LL | |         )
-   | |_________^ help: try using as_deref instead: `opt.clone().as_deref()`
+   | |_________^ help: consider using as_deref: `opt.clone().as_deref()`
 
 error: called `.as_mut().map(DerefMut::deref_mut)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:20:13
    |
 LL |     let _ = opt.as_mut().map(DerefMut::deref_mut);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_ref().map(String::as_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:22:13
    |
 LL |     let _ = opt.as_ref().map(String::as_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_ref().map(|x| x.as_str())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:23:13
    |
 LL |     let _ = opt.as_ref().map(|x| x.as_str());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_mut().map(String::as_mut_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:24:13
    |
 LL |     let _ = opt.as_mut().map(String::as_mut_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_mut().map(|x| x.as_mut_str())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:25:13
    |
 LL |     let _ = opt.as_mut().map(|x| x.as_mut_str());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_ref().map(CString::as_c_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:26:13
    |
 LL |     let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(CString::new(vec![]).unwrap()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(CString::new(vec![]).unwrap()).as_deref()`
 
 error: called `.as_ref().map(OsString::as_os_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:27:13
    |
 LL |     let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(OsString::new()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(OsString::new()).as_deref()`
 
 error: called `.as_ref().map(PathBuf::as_path)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:28:13
    |
 LL |     let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(PathBuf::new()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(PathBuf::new()).as_deref()`
 
 error: called `.as_ref().map(Vec::as_slice)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:29:13
    |
 LL |     let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(Vec::<()>::new()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(Vec::<()>::new()).as_deref()`
 
 error: called `.as_mut().map(Vec::as_mut_slice)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:30:13
    |
 LL |     let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `Some(Vec::<()>::new()).as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `Some(Vec::<()>::new()).as_deref_mut()`
 
 error: called `.as_ref().map(|x| x.deref())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:32:13
    |
 LL |     let _ = opt.as_ref().map(|x| x.deref());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_mut().map(|x| x.deref_mut())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:33:13
    |
 LL |     let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.clone().as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.clone().as_deref_mut()`
 
 error: called `.as_ref().map(|x| &**x)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:40:13
    |
 LL |     let _ = opt.as_ref().map(|x| &**x);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_mut().map(|x| &mut **x)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:41:13
    |
 LL |     let _ = opt.as_mut().map(|x| &mut **x);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_ref().map(std::ops::Deref::deref)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:44:13
    |
 LL |     let _ = opt.as_ref().map(std::ops::Deref::deref);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_ref().map(String::as_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:56:13
    |
 LL |     let _ = opt.as_ref().map(String::as_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr b/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr
index a193e3c4c49..381601cb6b3 100644
--- a/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr
+++ b/src/tools/clippy/tests/ui/option_map_or_err_ok.stderr
@@ -2,7 +2,7 @@ error: called `map_or(Err(_), Ok)` on an `Option` value
   --> $DIR/option_map_or_err_ok.rs:5:13
    |
 LL |     let _ = x.map_or(Err("a"), Ok);
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok_or` instead: `x.ok_or("a")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `x.ok_or("a")`
    |
    = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]`
diff --git a/src/tools/clippy/tests/ui/option_map_or_none.stderr b/src/tools/clippy/tests/ui/option_map_or_none.stderr
index f2cfc3f9a28..d58ff83c3da 100644
--- a/src/tools/clippy/tests/ui/option_map_or_none.stderr
+++ b/src/tools/clippy/tests/ui/option_map_or_none.stderr
@@ -2,7 +2,7 @@ error: called `map_or(None, ..)` on an `Option` value
   --> $DIR/option_map_or_none.rs:10:26
    |
 LL |     let _: Option<i32> = opt.map_or(None, |x| Some(x + 1));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `map` instead: `opt.map(|x| x + 1)`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `map`: `opt.map(|x| x + 1)`
    |
    = note: `-D clippy::option-map-or-none` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_map_or_none)]`
@@ -14,13 +14,13 @@ LL |       let _: Option<i32> = opt.map_or(None, |x| {
    |  __________________________^
 LL | |                         Some(x + 1)
 LL | |                        });
-   | |_________________________^ help: try using `map` instead: `opt.map(|x| x + 1)`
+   | |_________________________^ help: consider using `map`: `opt.map(|x| x + 1)`
 
 error: called `map_or(None, ..)` on an `Option` value
   --> $DIR/option_map_or_none.rs:17:26
    |
 LL |     let _: Option<i32> = opt.map_or(None, bar);
-   |                          ^^^^^^^^^^^^^^^^^^^^^ help: try using `and_then` instead: `opt.and_then(bar)`
+   |                          ^^^^^^^^^^^^^^^^^^^^^ help: consider using `and_then`: `opt.and_then(bar)`
 
 error: called `map_or(None, ..)` on an `Option` value
   --> $DIR/option_map_or_none.rs:18:26
@@ -33,7 +33,7 @@ LL | |         Some(offset + height)
 LL | |     });
    | |______^
    |
-help: try using `and_then` instead
+help: consider using `and_then`
    |
 LL ~     let _: Option<i32> = opt.and_then(|x| {
 LL +         let offset = 0;
@@ -46,7 +46,7 @@ error: called `map_or(None, Some)` on a `Result` value
   --> $DIR/option_map_or_none.rs:25:26
    |
 LL |     let _: Option<i32> = r.map_or(None, Some);
-   |                          ^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `r.ok()`
+   |                          ^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `r.ok()`
    |
    = note: `-D clippy::result-map-or-into-option` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed b/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
new file mode 100644
index 00000000000..97c8c394c03
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
@@ -0,0 +1,49 @@
+#![warn(clippy::ptr_eq)]
+#![no_std]
+#![feature(lang_items)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+macro_rules! mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ as usize == $b as *const _ as usize
+    };
+}
+
+macro_rules! another_mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ == $b as *const _
+    };
+}
+
+fn main() {
+    let a = &[1, 2, 3];
+    let b = &[1, 2, 3];
+
+    let _ = core::ptr::eq(a, b);
+    let _ = core::ptr::eq(a, b);
+    let _ = a.as_ptr() == b as *const _;
+    let _ = a.as_ptr() == b.as_ptr();
+
+    // Do not lint
+
+    let _ = mac!(a, b);
+    let _ = another_mac!(a, b);
+
+    let a = &mut [1, 2, 3];
+    let b = &mut [1, 2, 3];
+
+    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    let _ = a.as_mut_ptr() == b.as_mut_ptr();
+
+    let _ = a == b;
+    let _ = core::ptr::eq(a, b);
+}
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.rs b/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
new file mode 100644
index 00000000000..a7ba9b4d817
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
@@ -0,0 +1,49 @@
+#![warn(clippy::ptr_eq)]
+#![no_std]
+#![feature(lang_items)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+macro_rules! mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ as usize == $b as *const _ as usize
+    };
+}
+
+macro_rules! another_mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ == $b as *const _
+    };
+}
+
+fn main() {
+    let a = &[1, 2, 3];
+    let b = &[1, 2, 3];
+
+    let _ = a as *const _ as usize == b as *const _ as usize;
+    let _ = a as *const _ == b as *const _;
+    let _ = a.as_ptr() == b as *const _;
+    let _ = a.as_ptr() == b.as_ptr();
+
+    // Do not lint
+
+    let _ = mac!(a, b);
+    let _ = another_mac!(a, b);
+
+    let a = &mut [1, 2, 3];
+    let b = &mut [1, 2, 3];
+
+    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    let _ = a.as_mut_ptr() == b.as_mut_ptr();
+
+    let _ = a == b;
+    let _ = core::ptr::eq(a, b);
+}
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr b/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
new file mode 100644
index 00000000000..3e289f5be61
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
@@ -0,0 +1,17 @@
+error: use `core::ptr::eq` when comparing raw pointers
+  --> $DIR/ptr_eq_no_std.rs:31:13
+   |
+LL |     let _ = a as *const _ as usize == b as *const _ as usize;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
+   |
+   = note: `-D clippy::ptr-eq` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> $DIR/ptr_eq_no_std.rs:32:13
+   |
+LL |     let _ = a as *const _ == b as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/read_zero_byte_vec.rs b/src/tools/clippy/tests/ui/read_zero_byte_vec.rs
index 76b9b981851..fd5a88a37a6 100644
--- a/src/tools/clippy/tests/ui/read_zero_byte_vec.rs
+++ b/src/tools/clippy/tests/ui/read_zero_byte_vec.rs
@@ -56,14 +56,6 @@ fn test() -> io::Result<()> {
     f.read(&mut buf)?;
 
     // should not lint
-    let mut empty = vec![];
-    let mut data7 = vec![];
-    f.read(&mut empty);
-
-    // should not lint
-    f.read(&mut data7);
-
-    // should not lint
     let mut data8 = Vec::new();
     data8.resize(100, 0);
     f.read_exact(&mut data8)?;
@@ -75,6 +67,27 @@ fn test() -> io::Result<()> {
     Ok(())
 }
 
+fn test_nested() -> io::Result<()> {
+    let cap = 1000;
+    let mut f = File::open("foo.txt").unwrap();
+
+    // Issue #9274
+    // Should not lint
+    let mut v = Vec::new();
+    {
+        v.resize(10, 0);
+        f.read(&mut v)?;
+    }
+
+    let mut v = Vec::new();
+    {
+        f.read(&mut v)?;
+        //~^ ERROR: reading zero byte data to `Vec`
+    }
+
+    Ok(())
+}
+
 async fn test_futures<R: AsyncRead + Unpin>(r: &mut R) {
     // should lint
     let mut data = Vec::new();
diff --git a/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr b/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr
index 523ecb2948d..e85aa051c34 100644
--- a/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr
+++ b/src/tools/clippy/tests/ui/read_zero_byte_vec.stderr
@@ -2,7 +2,7 @@ error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:21:5
    |
 LL |     f.read_exact(&mut data).unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data).unwrap();`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data)`
    |
    = note: `-D clippy::read-zero-byte-vec` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::read_zero_byte_vec)]`
@@ -11,19 +11,19 @@ error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:27:5
    |
 LL |     f.read_exact(&mut data2)?;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)?;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)`
 
 error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:32:5
    |
 LL |     f.read_exact(&mut data3)?;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:37:5
+  --> $DIR/read_zero_byte_vec.rs:37:13
    |
 LL |     let _ = f.read(&mut data4)?;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:43:9
@@ -38,28 +38,34 @@ LL |         f.read(&mut data6)
    |         ^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:81:5
+  --> $DIR/read_zero_byte_vec.rs:84:9
+   |
+LL |         f.read(&mut v)?;
+   |         ^^^^^^^^^^^^^^
+
+error: reading zero byte data to `Vec`
+  --> $DIR/read_zero_byte_vec.rs:94:5
    |
 LL |     r.read(&mut data).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:86:5
+  --> $DIR/read_zero_byte_vec.rs:99:5
    |
 LL |     r.read_exact(&mut data2).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:93:5
+  --> $DIR/read_zero_byte_vec.rs:106:5
    |
 LL |     r.read(&mut data).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:98:5
+  --> $DIR/read_zero_byte_vec.rs:111:5
    |
 LL |     r.read_exact(&mut data2).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.stderr b/src/tools/clippy/tests/ui/result_map_or_into_option.stderr
index 3d6bfef48ec..201868f09ef 100644
--- a/src/tools/clippy/tests/ui/result_map_or_into_option.stderr
+++ b/src/tools/clippy/tests/ui/result_map_or_into_option.stderr
@@ -2,7 +2,7 @@ error: called `map_or(None, Some)` on a `Result` value
   --> $DIR/result_map_or_into_option.rs:5:13
    |
 LL |     let _ = opt.map_or(None, Some);
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`
    |
    = note: `-D clippy::result-map-or-into-option` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`
@@ -11,13 +11,13 @@ error: called `map_or_else(|_| None, Some)` on a `Result` value
   --> $DIR/result_map_or_into_option.rs:7:13
    |
 LL |     let _ = opt.map_or_else(|_| None, Some);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`
 
 error: called `map_or_else(|_| None, Some)` on a `Result` value
   --> $DIR/result_map_or_into_option.rs:10:13
    |
 LL |     let _ = opt.map_or_else(|_| { None }, Some);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_item_push.stderr b/src/tools/clippy/tests/ui/same_item_push.stderr
index f519be46369..f569aab6490 100644
--- a/src/tools/clippy/tests/ui/same_item_push.stderr
+++ b/src/tools/clippy/tests/ui/same_item_push.stderr
@@ -4,7 +4,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
    = note: `-D clippy::same-item-push` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]`
 
@@ -14,7 +14,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:36:9
@@ -22,7 +22,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(13);
    |         ^^^
    |
-   = help: try using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
+   = help: consider using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:42:9
@@ -30,7 +30,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(VALUE);
    |         ^^^
    |
-   = help: try using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
+   = help: consider using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:49:9
@@ -38,7 +38,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
 
 error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/search_is_some.stderr b/src/tools/clippy/tests/ui/search_is_some.stderr
index a7a47447f61..9dec8c9caf2 100644
--- a/src/tools/clippy/tests/ui/search_is_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some.stderr
@@ -40,7 +40,7 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some.rs:42:20
    |
 LL |     let _ = (0..1).find(some_closure).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(some_closure)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(some_closure)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some.rs:52:13
@@ -82,7 +82,7 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some.rs:79:13
    |
 LL |     let _ = (0..1).find(some_closure).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(some_closure)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr b/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr
index f33b0430912..107f59a97d2 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_none.stderr
@@ -2,7 +2,7 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:9:13
    |
 LL |     let _ = v.iter().find(|&x| *x < 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x < 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x < 0)`
    |
    = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
@@ -11,43 +11,43 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:10:13
    |
 LL |     let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| **y == x)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| **y == x)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:11:13
    |
 LL |     let _ = (0..1).find(|x| *x == 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| x == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| x == 0)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:12:13
    |
 LL |     let _ = v.iter().find(|x| **x == 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 0)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:13:13
    |
 LL |     let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:14:13
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:15:13
    |
 LL |     let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:16:13
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:17:13
@@ -56,91 +56,91 @@ LL |       let _ = (1..3)
    |  _____________^
 LL | |         .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)
 LL | |         .is_none();
-   | |__________________^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
+   | |__________________^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
 
 error: called `is_none()` after searching an `Iterator` with `position`
   --> $DIR/search_is_some_fixable_none.rs:22:13
    |
 LL |     let _ = v.iter().position(|&x| x < 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)`
 
 error: called `is_none()` after searching an `Iterator` with `rposition`
   --> $DIR/search_is_some_fixable_none.rs:25:13
    |
 LL |     let _ = v.iter().rposition(|&x| x < 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:31:13
    |
 LL |     let _ = "hello world".find("world").is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains("world")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains("world")`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:32:13
    |
 LL |     let _ = "hello world".find(&s2).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:33:13
    |
 LL |     let _ = "hello world".find(&s2[2..]).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2[2..])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2[2..])`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:35:13
    |
 LL |     let _ = s1.find("world").is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains("world")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains("world")`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:36:13
    |
 LL |     let _ = s1.find(&s2).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:37:13
    |
 LL |     let _ = s1.find(&s2[2..]).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2[2..])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2[2..])`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:39:13
    |
 LL |     let _ = s1[2..].find("world").is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains("world")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains("world")`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:40:13
    |
 LL |     let _ = s1[2..].find(&s2).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:41:13
    |
 LL |     let _ = s1[2..].find(&s2[2..]).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2[2..])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2[2..])`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:57:25
    |
 LL |             .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == &cc)`
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == &cc)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:73:30
    |
 LL |             .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == cc)`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == cc)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:84:17
    |
 LL |         let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:87:17
@@ -152,7 +152,7 @@ LL | |             .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)
 LL | |             .is_none();
    | |______________________^
    |
-help: use `!_.any()` instead
+help: consider using
    |
 LL ~         let _ = !vfoo
 LL ~             .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2);
@@ -162,49 +162,49 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:95:17
    |
 LL |         let _ = vfoo.iter().find(|a| a[0] == 42).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|a| a[0] == 42)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|a| a[0] == 42)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:101:17
    |
 LL |         let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:119:17
    |
 LL |         let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:120:17
    |
 LL |         let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:123:17
    |
 LL |         let _ = v.iter().find(|x| deref_enough(**x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| deref_enough(*x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| deref_enough(*x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:124:17
    |
 LL |         let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| deref_enough(*x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| deref_enough(*x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:127:17
    |
 LL |         let _ = v.iter().find(|x| arg_no_deref(x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| arg_no_deref(&x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| arg_no_deref(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:129:17
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| arg_no_deref(&x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| arg_no_deref(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:149:17
@@ -216,7 +216,7 @@ LL | |             .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] ==
 LL | |             .is_none();
    | |______________________^
    |
-help: use `!_.any()` instead
+help: consider using
    |
 LL ~         let _ = !vfoo
 LL ~             .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2);
@@ -226,61 +226,61 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:165:17
    |
 LL |         let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.inner[0].bar == 2)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.inner[0].bar == 2)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:170:17
    |
 LL |         let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|x| (**x)[0] == 9)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|x| (**x)[0] == 9)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:183:17
    |
 LL |         let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.by_ref(&v.bar))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.by_ref(&v.bar))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:187:17
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:188:17
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:207:17
    |
 LL |         let _ = v.iter().find(|s| s[0].is_empty()).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| s[0].is_empty())`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| s[0].is_empty())`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:208:17
    |
 LL |         let _ = v.iter().find(|s| test_string_1(&s[0])).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| test_string_1(&s[0]))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| test_string_1(&s[0]))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:217:17
    |
 LL |         let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| fp.field.is_power_of_two())`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| fp.field.is_power_of_two())`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:218:17
    |
 LL |         let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_1(fp.field))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_1(fp.field))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:219:17
    |
 LL |         let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_2(*fp.field))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_2(*fp.field))`
 
 error: aborting due to 43 previous errors
 
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
index e878e62de07..e706ce64692 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
@@ -2,7 +2,7 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:9:22
    |
 LL |     let _ = v.iter().find(|&x| *x < 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x < 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x < 0)`
    |
    = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
@@ -11,43 +11,43 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:10:20
    |
 LL |     let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| **y == x)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| **y == x)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:11:20
    |
 LL |     let _ = (0..1).find(|x| *x == 0).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:12:22
    |
 LL |     let _ = v.iter().find(|x| **x == 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x == 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x == 0)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:13:20
    |
 LL |     let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 1 || x == 3 || x == 5)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 1 || x == 3 || x == 5)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:14:20
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x))`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:15:20
    |
 LL |     let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0 || [1, 2, 3].contains(&x))`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0 || [1, 2, 3].contains(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:16:20
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:18:10
@@ -55,91 +55,91 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |           .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)
    |  __________^
 LL | |         .is_some();
-   | |__________________^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
+   | |__________________^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
 
 error: called `is_some()` after searching an `Iterator` with `position`
   --> $DIR/search_is_some_fixable_some.rs:22:22
    |
 LL |     let _ = v.iter().position(|&x| x < 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)`
 
 error: called `is_some()` after searching an `Iterator` with `rposition`
   --> $DIR/search_is_some_fixable_some.rs:25:22
    |
 LL |     let _ = v.iter().rposition(|&x| x < 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:30:27
    |
 LL |     let _ = "hello world".find("world").is_some();
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:31:27
    |
 LL |     let _ = "hello world".find(&s2).is_some();
-   |                           ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
+   |                           ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:32:27
    |
 LL |     let _ = "hello world".find(&s2[2..]).is_some();
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:34:16
    |
 LL |     let _ = s1.find("world").is_some();
-   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:35:16
    |
 LL |     let _ = s1.find(&s2).is_some();
-   |                ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
+   |                ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:36:16
    |
 LL |     let _ = s1.find(&s2[2..]).is_some();
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:38:21
    |
 LL |     let _ = s1[2..].find("world").is_some();
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:39:21
    |
 LL |     let _ = s1[2..].find(&s2).is_some();
-   |                     ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
+   |                     ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:40:21
    |
 LL |     let _ = s1[2..].find(&s2[2..]).is_some();
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:56:44
    |
 LL |             .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some())
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == &cc)`
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == &cc)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:72:49
    |
 LL |             .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some())
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == cc)`
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == cc)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:83:29
    |
 LL |         let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.foo == 1 && v.bar == 2)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.foo == 1 && v.bar == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:88:14
@@ -147,55 +147,55 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |               .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)
    |  ______________^
 LL | |             .is_some();
-   | |______________________^ help: use `any()` instead: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)`
+   | |______________________^ help: consider using: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:94:29
    |
 LL |         let _ = vfoo.iter().find(|a| a[0] == 42).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|a| a[0] == 42)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|a| a[0] == 42)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:100:29
    |
 LL |         let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|sub| sub[1..4].len() == 3)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|sub| sub[1..4].len() == 3)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:118:30
    |
 LL |         let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|ppp_x: &&u32| please(ppp_x))`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|ppp_x: &&u32| please(ppp_x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:119:50
    |
 LL |         let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some();
-   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s.len() == 2)`
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s.len() == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:122:26
    |
 LL |         let _ = v.iter().find(|x| deref_enough(**x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| deref_enough(*x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| deref_enough(*x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:123:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| deref_enough(*x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| deref_enough(*x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:126:26
    |
 LL |         let _ = v.iter().find(|x| arg_no_deref(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| arg_no_deref(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| arg_no_deref(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:128:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:150:14
@@ -203,91 +203,91 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |               .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)
    |  ______________^
 LL | |             .is_some();
-   | |______________________^ help: use `any()` instead: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)`
+   | |______________________^ help: consider using: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:164:29
    |
 LL |         let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.inner[0].bar == 2)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.inner[0].bar == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:169:29
    |
 LL |         let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| (**x)[0] == 9)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| (**x)[0] == 9)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:182:29
    |
 LL |         let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.by_ref(&v.bar))`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.by_ref(&v.bar))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:186:55
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some();
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)`
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:187:55
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some();
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)`
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:206:26
    |
 LL |         let _ = v.iter().find(|s| s[0].is_empty()).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s[0].is_empty())`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s[0].is_empty())`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:207:26
    |
 LL |         let _ = v.iter().find(|s| test_string_1(&s[0])).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| test_string_1(&s[0]))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| test_string_1(&s[0]))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:216:26
    |
 LL |         let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| fp.field.is_power_of_two())`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| fp.field.is_power_of_two())`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:217:26
    |
 LL |         let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_1(fp.field))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_1(fp.field))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:218:26
    |
 LL |         let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_2(*fp.field))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_2(*fp.field))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:233:18
    |
 LL |         v.iter().find(|x: &&u32| func(x)).is_some()
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| func(&x))`
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| func(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:242:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_impl(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_impl(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:245:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_dyn(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_dyn(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:248:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`
 
 error: aborting due to 47 previous errors
 
diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
index 15cc8d54faa..8859a68320f 100644
--- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
@@ -80,6 +80,7 @@ fn main() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -104,6 +105,7 @@ fn msrv_1_54() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -124,6 +126,7 @@ fn msrv_1_55() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
index 197225ffbd5..7b72efb34ff 100644
--- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
@@ -80,6 +80,7 @@ fn main() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -104,6 +105,7 @@ fn msrv_1_54() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -124,6 +126,7 @@ fn msrv_1_55() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
index 05c11cf7f8c..b6b0d2effa8 100644
--- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
@@ -14,7 +14,7 @@ LL |     t.seek(SeekFrom::Start(0));
    |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
 
 error: used `seek` to go to the start of the stream
-  --> $DIR/seek_to_start_instead_of_rewind.rs:133:7
+  --> $DIR/seek_to_start_instead_of_rewind.rs:136:7
    |
 LL |     f.seek(SeekFrom::Start(0));
    |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed
index bbcc0de27d1..cdfa5d9cc78 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.fixed
@@ -1,6 +1,11 @@
+//@aux-build:proc_macro_attr.rs
+
 #![warn(clippy::semicolon_if_nothing_returned)]
 #![allow(clippy::redundant_closure, clippy::uninlined_format_args, clippy::needless_late_init)]
 
+#[macro_use]
+extern crate proc_macro_attr;
+
 fn get_unit() {}
 
 // the functions below trigger the lint
@@ -120,3 +125,32 @@ fn let_else_stmts() {
         return;
     };
 }
+
+mod issue12123 {
+    #[rustfmt::skip]
+    mod this_triggers {
+        #[fake_main]
+        async fn main() {
+
+        }
+    }
+
+    mod and_this {
+        #[fake_main]
+        async fn main() {
+            println!("hello");
+        }
+    }
+
+    #[rustfmt::skip]
+    mod maybe_this {
+        /** */ #[fake_main]
+        async fn main() {
+        }
+    }
+
+    mod but_this_does_not {
+        #[fake_main]
+        async fn main() {}
+    }
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
index fdc9c0c33f5..315b7e4f383 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
@@ -1,6 +1,11 @@
+//@aux-build:proc_macro_attr.rs
+
 #![warn(clippy::semicolon_if_nothing_returned)]
 #![allow(clippy::redundant_closure, clippy::uninlined_format_args, clippy::needless_late_init)]
 
+#[macro_use]
+extern crate proc_macro_attr;
+
 fn get_unit() {}
 
 // the functions below trigger the lint
@@ -120,3 +125,32 @@ fn let_else_stmts() {
         return;
     };
 }
+
+mod issue12123 {
+    #[rustfmt::skip]
+    mod this_triggers {
+        #[fake_main]
+        async fn main() {
+
+        }
+    }
+
+    mod and_this {
+        #[fake_main]
+        async fn main() {
+            println!("hello");
+        }
+    }
+
+    #[rustfmt::skip]
+    mod maybe_this {
+        /** */ #[fake_main]
+        async fn main() {
+        }
+    }
+
+    mod but_this_does_not {
+        #[fake_main]
+        async fn main() {}
+    }
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
index 66373a13c56..09c4d12f216 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
@@ -1,5 +1,5 @@
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:8:5
+  --> $DIR/semicolon_if_nothing_returned.rs:13:5
    |
 LL |     println!("Hello")
    |     ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");`
@@ -8,25 +8,25 @@ LL |     println!("Hello")
    = help: to override `-D warnings` add `#[allow(clippy::semicolon_if_nothing_returned)]`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:12:5
+  --> $DIR/semicolon_if_nothing_returned.rs:17:5
    |
 LL |     get_unit()
    |     ^^^^^^^^^^ help: add a `;` here: `get_unit();`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:17:5
+  --> $DIR/semicolon_if_nothing_returned.rs:22:5
    |
 LL |     y = x + 1
    |     ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:23:9
+  --> $DIR/semicolon_if_nothing_returned.rs:28:9
    |
 LL |         hello()
    |         ^^^^^^^ help: add a `;` here: `hello();`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:34:9
+  --> $DIR/semicolon_if_nothing_returned.rs:39:9
    |
 LL |         ptr::drop_in_place(s.as_mut_ptr())
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
diff --git a/src/tools/clippy/tests/ui/single_call_fn.rs b/src/tools/clippy/tests/ui/single_call_fn.rs
index 3cc8061647d..c20214feccc 100644
--- a/src/tools/clippy/tests/ui/single_call_fn.rs
+++ b/src/tools/clippy/tests/ui/single_call_fn.rs
@@ -69,6 +69,17 @@ fn e() {
 #[test]
 fn k() {}
 
+mod issue12182 {
+    #[allow(clippy::single_call_fn)]
+    fn print_foo(text: &str) {
+        println!("{text}");
+    }
+
+    fn use_print_foo() {
+        print_foo("foo");
+    }
+}
+
 #[test]
 fn l() {
     k();
diff --git a/src/tools/clippy/tests/ui/single_char_pattern.stderr b/src/tools/clippy/tests/ui/single_char_pattern.stderr
index 781ab316d9d..664d6b5a1e9 100644
--- a/src/tools/clippy/tests/ui/single_char_pattern.stderr
+++ b/src/tools/clippy/tests/ui/single_char_pattern.stderr
@@ -2,7 +2,7 @@ error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:7:13
    |
 LL |     x.split("x");
-   |             ^^^ help: try using a `char` instead: `'x'`
+   |             ^^^ help: consider using a `char`: `'x'`
    |
    = note: `-D clippy::single-char-pattern` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::single_char_pattern)]`
@@ -11,235 +11,235 @@ error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:13:13
    |
 LL |     x.split("ß");
-   |             ^^^ help: try using a `char` instead: `'ß'`
+   |             ^^^ help: consider using a `char`: `'ß'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:14:13
    |
 LL |     x.split("ℝ");
-   |             ^^^ help: try using a `char` instead: `'ℝ'`
+   |             ^^^ help: consider using a `char`: `'ℝ'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:15:13
    |
 LL |     x.split("💣");
-   |             ^^^^ help: try using a `char` instead: `'💣'`
+   |             ^^^^ help: consider using a `char`: `'💣'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:18:23
    |
 LL |     x.split_inclusive("x");
-   |                       ^^^ help: try using a `char` instead: `'x'`
+   |                       ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:19:16
    |
 LL |     x.contains("x");
-   |                ^^^ help: try using a `char` instead: `'x'`
+   |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:20:19
    |
 LL |     x.starts_with("x");
-   |                   ^^^ help: try using a `char` instead: `'x'`
+   |                   ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:21:17
    |
 LL |     x.ends_with("x");
-   |                 ^^^ help: try using a `char` instead: `'x'`
+   |                 ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:22:12
    |
 LL |     x.find("x");
-   |            ^^^ help: try using a `char` instead: `'x'`
+   |            ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:23:13
    |
 LL |     x.rfind("x");
-   |             ^^^ help: try using a `char` instead: `'x'`
+   |             ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:24:14
    |
 LL |     x.rsplit("x");
-   |              ^^^ help: try using a `char` instead: `'x'`
+   |              ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:25:24
    |
 LL |     x.split_terminator("x");
-   |                        ^^^ help: try using a `char` instead: `'x'`
+   |                        ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:26:25
    |
 LL |     x.rsplit_terminator("x");
-   |                         ^^^ help: try using a `char` instead: `'x'`
+   |                         ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:27:17
    |
 LL |     x.splitn(2, "x");
-   |                 ^^^ help: try using a `char` instead: `'x'`
+   |                 ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:28:18
    |
 LL |     x.rsplitn(2, "x");
-   |                  ^^^ help: try using a `char` instead: `'x'`
+   |                  ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:29:18
    |
 LL |     x.split_once("x");
-   |                  ^^^ help: try using a `char` instead: `'x'`
+   |                  ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:30:19
    |
 LL |     x.rsplit_once("x");
-   |                   ^^^ help: try using a `char` instead: `'x'`
+   |                   ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:31:15
    |
 LL |     x.matches("x");
-   |               ^^^ help: try using a `char` instead: `'x'`
+   |               ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:32:16
    |
 LL |     x.rmatches("x");
-   |                ^^^ help: try using a `char` instead: `'x'`
+   |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:33:21
    |
 LL |     x.match_indices("x");
-   |                     ^^^ help: try using a `char` instead: `'x'`
+   |                     ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:34:22
    |
 LL |     x.rmatch_indices("x");
-   |                      ^^^ help: try using a `char` instead: `'x'`
+   |                      ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:35:26
    |
 LL |     x.trim_start_matches("x");
-   |                          ^^^ help: try using a `char` instead: `'x'`
+   |                          ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:36:24
    |
 LL |     x.trim_end_matches("x");
-   |                        ^^^ help: try using a `char` instead: `'x'`
+   |                        ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:37:20
    |
 LL |     x.strip_prefix("x");
-   |                    ^^^ help: try using a `char` instead: `'x'`
+   |                    ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:38:20
    |
 LL |     x.strip_suffix("x");
-   |                    ^^^ help: try using a `char` instead: `'x'`
+   |                    ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:39:15
    |
 LL |     x.replace("x", "y");
-   |               ^^^ help: try using a `char` instead: `'x'`
+   |               ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:40:16
    |
 LL |     x.replacen("x", "y", 3);
-   |                ^^^ help: try using a `char` instead: `'x'`
+   |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:42:13
    |
 LL |     x.split("\n");
-   |             ^^^^ help: try using a `char` instead: `'\n'`
+   |             ^^^^ help: consider using a `char`: `'\n'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:43:13
    |
 LL |     x.split("'");
-   |             ^^^ help: try using a `char` instead: `'\''`
+   |             ^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:44:13
    |
 LL |     x.split("\'");
-   |             ^^^^ help: try using a `char` instead: `'\''`
+   |             ^^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:46:13
    |
 LL |     x.split("\"");
-   |             ^^^^ help: try using a `char` instead: `'"'`
+   |             ^^^^ help: consider using a `char`: `'"'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:51:31
    |
 LL |     x.replace(';', ",").split(","); // issue #2978
-   |                               ^^^ help: try using a `char` instead: `','`
+   |                               ^^^ help: consider using a `char`: `','`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:52:19
    |
 LL |     x.starts_with("\x03"); // issue #2996
-   |                   ^^^^^^ help: try using a `char` instead: `'\x03'`
+   |                   ^^^^^^ help: consider using a `char`: `'\x03'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:59:13
    |
 LL |     x.split(r"a");
-   |             ^^^^ help: try using a `char` instead: `'a'`
+   |             ^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:60:13
    |
 LL |     x.split(r#"a"#);
-   |             ^^^^^^ help: try using a `char` instead: `'a'`
+   |             ^^^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:61:13
    |
 LL |     x.split(r###"a"###);
-   |             ^^^^^^^^^^ help: try using a `char` instead: `'a'`
+   |             ^^^^^^^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:62:13
    |
 LL |     x.split(r###"'"###);
-   |             ^^^^^^^^^^ help: try using a `char` instead: `'\''`
+   |             ^^^^^^^^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:63:13
    |
 LL |     x.split(r###"#"###);
-   |             ^^^^^^^^^^ help: try using a `char` instead: `'#'`
+   |             ^^^^^^^^^^ help: consider using a `char`: `'#'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:65:13
    |
 LL |     x.split(r#"\"#);
-   |             ^^^^^^ help: try using a `char` instead: `'\\'`
+   |             ^^^^^^ help: consider using a `char`: `'\\'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:66:13
    |
 LL |     x.split(r"\");
-   |             ^^^^ help: try using a `char` instead: `'\\'`
+   |             ^^^^ help: consider using a `char`: `'\\'`
 
 error: aborting due to 40 previous errors
 
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
index 4fca29698e0..7e2663d734f 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
@@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send)) {
     unimplemented!();
 }
 
-fn main() {}
+trait Proj {
+    type S;
+}
+
+impl Proj for () {
+    type S = ();
+}
+
+impl Proj for i32 {
+    type S = i32;
+}
+
+trait Base<T> {
+    fn is_base(&self);
+}
+
+trait Derived<B: Proj>: Base<B::S> + Base<()> {
+    fn is_derived(&self);
+}
+
+fn f<P: Proj>(obj: &dyn Derived<P>) {
+    obj.is_derived();
+    Base::<P::S>::is_base(obj);
+    Base::<()>::is_base(obj);
+}
+
+fn main() {
+    let _x: fn(_) = f::<()>;
+    let _x: fn(_) = f::<i32>;
+}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index f67c8e35ed4..fede1671a43 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
     unimplemented!();
 }
 
-fn main() {}
+trait Proj {
+    type S;
+}
+
+impl Proj for () {
+    type S = ();
+}
+
+impl Proj for i32 {
+    type S = i32;
+}
+
+trait Base<T> {
+    fn is_base(&self);
+}
+
+trait Derived<B: Proj>: Base<B::S> + Base<()> {
+    fn is_derived(&self);
+}
+
+fn f<P: Proj>(obj: &dyn Derived<P>) {
+    obj.is_derived();
+    Base::<P::S>::is_base(obj);
+    Base::<()>::is_base(obj);
+}
+
+fn main() {
+    let _x: fn(_) = f::<()>;
+    let _x: fn(_) = f::<i32>;
+}
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 32f6027e991..1796ccaf28e 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -102,19 +102,6 @@ fn crosspointer() {
     }
 }
 
-#[warn(clippy::transmute_int_to_char)]
-fn int_to_char() {
-    let _: char = unsafe { std::mem::transmute(0_u32) };
-    //~^ ERROR: transmute from a `u32` to a `char`
-    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
-    let _: char = unsafe { std::mem::transmute(0_i32) };
-    //~^ ERROR: transmute from a `i32` to a `char`
-
-    // These shouldn't warn
-    const _: char = unsafe { std::mem::transmute(0_u32) };
-    const _: char = unsafe { std::mem::transmute(0_i32) };
-}
-
 #[warn(clippy::transmute_int_to_bool)]
 fn int_to_bool() {
     let _: bool = unsafe { std::mem::transmute(0_u8) };
diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr
index cdc733b54a9..df32d478cbf 100644
--- a/src/tools/clippy/tests/ui/transmute.stderr
+++ b/src/tools/clippy/tests/ui/transmute.stderr
@@ -88,23 +88,8 @@ error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
 LL |         let _: *mut Usize = core::intrinsics::transmute(my_int());
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: transmute from a `u32` to a `char`
-  --> $DIR/transmute.rs:107:28
-   |
-LL |     let _: char = unsafe { std::mem::transmute(0_u32) };
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
-   |
-   = note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
-
-error: transmute from a `i32` to a `char`
-  --> $DIR/transmute.rs:110:28
-   |
-LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
-
 error: transmute from a `u8` to a `bool`
-  --> $DIR/transmute.rs:120:28
+  --> $DIR/transmute.rs:107:28
    |
 LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
@@ -113,7 +98,7 @@ LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]`
 
 error: transmute from a `u32` to a `f32`
-  --> $DIR/transmute.rs:128:31
+  --> $DIR/transmute.rs:115:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
@@ -122,25 +107,25 @@ LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]`
 
 error: transmute from a `i32` to a `f32`
-  --> $DIR/transmute.rs:131:31
+  --> $DIR/transmute.rs:118:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_i32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
 
 error: transmute from a `u64` to a `f64`
-  --> $DIR/transmute.rs:133:31
+  --> $DIR/transmute.rs:120:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_u64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
 
 error: transmute from a `i64` to a `f64`
-  --> $DIR/transmute.rs:135:31
+  --> $DIR/transmute.rs:122:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_i64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:156:30
+  --> $DIR/transmute.rs:143:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -149,85 +134,85 @@ LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:159:30
+  --> $DIR/transmute.rs:146:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:161:31
+  --> $DIR/transmute.rs:148:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:163:30
+  --> $DIR/transmute.rs:150:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:165:30
+  --> $DIR/transmute.rs:152:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:167:31
+  --> $DIR/transmute.rs:154:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `f32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:169:30
+  --> $DIR/transmute.rs:156:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
 
 error: transmute from a `f64` to a `[u8; 8]`
-  --> $DIR/transmute.rs:171:30
+  --> $DIR/transmute.rs:158:30
    |
 LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:177:30
+  --> $DIR/transmute.rs:164:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:179:30
+  --> $DIR/transmute.rs:166:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:181:31
+  --> $DIR/transmute.rs:168:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:183:30
+  --> $DIR/transmute.rs:170:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:185:30
+  --> $DIR/transmute.rs:172:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:187:31
+  --> $DIR/transmute.rs:174:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> $DIR/transmute.rs:198:28
+  --> $DIR/transmute.rs:185:28
    |
 LL |     let _: &str = unsafe { std::mem::transmute(B) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
@@ -236,16 +221,16 @@ LL |     let _: &str = unsafe { std::mem::transmute(B) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
 
 error: transmute from a `&mut [u8]` to a `&mut str`
-  --> $DIR/transmute.rs:201:32
+  --> $DIR/transmute.rs:188:32
    |
 LL |     let _: &mut str = unsafe { std::mem::transmute(mb) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> $DIR/transmute.rs:203:30
+  --> $DIR/transmute.rs:190:30
    |
 LL |     const _: &str = unsafe { std::mem::transmute(B) };
    |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
 
-error: aborting due to 38 previous errors
+error: aborting due to 36 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.fixed b/src/tools/clippy/tests/ui/transmute_int_to_char.fixed
new file mode 100644
index 00000000000..17080118175
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char.fixed
@@ -0,0 +1,15 @@
+#![warn(clippy::transmute_int_to_char)]
+
+fn int_to_char() {
+    let _: char = unsafe { std::char::from_u32(0_u32).unwrap() };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { std::char::from_u32(0_i32 as u32).unwrap() };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { std::mem::transmute(0_u32) };
+    const _: char = unsafe { std::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.rs b/src/tools/clippy/tests/ui/transmute_int_to_char.rs
new file mode 100644
index 00000000000..5846a97e88a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char.rs
@@ -0,0 +1,15 @@
+#![warn(clippy::transmute_int_to_char)]
+
+fn int_to_char() {
+    let _: char = unsafe { std::mem::transmute(0_u32) };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { std::mem::transmute(0_i32) };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { std::mem::transmute(0_u32) };
+    const _: char = unsafe { std::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.stderr b/src/tools/clippy/tests/ui/transmute_int_to_char.stderr
new file mode 100644
index 00000000000..2297f5b4f8b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char.stderr
@@ -0,0 +1,17 @@
+error: transmute from a `u32` to a `char`
+  --> $DIR/transmute_int_to_char.rs:4:28
+   |
+LL |     let _: char = unsafe { std::mem::transmute(0_u32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
+   |
+   = note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
+
+error: transmute from a `i32` to a `char`
+  --> $DIR/transmute_int_to_char.rs:7:28
+   |
+LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed
new file mode 100644
index 00000000000..9ae4e11fb56
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed
@@ -0,0 +1,27 @@
+#![no_std]
+#![feature(lang_items)]
+#![warn(clippy::transmute_int_to_char)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn int_to_char() {
+    let _: char = unsafe { core::char::from_u32(0_u32).unwrap() };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { core::char::from_u32(0_i32 as u32).unwrap() };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { core::mem::transmute(0_u32) };
+    const _: char = unsafe { core::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs
new file mode 100644
index 00000000000..9a2afd5bd2f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs
@@ -0,0 +1,27 @@
+#![no_std]
+#![feature(lang_items)]
+#![warn(clippy::transmute_int_to_char)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn int_to_char() {
+    let _: char = unsafe { core::mem::transmute(0_u32) };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { core::mem::transmute(0_i32) };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { core::mem::transmute(0_u32) };
+    const _: char = unsafe { core::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr
new file mode 100644
index 00000000000..aace6968696
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr
@@ -0,0 +1,17 @@
+error: transmute from a `u32` to a `char`
+  --> $DIR/transmute_int_to_char_no_std.rs:16:28
+   |
+LL |     let _: char = unsafe { core::mem::transmute(0_u32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_u32).unwrap()`
+   |
+   = note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
+
+error: transmute from a `i32` to a `char`
+  --> $DIR/transmute_int_to_char_no_std.rs:19:28
+   |
+LL |     let _: char = unsafe { core::mem::transmute(0_i32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_i32 as u32).unwrap()`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs b/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs
index e7f35c57436..bdc7b9f6478 100644
--- a/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs
+++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs
@@ -12,7 +12,7 @@ fn main() {
         let b: &[u8] = unsafe { std::mem::transmute(a) };
         //~^ ERROR: transmute from a reference to a reference
         let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
-        let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
+        let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };
         //~^ ERROR: transmute from a reference to a reference
     }
 }
diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr b/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr
index cc6b156b188..4238bc637ad 100644
--- a/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr
+++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref.stderr
@@ -19,8 +19,8 @@ LL |         let b: &[u8] = unsafe { std::mem::transmute(a) };
 error: transmute from a reference to a reference
   --> $DIR/transmute_ref_to_ref.rs:15:42
    |
-LL |         let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
+LL |         let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs b/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs
new file mode 100644
index 00000000000..b67386f8588
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs
@@ -0,0 +1,30 @@
+//@no-rustfix
+
+#![deny(clippy::transmute_ptr_to_ptr)]
+#![allow(dead_code)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn main() {
+    unsafe {
+        let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];
+        let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };
+        //~^ ERROR: transmute from a reference to a reference
+        let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];
+        let b: &[u8] = unsafe { core::mem::transmute(a) };
+        //~^ ERROR: transmute from a reference to a reference
+        let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
+        let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
+        //~^ ERROR: transmute from a reference to a reference
+    }
+}
diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.stderr b/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.stderr
new file mode 100644
index 00000000000..ca7966ffa9e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.stderr
@@ -0,0 +1,26 @@
+error: transmute from a reference to a reference
+  --> $DIR/transmute_ref_to_ref_no_std.rs:21:39
+   |
+LL |         let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])`
+   |
+note: the lint level is defined here
+  --> $DIR/transmute_ref_to_ref_no_std.rs:3:9
+   |
+LL | #![deny(clippy::transmute_ptr_to_ptr)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: transmute from a reference to a reference
+  --> $DIR/transmute_ref_to_ref_no_std.rs:24:33
+   |
+LL |         let b: &[u8] = unsafe { core::mem::transmute(a) };
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])`
+
+error: transmute from a reference to a reference
+  --> $DIR/transmute_ref_to_ref_no_std.rs:27:42
+   |
+LL |         let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.rs b/src/tools/clippy/tests/ui/unconditional_recursion.rs
index e1a2d6a90b8..7b898a6e0e7 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.rs
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.rs
@@ -264,6 +264,28 @@ impl S13 {
     }
 }
 
-fn main() {
-    // test code goes here
+struct S14 {
+    field: String,
+}
+
+impl PartialEq for S14 {
+    fn eq(&self, other: &Self) -> bool {
+        // Should not warn!
+        self.field.eq(&other.field)
+    }
+}
+
+struct S15<'a> {
+    field: &'a S15<'a>,
 }
+
+impl PartialEq for S15<'_> {
+    fn eq(&self, other: &Self) -> bool {
+        //~^ ERROR: function cannot return without recursing
+        let mine = &self.field;
+        let theirs = &other.field;
+        mine.eq(theirs)
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.stderr b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
index 5d82e2a9f31..094b80d4586 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.stderr
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
@@ -340,5 +340,22 @@ note: recursive call site
 LL |         Self::default()
    |         ^^^^^^^^^^^^^^^
 
-error: aborting due to 26 previous errors
+error: function cannot return without recursing
+  --> $DIR/unconditional_recursion.rs:283:5
+   |
+LL | /     fn eq(&self, other: &Self) -> bool {
+LL | |
+LL | |         let mine = &self.field;
+LL | |         let theirs = &other.field;
+LL | |         mine.eq(theirs)
+LL | |     }
+   | |_____^
+   |
+note: recursive call site
+  --> $DIR/unconditional_recursion.rs:287:9
+   |
+LL |         mine.eq(theirs)
+   |         ^^^^^^^^^^^^^^^
+
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_join.stderr b/src/tools/clippy/tests/ui/unnecessary_join.stderr
index 8bf2ac5fdb1..205a714b694 100644
--- a/src/tools/clippy/tests/ui/unnecessary_join.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_join.stderr
@@ -4,7 +4,7 @@ error: called `.collect::<Vec<String>>().join("")` on an iterator
 LL |           .collect::<Vec<String>>()
    |  __________^
 LL | |         .join("");
-   | |_________________^ help: try using: `collect::<String>()`
+   | |_________________^ help: consider using: `collect::<String>()`
    |
    = note: `-D clippy::unnecessary-join` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_join)]`
@@ -15,7 +15,7 @@ error: called `.collect::<Vec<String>>().join("")` on an iterator
 LL |           .collect::<Vec<_>>()
    |  __________^
 LL | |         .join("");
-   | |_________________^ help: try using: `collect::<String>()`
+   | |_________________^ help: consider using: `collect::<String>()`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr b/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
index 9d54c8d50e3..f4409113a45 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
@@ -1,4 +1,4 @@
-error: use Vec::sort here instead
+error: consider using `sort`
   --> $DIR/unnecessary_sort_by.rs:12:5
    |
 LL |     vec.sort_by(|a, b| a.cmp(b));
@@ -7,67 +7,67 @@ LL |     vec.sort_by(|a, b| a.cmp(b));
    = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]`
 
-error: use Vec::sort here instead
+error: consider using `sort`
   --> $DIR/unnecessary_sort_by.rs:13:5
    |
 LL |     vec.sort_unstable_by(|a, b| a.cmp(b));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:14:5
    |
 LL |     vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (a + 5).abs())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:15:5
    |
 LL |     vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| id(-a))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:18:5
    |
 LL |     vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:19:5
    |
 LL |     vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:29:5
    |
 LL |     vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (***a).abs())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:30:5
    |
 LL |     vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| (***a).abs())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:89:9
    |
 LL |         args.sort_by(|a, b| a.name().cmp(&b.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|a| a.name())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:90:9
    |
 LL |         args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|a| a.name())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:92:9
    |
 LL |         args.sort_by(|a, b| b.name().cmp(&a.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|b| std::cmp::Reverse(b.name()))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:93:9
    |
 LL |         args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.rs b/src/tools/clippy/tests/ui/unused_io_amount.rs
index 62aec6e9eaf..9974600dad5 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.rs
+++ b/src/tools/clippy/tests/ui/unused_io_amount.rs
@@ -1,4 +1,5 @@
 #![allow(dead_code, clippy::needless_pass_by_ref_mut)]
+#![allow(clippy::redundant_pattern_matching)]
 #![warn(clippy::unused_io_amount)]
 
 extern crate futures;
@@ -142,4 +143,90 @@ async fn undetected_bad_async_write<W: AsyncWrite + Unpin>(w: &mut W) {
     future.await.unwrap();
 }
 
+fn match_okay_underscore<T: io::Read + io::Write>(s: &mut T) {
+    match s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    };
+
+    let mut buf = [0u8; 4];
+    match s.read(&mut buf) {
+        //~^ ERROR: read amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    }
+}
+
+fn match_okay_underscore_read_expr<T: io::Read + io::Write>(s: &mut T) {
+    match s.read(&mut [0u8; 4]) {
+        //~^ ERROR: read amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    }
+}
+
+fn match_okay_underscore_write_expr<T: io::Read + io::Write>(s: &mut T) {
+    match s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    }
+}
+
+fn returned_value_should_not_lint<T: io::Read + io::Write>(s: &mut T) -> Result<usize, std::io::Error> {
+    s.write(b"test")
+}
+
+fn if_okay_underscore_read_expr<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(_) = s.read(&mut [0u8; 4]) {
+        //~^ ERROR: read amount is not handled
+        todo!()
+    }
+}
+
+fn if_okay_underscore_write_expr<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(_) = s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        todo!()
+    }
+}
+
+fn if_okay_dots_write_expr<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(..) = s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        todo!()
+    }
+}
+
+fn if_okay_underscore_write_expr_true_negative<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(bound) = s.write(b"test") {
+        todo!()
+    }
+}
+
+fn match_okay_underscore_true_neg<T: io::Read + io::Write>(s: &mut T) {
+    match s.write(b"test") {
+        Ok(bound) => todo!(),
+        Err(_) => todo!(),
+    };
+}
+
+fn true_negative<T: io::Read + io::Write>(s: &mut T) {
+    let mut buf = [0u8; 4];
+    let read_amount = s.read(&mut buf).unwrap();
+}
+
+fn on_return_should_not_raise<T: io::Read + io::Write>(s: &mut T) -> io::Result<usize> {
+    /// this is bad code because it goes around the problem of handling the read amount
+    /// by returning it, which makes it impossible to know this is a resonpose from the
+    /// correct account.
+    let mut buf = [0u8; 4];
+    s.read(&mut buf)
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.stderr b/src/tools/clippy/tests/ui/unused_io_amount.stderr
index f9aef596a1c..4af56d264bf 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.stderr
+++ b/src/tools/clippy/tests/ui/unused_io_amount.stderr
@@ -1,5 +1,5 @@
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:9:5
+  --> $DIR/unused_io_amount.rs:10:5
    |
 LL |     s.write(b"test")?;
    |     ^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     s.write(b"test")?;
    = help: to override `-D warnings` add `#[allow(clippy::unused_io_amount)]`
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:12:5
+  --> $DIR/unused_io_amount.rs:13:5
    |
 LL |     s.read(&mut buf)?;
    |     ^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     s.read(&mut buf)?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:18:5
+  --> $DIR/unused_io_amount.rs:19:5
    |
 LL |     s.write(b"test").unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     s.write(b"test").unwrap();
    = help: use `Write::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:21:5
+  --> $DIR/unused_io_amount.rs:22:5
    |
 LL |     s.read(&mut buf).unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,19 +33,19 @@ LL |     s.read(&mut buf).unwrap();
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:26:5
+  --> $DIR/unused_io_amount.rs:27:5
    |
 LL |     s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:28:5
+  --> $DIR/unused_io_amount.rs:29:5
    |
 LL |     s.write_vectored(&[io::IoSlice::new(&[])])?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:36:5
+  --> $DIR/unused_io_amount.rs:37:5
    |
 LL |     reader.read(&mut result).ok()?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -53,7 +53,7 @@ LL |     reader.read(&mut result).ok()?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:46:5
+  --> $DIR/unused_io_amount.rs:47:5
    |
 LL |     reader.read(&mut result).or_else(|err| Err(err))?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL |     reader.read(&mut result).or_else(|err| Err(err))?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:59:5
+  --> $DIR/unused_io_amount.rs:60:5
    |
 LL |     reader.read(&mut result).or(Err(Error::Kind))?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,7 +69,7 @@ LL |     reader.read(&mut result).or(Err(Error::Kind))?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:67:5
+  --> $DIR/unused_io_amount.rs:68:5
    |
 LL | /     reader
 LL | |
@@ -82,7 +82,7 @@ LL | |         .expect("error");
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:77:5
+  --> $DIR/unused_io_amount.rs:78:5
    |
 LL |     s.write(b"ok").is_ok();
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     s.write(b"ok").is_ok();
    = help: use `Write::write_all` instead, or handle partial writes
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:79:5
+  --> $DIR/unused_io_amount.rs:80:5
    |
 LL |     s.write(b"err").is_err();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -98,7 +98,7 @@ LL |     s.write(b"err").is_err();
    = help: use `Write::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:82:5
+  --> $DIR/unused_io_amount.rs:83:5
    |
 LL |     s.read(&mut buf).is_ok();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,7 +106,7 @@ LL |     s.read(&mut buf).is_ok();
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:84:5
+  --> $DIR/unused_io_amount.rs:85:5
    |
 LL |     s.read(&mut buf).is_err();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +114,7 @@ LL |     s.read(&mut buf).is_err();
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:89:5
+  --> $DIR/unused_io_amount.rs:90:5
    |
 LL |     w.write(b"hello world").await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -122,7 +122,7 @@ LL |     w.write(b"hello world").await.unwrap();
    = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:95:5
+  --> $DIR/unused_io_amount.rs:96:5
    |
 LL |     r.read(&mut buf[..]).await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -130,7 +130,15 @@ LL |     r.read(&mut buf[..]).await.unwrap();
    = help: use `AsyncReadExt::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:109:9
+  --> $DIR/unused_io_amount.rs:104:5
+   |
+LL |     w.write(b"hello world");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:110:9
    |
 LL |         w.write(b"hello world").await?;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,7 +146,7 @@ LL |         w.write(b"hello world").await?;
    = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:118:9
+  --> $DIR/unused_io_amount.rs:119:9
    |
 LL |         r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -146,7 +154,7 @@ LL |         r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
    = help: use `AsyncReadExt::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:127:5
+  --> $DIR/unused_io_amount.rs:128:5
    |
 LL |     w.write(b"hello world").await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,12 +162,103 @@ LL |     w.write(b"hello world").await.unwrap();
    = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:133:5
+  --> $DIR/unused_io_amount.rs:134:5
    |
 LL |     r.read(&mut buf[..]).await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use `AsyncReadExt::read_exact` instead, or handle partial reads
 
-error: aborting due to 20 previous errors
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:147:11
+   |
+LL |     match s.write(b"test") {
+   |           ^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:149:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: read amount is not handled
+  --> $DIR/unused_io_amount.rs:155:11
+   |
+LL |     match s.read(&mut buf) {
+   |           ^^^^^^^^^^^^^^^^
+   |
+   = help: use `Read::read_exact` instead, or handle partial reads
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:157:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: read amount is not handled
+  --> $DIR/unused_io_amount.rs:164:11
+   |
+LL |     match s.read(&mut [0u8; 4]) {
+   |           ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Read::read_exact` instead, or handle partial reads
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:166:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:173:11
+   |
+LL |     match s.write(b"test") {
+   |           ^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:175:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: read amount is not handled
+  --> $DIR/unused_io_amount.rs:186:8
+   |
+LL |     if let Ok(_) = s.read(&mut [0u8; 4]) {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Read::read_exact` instead, or handle partial reads
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:186:12
+   |
+LL |     if let Ok(_) = s.read(&mut [0u8; 4]) {
+   |            ^^^^^
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:193:8
+   |
+LL |     if let Ok(_) = s.write(b"test") {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:193:12
+   |
+LL |     if let Ok(_) = s.write(b"test") {
+   |            ^^^^^
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:200:8
+   |
+LL |     if let Ok(..) = s.write(b"test") {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:200:12
+   |
+LL |     if let Ok(..) = s.write(b"test") {
+   |            ^^^^^^
+
+error: aborting due to 28 previous errors
 
diff --git a/src/tools/clippy/tests/ui/useless_asref.fixed b/src/tools/clippy/tests/ui/useless_asref.fixed
index 88b95095bc0..c98f2928e03 100644
--- a/src/tools/clippy/tests/ui/useless_asref.fixed
+++ b/src/tools/clippy/tests/ui/useless_asref.fixed
@@ -144,6 +144,42 @@ fn foo() {
     //~^ ERROR: this call to `as_ref.map(...)` does nothing
 }
 
+mod issue12135 {
+    pub struct Struct {
+        field: Option<InnerStruct>,
+    }
+
+    #[derive(Clone)]
+    pub struct Foo;
+
+    #[derive(Clone)]
+    struct InnerStruct {
+        x: Foo,
+    }
+
+    impl InnerStruct {
+        fn method(&self) -> &Foo {
+            &self.x
+        }
+    }
+
+    pub fn f(x: &Struct) -> Option<Foo> {
+        x.field.clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223
+        #[allow(clippy::clone_on_copy)]
+        Some(1).clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        x.field.as_ref().map(|v| v.method().clone())
+    }
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/src/tools/clippy/tests/ui/useless_asref.rs b/src/tools/clippy/tests/ui/useless_asref.rs
index 504dc1f5cbf..f9d603f116d 100644
--- a/src/tools/clippy/tests/ui/useless_asref.rs
+++ b/src/tools/clippy/tests/ui/useless_asref.rs
@@ -144,6 +144,42 @@ fn foo() {
     //~^ ERROR: this call to `as_ref.map(...)` does nothing
 }
 
+mod issue12135 {
+    pub struct Struct {
+        field: Option<InnerStruct>,
+    }
+
+    #[derive(Clone)]
+    pub struct Foo;
+
+    #[derive(Clone)]
+    struct InnerStruct {
+        x: Foo,
+    }
+
+    impl InnerStruct {
+        fn method(&self) -> &Foo {
+            &self.x
+        }
+    }
+
+    pub fn f(x: &Struct) -> Option<Foo> {
+        x.field.as_ref().map(|v| v.clone());
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.as_ref().map(Clone::clone);
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.as_ref().map(|v| Clone::clone(v));
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223
+        #[allow(clippy::clone_on_copy)]
+        Some(1).as_ref().map(|&x| x.clone());
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        x.field.as_ref().map(|v| v.method().clone())
+    }
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/src/tools/clippy/tests/ui/useless_asref.stderr b/src/tools/clippy/tests/ui/useless_asref.stderr
index deb5d90f2f6..e158df2664d 100644
--- a/src/tools/clippy/tests/ui/useless_asref.stderr
+++ b/src/tools/clippy/tests/ui/useless_asref.stderr
@@ -88,5 +88,29 @@ error: this call to `as_ref.map(...)` does nothing
 LL |     let z = x.as_ref().map(|z| String::clone(z));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`
 
-error: aborting due to 14 previous errors
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:167:9
+   |
+LL |         x.field.as_ref().map(|v| v.clone());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
+
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:169:9
+   |
+LL |         x.field.as_ref().map(Clone::clone);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
+
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:171:9
+   |
+LL |         x.field.as_ref().map(|v| Clone::clone(v));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
+
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:176:9
+   |
+LL |         Some(1).as_ref().map(|&x| x.clone());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()`
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index a05765b3981..3eadc66f544 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -19,7 +19,6 @@ new_pr = true
 
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
-users_on_vacation = ["blyxyas"]
 
 [assign.owners]
 "/.github" = ["@flip1995"]
diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml
index 76c2e330b21..f4dac6e947e 100644
--- a/src/tools/error_index_generator/Cargo.toml
+++ b/src/tools/error_index_generator/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
 
 [dependencies]
 mdbook = { version = "0.4", default-features = false, features = ["search"] }
-rustc_error_codes = { version = "0.0.0", path = "../../../compiler/rustc_error_codes" }
 
 [[bin]]
 name = "error_index_generator"
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 865d7172cd3..2de2d959a95 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -4,13 +4,15 @@ extern crate rustc_driver;
 extern crate rustc_log;
 extern crate rustc_session;
 
+extern crate rustc_errors;
+use rustc_errors::codes::DIAGNOSTICS;
+
 use std::env;
 use std::error::Error;
 use std::fs::{self, File};
 use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
-
 use std::str::FromStr;
 
 use mdbook::book::{parse_summary, BookItem, Chapter};
@@ -38,7 +40,7 @@ fn render_markdown(output_path: &Path) -> Result<(), Box<dyn Error>> {
 
     write!(output_file, "# Rust Compiler Error Index\n")?;
 
-    for (err_code, description) in rustc_error_codes::DIAGNOSTICS.iter() {
+    for (err_code, description) in DIAGNOSTICS.iter() {
         write!(output_file, "## {}\n{}\n", err_code, description)?
     }
 
@@ -85,7 +87,7 @@ This page lists all the error codes emitted by the Rust compiler.
 "
     );
 
-    let err_codes = rustc_error_codes::DIAGNOSTICS;
+    let err_codes = DIAGNOSTICS;
     let mut chapters = Vec::with_capacity(err_codes.len());
 
     for (err_code, explanation) in err_codes.iter() {
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index bf3284df596..92c58d48dc7 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -104,7 +104,7 @@ impl MachineStopType for TerminationInfo {
         self: Box<Self>,
         _: &mut dyn FnMut(
             std::borrow::Cow<'static, str>,
-            rustc_errors::DiagnosticArgValue<'static>,
+            rustc_errors::DiagnosticArgValue,
         ),
     ) {
     }
diff --git a/src/tools/miri/tests/pass/issues/issue-120337-irrefutable-let-ice.rs b/src/tools/miri/tests/pass/issues/issue-120337-irrefutable-let-ice.rs
new file mode 100644
index 00000000000..5af0d0e4bbd
--- /dev/null
+++ b/src/tools/miri/tests/pass/issues/issue-120337-irrefutable-let-ice.rs
@@ -0,0 +1,16 @@
+// Validation stops the test before the ICE we used to hit
+//@compile-flags: -Zmiri-disable-validation
+
+#![feature(never_type)]
+#[derive(Copy, Clone)]
+pub enum E {
+    A(!),
+}
+pub union U {
+    u: (),
+    e: E,
+}
+
+fn main() {
+    let E::A(ref _a) = unsafe { &(&U { u: () }).e };
+}
diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
index aa25f82ae1d..bf1feb9a7eb 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
@@ -379,14 +379,14 @@ fn unescape_string_error_message(text: &str, mode: Mode) -> &'static str {
     let mut error_message = "";
     match mode {
         Mode::CStr => {
-            rustc_lexer::unescape::unescape_c_string(text, mode, &mut |_, res| {
+            rustc_lexer::unescape::unescape_mixed(text, mode, &mut |_, res| {
                 if let Err(e) = res {
                     error_message = error_to_diagnostic_message(e, mode);
                 }
             });
         }
         Mode::ByteStr | Mode::Str => {
-            rustc_lexer::unescape::unescape_literal(text, mode, &mut |_, res| {
+            rustc_lexer::unescape::unescape_unicode(text, mode, &mut |_, res| {
                 if let Err(e) = res {
                     error_message = error_to_diagnostic_message(e, mode);
                 }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
index b39006e2ff2..7cd1f1550b9 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
@@ -6,7 +6,7 @@ use std::{
 };
 
 use rustc_lexer::unescape::{
-    unescape_byte, unescape_c_string, unescape_char, unescape_literal, CStrUnit, Mode,
+    unescape_byte, unescape_char, unescape_mixed, unescape_unicode, MixedUnit, Mode,
 };
 
 use crate::{
@@ -193,7 +193,7 @@ pub trait IsString: AstToken {
         let text = &self.text()[text_range_no_quotes - start];
         let offset = text_range_no_quotes.start() - start;
 
-        unescape_literal(text, Self::MODE, &mut |range, unescaped_char| {
+        unescape_unicode(text, Self::MODE, &mut |range, unescaped_char| {
             let text_range =
                 TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap());
             cb(text_range + offset, unescaped_char);
@@ -226,7 +226,7 @@ impl ast::String {
         let mut buf = String::new();
         let mut prev_end = 0;
         let mut has_error = false;
-        unescape_literal(text, Self::MODE, &mut |char_range, unescaped_char| match (
+        unescape_unicode(text, Self::MODE, &mut |char_range, unescaped_char| match (
             unescaped_char,
             buf.capacity() == 0,
         ) {
@@ -270,7 +270,7 @@ impl ast::ByteString {
         let mut buf: Vec<u8> = Vec::new();
         let mut prev_end = 0;
         let mut has_error = false;
-        unescape_literal(text, Self::MODE, &mut |char_range, unescaped_char| match (
+        unescape_unicode(text, Self::MODE, &mut |char_range, unescaped_char| match (
             unescaped_char,
             buf.capacity() == 0,
         ) {
@@ -311,7 +311,7 @@ impl IsString for ast::CString {
         let text = &self.text()[text_range_no_quotes - start];
         let offset = text_range_no_quotes.start() - start;
 
-        unescape_c_string(text, Self::MODE, &mut |range, unescaped_char| {
+        unescape_mixed(text, Self::MODE, &mut |range, unescaped_char| {
             let text_range =
                 TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap());
             // XXX: This method should only be used for highlighting ranges. The unescaped
@@ -336,12 +336,11 @@ impl ast::CString {
         let mut buf = Vec::new();
         let mut prev_end = 0;
         let mut has_error = false;
-        let mut char_buf = [0u8; 4];
-        let mut extend_unit = |buf: &mut Vec<u8>, unit: CStrUnit| match unit {
-            CStrUnit::Byte(b) => buf.push(b),
-            CStrUnit::Char(c) => buf.extend(c.encode_utf8(&mut char_buf).as_bytes()),
+        let extend_unit = |buf: &mut Vec<u8>, unit: MixedUnit| match unit {
+            MixedUnit::Char(c) => buf.extend(c.encode_utf8(&mut [0; 4]).as_bytes()),
+            MixedUnit::HighByte(b) => buf.push(b),
         };
-        unescape_c_string(text, Self::MODE, &mut |char_range, unescaped| match (
+        unescape_mixed(text, Self::MODE, &mut |char_range, unescaped| match (
             unescaped,
             buf.capacity() == 0,
         ) {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
index 69dffbf79f1..5c5b26f525f 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
@@ -5,7 +5,7 @@
 mod block;
 
 use rowan::Direction;
-use rustc_lexer::unescape::{self, unescape_literal, Mode};
+use rustc_lexer::unescape::{self, unescape_mixed, unescape_unicode, Mode};
 
 use crate::{
     algo,
@@ -140,7 +140,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
         ast::LiteralKind::String(s) => {
             if !s.is_raw() {
                 if let Some(without_quotes) = unquote(text, 1, '"') {
-                    unescape_literal(without_quotes, Mode::Str, &mut |range, char| {
+                    unescape_unicode(without_quotes, Mode::Str, &mut |range, char| {
                         if let Err(err) = char {
                             push_err(1, range.start, err);
                         }
@@ -151,7 +151,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
         ast::LiteralKind::ByteString(s) => {
             if !s.is_raw() {
                 if let Some(without_quotes) = unquote(text, 2, '"') {
-                    unescape_literal(without_quotes, Mode::ByteStr, &mut |range, char| {
+                    unescape_unicode(without_quotes, Mode::ByteStr, &mut |range, char| {
                         if let Err(err) = char {
                             push_err(1, range.start, err);
                         }
@@ -162,7 +162,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
         ast::LiteralKind::CString(s) => {
             if !s.is_raw() {
                 if let Some(without_quotes) = unquote(text, 2, '"') {
-                    unescape_literal(without_quotes, Mode::ByteStr, &mut |range, char| {
+                    unescape_mixed(without_quotes, Mode::CStr, &mut |range, char| {
                         if let Err(err) = char {
                             push_err(1, range.start, err);
                         }
@@ -172,7 +172,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
         }
         ast::LiteralKind::Char(_) => {
             if let Some(without_quotes) = unquote(text, 1, '\'') {
-                unescape_literal(without_quotes, Mode::Char, &mut |range, char| {
+                unescape_unicode(without_quotes, Mode::Char, &mut |range, char| {
                     if let Err(err) = char {
                         push_err(1, range.start, err);
                     }
@@ -181,7 +181,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
         }
         ast::LiteralKind::Byte(_) => {
             if let Some(without_quotes) = unquote(text, 2, '\'') {
-                unescape_literal(without_quotes, Mode::Byte, &mut |range, char| {
+                unescape_unicode(without_quotes, Mode::Byte, &mut |range, char| {
                     if let Err(err) = char {
                         push_err(2, range.start, err);
                     }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index b03811e5efd..b06c072a2b0 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -340,8 +340,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "termize",
     "thin-vec",
     "thiserror",
-    "thiserror-core",
-    "thiserror-core-impl",
     "thiserror-impl",
     "thorin-dwp",
     "thread_local",
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index 094efa981d3..6fc65e56901 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -2,7 +2,7 @@
 //!
 //! Overview of check:
 //!
-//! 1. We create a list of error codes used by the compiler. Error codes are extracted from `compiler/rustc_error_codes/src/error_codes.rs`.
+//! 1. We create a list of error codes used by the compiler. Error codes are extracted from `compiler/rustc_error_codes/src/lib.rs`.
 //!
 //! 2. We check that the error code has a long-form explanation in `compiler/rustc_error_codes/src/error_codes/`.
 //!   - The explanation is expected to contain a `doctest` that fails with the correct error code. (`EXEMPT_FROM_DOCTEST` *currently* bypasses this check)
@@ -22,7 +22,7 @@ use regex::Regex;
 
 use crate::walk::{filter_dirs, walk, walk_many};
 
-const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/error_codes.rs";
+const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/lib.rs";
 const ERROR_DOCS_PATH: &str = "compiler/rustc_error_codes/src/error_codes/";
 const ERROR_TESTS_PATH: &str = "tests/ui/error-codes/";
 
@@ -80,13 +80,14 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
         if line.starts_with('E') {
             let split_line = line.split_once(':');
 
-            // Extract the error code from the line, emitting a fatal error if it is not in a correct format.
+            // Extract the error code from the line. Emit a fatal error if it is not in the correct
+            // format.
             let err_code = if let Some(err_code) = split_line {
                 err_code.0.to_owned()
             } else {
                 errors.push(format!(
-                    "Expected a line with the format `Exxxx: include_str!(\"..\")`, but got \"{}\" \
-                    without a `:` delimiter",
+                    "Expected a line with the format `Eabcd: abcd, \
+                    but got \"{}\" without a `:` delimiter",
                     line,
                 ));
                 continue;
@@ -98,12 +99,16 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
                 continue;
             }
 
+            let mut chars = err_code.chars();
+            chars.next();
+            let error_num_as_str = chars.as_str();
+
             // Ensure that the line references the correct markdown file.
-            let expected_filename = format!(" include_str!(\"./error_codes/{}.md\"),", err_code);
+            let expected_filename = format!(" {},", error_num_as_str);
             if expected_filename != split_line.unwrap().1 {
                 errors.push(format!(
-                    "Error code `{}` expected to reference docs with `{}` but instead found `{}` in \
-                    `compiler/rustc_error_codes/src/error_codes.rs`",
+                    "`{}:` should be followed by `{}` but instead found `{}` in \
+                    `compiler/rustc_error_codes/src/lib.rs`",
                     err_code,
                     expected_filename,
                     split_line.unwrap().1,
@@ -311,13 +316,8 @@ fn check_error_codes_used(
     no_longer_emitted: &[String],
     verbose: bool,
 ) {
-    // We want error codes which match the following cases:
-    //
-    // * foo(a, E0111, a)
-    // * foo(a, E0111)
-    // * foo(E0111, a)
-    // * #[error = "E0111"]
-    let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();
+    // Search for error codes in the form `E0123`.
+    let regex = Regex::new(r#"\bE\d{4}\b"#).unwrap();
 
     let mut found_codes = Vec::new();
 
@@ -336,12 +336,12 @@ fn check_error_codes_used(
             }
 
             for cap in regex.captures_iter(line) {
-                if let Some(error_code) = cap.get(1) {
+                if let Some(error_code) = cap.get(0) {
                     let error_code = error_code.as_str().to_owned();
 
                     if !error_codes.contains(&error_code) {
                         // This error code isn't properly defined, we must error.
-                        errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/error_codes.rs`.", error_code));
+                        errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/lib.rs`.", error_code));
                         continue;
                     }
 
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 95cf9f8cb13..451276b5ac1 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -8,9 +8,12 @@ use std::ffi::OsStr;
 use std::fs;
 use std::path::{Path, PathBuf};
 
+// FIXME: GitHub's UI truncates file lists that exceed 1000 entries, so these
+// should all be 1000 or lower. Limits significantly smaller than 1000 are also
+// desirable, because large numbers of files are unwieldy in general. See issue
+// #73494.
 const ENTRY_LIMIT: usize = 900;
-// FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1849;
+const ISSUES_ENTRY_LIMIT: usize = 1807;
 const ROOT_ENTRY_LIMIT: usize = 870;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
@@ -24,9 +27,10 @@ const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
 
 const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
     "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint
-    "tests/ui/check-cfg/my-awesome-platform.json", // testing custom targets with cfgs
-    "tests/ui/commandline-argfile-badutf8.args", // passing args via a file
-    "tests/ui/commandline-argfile.args", // passing args via a file
+    "tests/ui/codegen/mismatched-data-layout.json", // testing mismatched data layout w/ custom targets
+    "tests/ui/check-cfg/my-awesome-platform.json",  // testing custom targets with cfgs
+    "tests/ui/commandline-argfile-badutf8.args",    // passing args via a file
+    "tests/ui/commandline-argfile.args",            // passing args via a file
     "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib
     "tests/ui/include-macros/data.bin", // testing including data with the include macros
     "tests/ui/include-macros/file.txt", // testing including data with the include macros
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index f6f2f5e88ff..41f5df0fba0 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -1,29 +1,5 @@
 // assembly-output: emit-asm
 // ignore-tidy-linelength
-// revisions: aarch64_apple_darwin
-// [aarch64_apple_darwin] compile-flags: --target aarch64-apple-darwin
-// [aarch64_apple_darwin] needs-llvm-components: aarch64
-// revisions: aarch64_apple_ios
-// [aarch64_apple_ios] compile-flags: --target aarch64-apple-ios
-// [aarch64_apple_ios] needs-llvm-components: aarch64
-// revisions: aarch64_apple_ios_macabi
-// [aarch64_apple_ios_macabi] compile-flags: --target aarch64-apple-ios-macabi
-// [aarch64_apple_ios_macabi] needs-llvm-components: aarch64
-// revisions: aarch64_apple_ios_sim
-// [aarch64_apple_ios_sim] compile-flags: --target aarch64-apple-ios-sim
-// [aarch64_apple_ios_sim] needs-llvm-components: aarch64
-// revisions: aarch64_apple_tvos
-// [aarch64_apple_tvos] compile-flags: --target aarch64-apple-tvos
-// [aarch64_apple_tvos] needs-llvm-components: aarch64
-// revisions: aarch64_apple_tvos_sim
-// [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
-// [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
-// revisions: aarch64_apple_watchos
-// [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
-// [aarch64_apple_watchos] needs-llvm-components: aarch64
-// revisions: aarch64_apple_watchos_sim
-// [aarch64_apple_watchos_sim] compile-flags: --target aarch64-apple-watchos-sim
-// [aarch64_apple_watchos_sim] needs-llvm-components: aarch64
 // revisions: aarch64_be_unknown_linux_gnu
 // [aarch64_be_unknown_linux_gnu] compile-flags: --target aarch64_be-unknown-linux-gnu
 // [aarch64_be_unknown_linux_gnu] needs-llvm-components: aarch64
@@ -93,15 +69,6 @@
 // revisions: aarch64_wrs_vxworks
 // [aarch64_wrs_vxworks] compile-flags: --target aarch64-wrs-vxworks
 // [aarch64_wrs_vxworks] needs-llvm-components: aarch64
-// revisions: arm64_32_apple_watchos
-// [arm64_32_apple_watchos] compile-flags: --target arm64_32-apple-watchos
-// [arm64_32_apple_watchos] needs-llvm-components: aarch64
-// revisions: arm64e_apple_darwin
-// [arm64e_apple_darwin] compile-flags: --target arm64e-apple-darwin
-// [arm64e_apple_darwin] needs-llvm-components: aarch64
-// revisions: arm64e_apple_ios
-// [arm64e_apple_ios] compile-flags: --target arm64e-apple-ios
-// [arm64e_apple_ios] needs-llvm-components: aarch64
 // revisions: arm_linux_androideabi
 // [arm_linux_androideabi] compile-flags: --target arm-linux-androideabi
 // [arm_linux_androideabi] needs-llvm-components: arm
@@ -201,18 +168,12 @@
 // revisions: armv7a_none_eabihf
 // [armv7a_none_eabihf] compile-flags: --target armv7a-none-eabihf
 // [armv7a_none_eabihf] needs-llvm-components: arm
-// revisions: armv7k_apple_watchos
-// [armv7k_apple_watchos] compile-flags: --target armv7k-apple-watchos
-// [armv7k_apple_watchos] needs-llvm-components: arm
 // revisions: armv7r_none_eabi
 // [armv7r_none_eabi] compile-flags: --target armv7r-none-eabi
 // [armv7r_none_eabi] needs-llvm-components: arm
 // revisions: armv7r_none_eabihf
 // [armv7r_none_eabihf] compile-flags: --target armv7r-none-eabihf
 // [armv7r_none_eabihf] needs-llvm-components: arm
-// revisions: armv7s_apple_ios
-// [armv7s_apple_ios] compile-flags: --target armv7s-apple-ios
-// [armv7s_apple_ios] needs-llvm-components: arm
 // FIXME: disabled since it fails on CI saying the csky component is missing
 /*
     revisions: csky_unknown_linux_gnuabiv2
@@ -228,9 +189,6 @@
 // revisions: hexagon_unknown_none_elf
 // [hexagon_unknown_none_elf] compile-flags: --target hexagon-unknown-none-elf
 // [hexagon_unknown_none_elf] needs-llvm-components: hexagon
-// revisions: i386_apple_ios
-// [i386_apple_ios] compile-flags: --target i386-apple-ios
-// [i386_apple_ios] needs-llvm-components: x86
 // revisions: i586_pc_nto_qnx700
 // [i586_pc_nto_qnx700] compile-flags: --target i586-pc-nto-qnx700
 // [i586_pc_nto_qnx700] needs-llvm-components: x86
@@ -243,9 +201,6 @@
 // revisions: i586_unknown_netbsd
 // [i586_unknown_netbsd] compile-flags: --target i586-unknown-netbsd
 // [i586_unknown_netbsd] needs-llvm-components: x86
-// revisions: i686_apple_darwin
-// [i686_apple_darwin] compile-flags: --target i686-apple-darwin
-// [i686_apple_darwin] needs-llvm-components: x86
 // revisions: i686_linux_android
 // [i686_linux_android] compile-flags: --target i686-linux-android
 // [i686_linux_android] needs-llvm-components: x86
@@ -534,24 +489,6 @@
 // revisions: wasm64_unknown_unknown
 // [wasm64_unknown_unknown] compile-flags: --target wasm64-unknown-unknown
 // [wasm64_unknown_unknown] needs-llvm-components: webassembly
-// revisions: wasm32_wasi_preview2
-// [wasm32_wasi_preview2] compile-flags: --target wasm32-wasi-preview2
-// [wasm32_wasi_preview2] needs-llvm-components: webassembly
-// revisions: x86_64_apple_darwin
-// [x86_64_apple_darwin] compile-flags: --target x86_64-apple-darwin
-// [x86_64_apple_darwin] needs-llvm-components: x86
-// revisions: x86_64_apple_ios
-// [x86_64_apple_ios] compile-flags: --target x86_64-apple-ios
-// [x86_64_apple_ios] needs-llvm-components: x86
-// revisions: x86_64_apple_ios_macabi
-// [x86_64_apple_ios_macabi] compile-flags: --target x86_64-apple-ios-macabi
-// [x86_64_apple_ios_macabi] needs-llvm-components: x86
-// revisions: x86_64_apple_tvos
-// [x86_64_apple_tvos] compile-flags: --target x86_64-apple-tvos
-// [x86_64_apple_tvos] needs-llvm-components: x86
-// revisions: x86_64_apple_watchos_sim
-// [x86_64_apple_watchos_sim] compile-flags: --target x86_64-apple-watchos-sim
-// [x86_64_apple_watchos_sim] needs-llvm-components: x86
 // revisions: x86_64_fortanix_unknown_sgx
 // [x86_64_fortanix_unknown_sgx] compile-flags: --target x86_64-fortanix-unknown-sgx
 // [x86_64_fortanix_unknown_sgx] needs-llvm-components: x86
@@ -618,9 +555,6 @@
 // revisions: x86_64_wrs_vxworks
 // [x86_64_wrs_vxworks] compile-flags: --target x86_64-wrs-vxworks
 // [x86_64_wrs_vxworks] needs-llvm-components: x86
-// revisions: x86_64h_apple_darwin
-// [x86_64h_apple_darwin] compile-flags: --target x86_64h-apple-darwin
-// [x86_64h_apple_darwin] needs-llvm-components: x86
 
 // Sanity-check that each target can produce assembly code.
 
@@ -636,4 +570,4 @@ pub fn test() -> u8 {
     42
 }
 
-// CHECK: .section
+// CHECK: .text
diff --git a/tests/assembly/targets/targets-macho.rs b/tests/assembly/targets/targets-macho.rs
new file mode 100644
index 00000000000..ead9ccfc8e7
--- /dev/null
+++ b/tests/assembly/targets/targets-macho.rs
@@ -0,0 +1,81 @@
+// assembly-output: emit-asm
+// ignore-tidy-linelength
+// revisions: aarch64_apple_darwin
+// [aarch64_apple_darwin] compile-flags: --target aarch64-apple-darwin
+// [aarch64_apple_darwin] needs-llvm-components: aarch64
+// revisions: aarch64_apple_ios
+// [aarch64_apple_ios] compile-flags: --target aarch64-apple-ios
+// [aarch64_apple_ios] needs-llvm-components: aarch64
+// revisions: aarch64_apple_ios_macabi
+// [aarch64_apple_ios_macabi] compile-flags: --target aarch64-apple-ios-macabi
+// [aarch64_apple_ios_macabi] needs-llvm-components: aarch64
+// revisions: aarch64_apple_ios_sim
+// [aarch64_apple_ios_sim] compile-flags: --target aarch64-apple-ios-sim
+// [aarch64_apple_ios_sim] needs-llvm-components: aarch64
+// revisions: aarch64_apple_tvos
+// [aarch64_apple_tvos] compile-flags: --target aarch64-apple-tvos
+// [aarch64_apple_tvos] needs-llvm-components: aarch64
+// revisions: aarch64_apple_tvos_sim
+// [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
+// [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
+// revisions: aarch64_apple_watchos
+// [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
+// [aarch64_apple_watchos] needs-llvm-components: aarch64
+// revisions: aarch64_apple_watchos_sim
+// [aarch64_apple_watchos_sim] compile-flags: --target aarch64-apple-watchos-sim
+// [aarch64_apple_watchos_sim] needs-llvm-components: aarch64
+// revisions: arm64_32_apple_watchos
+// [arm64_32_apple_watchos] compile-flags: --target arm64_32-apple-watchos
+// [arm64_32_apple_watchos] needs-llvm-components: aarch64
+// revisions: arm64e_apple_darwin
+// [arm64e_apple_darwin] compile-flags: --target arm64e-apple-darwin
+// [arm64e_apple_darwin] needs-llvm-components: aarch64
+// revisions: arm64e_apple_ios
+// [arm64e_apple_ios] compile-flags: --target arm64e-apple-ios
+// [arm64e_apple_ios] needs-llvm-components: aarch64
+// revisions: armv7k_apple_watchos
+// [armv7k_apple_watchos] compile-flags: --target armv7k-apple-watchos
+// [armv7k_apple_watchos] needs-llvm-components: arm
+// revisions: armv7s_apple_ios
+// [armv7s_apple_ios] compile-flags: --target armv7s-apple-ios
+// [armv7s_apple_ios] needs-llvm-components: arm
+// revisions: i386_apple_ios
+// [i386_apple_ios] compile-flags: --target i386-apple-ios
+// [i386_apple_ios] needs-llvm-components: x86
+// revisions: i686_apple_darwin
+// [i686_apple_darwin] compile-flags: --target i686-apple-darwin
+// [i686_apple_darwin] needs-llvm-components: x86
+// revisions: x86_64_apple_darwin
+// [x86_64_apple_darwin] compile-flags: --target x86_64-apple-darwin
+// [x86_64_apple_darwin] needs-llvm-components: x86
+// revisions: x86_64_apple_ios
+// [x86_64_apple_ios] compile-flags: --target x86_64-apple-ios
+// [x86_64_apple_ios] needs-llvm-components: x86
+// revisions: x86_64_apple_ios_macabi
+// [x86_64_apple_ios_macabi] compile-flags: --target x86_64-apple-ios-macabi
+// [x86_64_apple_ios_macabi] needs-llvm-components: x86
+// revisions: x86_64_apple_tvos
+// [x86_64_apple_tvos] compile-flags: --target x86_64-apple-tvos
+// [x86_64_apple_tvos] needs-llvm-components: x86
+// revisions: x86_64_apple_watchos_sim
+// [x86_64_apple_watchos_sim] compile-flags: --target x86_64-apple-watchos-sim
+// [x86_64_apple_watchos_sim] needs-llvm-components: x86
+// revisions: x86_64h_apple_darwin
+// [x86_64h_apple_darwin] compile-flags: --target x86_64h-apple-darwin
+// [x86_64h_apple_darwin] needs-llvm-components: x86
+
+// Sanity-check that each target can produce assembly code.
+
+#![feature(no_core, lang_items)]
+#![no_std]
+#![no_core]
+#![crate_type = "lib"]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub fn test() -> u8 {
+    42
+}
+
+// CHECK: .section __TEXT,__text
diff --git a/tests/codegen/infallible-unwrap-in-opt-z.rs b/tests/codegen/infallible-unwrap-in-opt-z.rs
index 5c57b41532f..e8ab77f8d20 100644
--- a/tests/codegen/infallible-unwrap-in-opt-z.rs
+++ b/tests/codegen/infallible-unwrap-in-opt-z.rs
@@ -21,6 +21,6 @@ pub fn read_up_to_8(buf: &[u8]) -> u64 {
 // CHECK-LABEL: @checking_unwrap_expectation(
 #[no_mangle]
 pub fn checking_unwrap_expectation(buf: &[u8]) -> &[u8; 4] {
-    // CHECK: call void @_ZN4core6result13unwrap_failed17h
+    // CHECK: call void @{{.*core6result13unwrap_failed}}
     buf.try_into().unwrap()
 }
diff --git a/tests/codegen/pow_of_two.rs b/tests/codegen/pow_of_two.rs
index a8c0550e332..372360dfd12 100644
--- a/tests/codegen/pow_of_two.rs
+++ b/tests/codegen/pow_of_two.rs
@@ -4,7 +4,7 @@
 #[no_mangle]
 pub fn a(exp: u32) -> u64 {
     // CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64
-    // CHECK: %{{[^ ]+}} = zext i32 %exp to i64
+    // CHECK: %{{[^ ]+}} = zext{{( nneg)?}} i32 %exp to i64
     // CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}}
     // CHECK: ret i64 %{{[^ ]+}}
     2u64.pow(exp)
@@ -14,7 +14,7 @@ pub fn a(exp: u32) -> u64 {
 #[no_mangle]
 pub fn b(exp: u32) -> i64 {
     // CHECK: %{{[^ ]+}} = icmp ugt i32 %exp, 64
-    // CHECK: %{{[^ ]+}} = zext i32 %exp to i64
+    // CHECK: %{{[^ ]+}} = zext{{( nneg)?}} i32 %exp to i64
     // CHECK: %{{[^ ]+}} = shl nuw i64 {{[^ ]+}}, %{{[^ ]+}}
     // CHECK: ret i64 %{{[^ ]+}}
     2i64.pow(exp)
diff --git a/tests/debuginfo/msvc-pretty-enums.rs b/tests/debuginfo/msvc-pretty-enums.rs
index d66e4c660f7..400e8801ca2 100644
--- a/tests/debuginfo/msvc-pretty-enums.rs
+++ b/tests/debuginfo/msvc-pretty-enums.rs
@@ -46,12 +46,12 @@
 // cdb-check:    [+0x000] __0              : 0x2a [Type: unsigned int]
 
 // cdb-command: dx niche128_some
-// cdb-check: niche128_some    : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// cdb-check: niche128_some    : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZero<i128> > >]
 // Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
-// cdb-check:    [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128]
+// cdb-check:    [+0x000] __0 [...] [Type: core::num::nonzero::NonZero<i128>]
 
 // cdb-command: dx niche128_none
-// cdb-check: niche128_none    : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// cdb-check: niche128_none    : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZero<i128> > >]
 
 // cdb-command: dx wrapping_niche128_untagged
 // cdb-check: wrapping_niche128_untagged : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
@@ -84,7 +84,7 @@
 
 // cdb-command: dx niche_w_fields_2_some,d
 // cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
-// cdb-check:     [+0x[...]] __0              : 800 [Type: core::num::nonzero::NonZeroU32]
+// cdb-check:     [+0x[...]] __0              : 800 [Type: core::num::nonzero::NonZero<u32>]
 // cdb-check:     [+0x[...]] __1              : 900 [Type: unsigned __int64]
 
 // cdb-command: dx niche_w_fields_2_none,d
diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs
index c122112e6c7..a1b5ae792a1 100644
--- a/tests/debuginfo/numeric-types.rs
+++ b/tests/debuginfo/numeric-types.rs
@@ -3,59 +3,59 @@
 // min-gdb-version: 8.1
 // ignore-windows-gnu // emit_debug_gdb_scripts is disabled on Windows
 
-// Tests the visualizations for `NonZero{I,U}{8,16,32,64,128,size}`, `Wrapping<T>` and
+// Tests the visualizations for `NonZero<T>`, `Wrapping<T>` and
 // `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`.
 
 // === CDB TESTS ==================================================================================
 // cdb-command: g
 
 // cdb-command: dx nz_i8
-// cdb-check:nz_i8            : 11 [Type: core::num::nonzero::NonZeroI8]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI8]
+// cdb-check:nz_i8            : 11 [Type: core::num::nonzero::NonZero<i8>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i8>]
 
 // cdb-command: dx nz_i16
-// cdb-check:nz_i16           : 22 [Type: core::num::nonzero::NonZeroI16]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI16]
+// cdb-check:nz_i16           : 22 [Type: core::num::nonzero::NonZero<i16>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i16>]
 
 // cdb-command: dx nz_i32
-// cdb-check:nz_i32           : 33 [Type: core::num::nonzero::NonZeroI32]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI32]
+// cdb-check:nz_i32           : 33 [Type: core::num::nonzero::NonZero<i32>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i32>]
 
 // cdb-command: dx nz_i64
-// cdb-check:nz_i64           : 44 [Type: core::num::nonzero::NonZeroI64]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI64]
+// cdb-check:nz_i64           : 44 [Type: core::num::nonzero::NonZero<i64>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i64>]
 
 // 128-bit integers don't seem to work in CDB
 // cdb-command: dx nz_i128
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI128]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i128>]
 
 // cdb-command: dx nz_isize
-// cdb-check:nz_isize         : 66 [Type: core::num::nonzero::NonZeroIsize]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroIsize]
+// cdb-check:nz_isize         : 66 [Type: core::num::nonzero::NonZero<isize>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<isize>]
 
 // cdb-command: dx nz_u8
-// cdb-check:nz_u8            : 0x4d [Type: core::num::nonzero::NonZeroU8]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU8]
+// cdb-check:nz_u8            : 0x4d [Type: core::num::nonzero::NonZero<u8>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u8>]
 
 // cdb-command: dx nz_u16
-// cdb-check:nz_u16           : 0x58 [Type: core::num::nonzero::NonZeroU16]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU16]
+// cdb-check:nz_u16           : 0x58 [Type: core::num::nonzero::NonZero<u16>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u16>]
 
 // cdb-command: dx nz_u32
-// cdb-check:nz_u32           : 0x63 [Type: core::num::nonzero::NonZeroU32]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU32]
+// cdb-check:nz_u32           : 0x63 [Type: core::num::nonzero::NonZero<u32>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u32>]
 
 // cdb-command: dx nz_u64
-// cdb-check:nz_u64           : 0x64 [Type: core::num::nonzero::NonZeroU64]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU64]
+// cdb-check:nz_u64           : 0x64 [Type: core::num::nonzero::NonZero<u64>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u64>]
 
 // 128-bit integers don't seem to work in CDB
 // cdb-command: dx nz_u128
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU128]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u128>]
 
 // cdb-command: dx nz_usize
-// cdb-check:nz_usize         : 0x7a [Type: core::num::nonzero::NonZeroUsize]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroUsize]
+// cdb-check:nz_usize         : 0x7a [Type: core::num::nonzero::NonZero<usize>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<usize>]
 
 // cdb-command: dx w_i8
 // cdb-check:w_i8             : 10 [Type: core::num::wrapping::Wrapping<i8>]
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
new file mode 100644
index 00000000000..0b6819ad483
--- /dev/null
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
@@ -0,0 +1,34 @@
+- // MIR for `f` before GVN
++ // MIR for `f` after GVN
+  
+  fn f() -> u32 {
+      let mut _0: u32;
+      let _1: u32;
+      let mut _2: E;
+      let mut _3: &U;
+      let _4: U;
+      scope 1 {
+          debug i => _1;
+      }
+      scope 2 {
+          let mut _5: &U;
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _5 = const _;
+          _3 = &(*_5);
+          _2 = ((*_3).1: E);
+          StorageLive(_1);
+-         _1 = ((_2 as A).1: u32);
++         _1 = const 0_u32;
+          StorageDead(_3);
+          StorageDead(_2);
+-         _0 = _1;
++         _0 = const 0_u32;
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..0b6819ad483
--- /dev/null
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
@@ -0,0 +1,34 @@
+- // MIR for `f` before GVN
++ // MIR for `f` after GVN
+  
+  fn f() -> u32 {
+      let mut _0: u32;
+      let _1: u32;
+      let mut _2: E;
+      let mut _3: &U;
+      let _4: U;
+      scope 1 {
+          debug i => _1;
+      }
+      scope 2 {
+          let mut _5: &U;
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _5 = const _;
+          _3 = &(*_5);
+          _2 = ((*_3).1: E);
+          StorageLive(_1);
+-         _1 = ((_2 as A).1: u32);
++         _1 = const 0_u32;
+          StorageDead(_3);
+          StorageDead(_2);
+-         _0 = _1;
++         _0 = const 0_u32;
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn_uninhabited.rs b/tests/mir-opt/gvn_uninhabited.rs
new file mode 100644
index 00000000000..a55b2dd763a
--- /dev/null
+++ b/tests/mir-opt/gvn_uninhabited.rs
@@ -0,0 +1,24 @@
+// unit-test: GVN
+// compile-flags: -O
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+// skip-filecheck
+
+#![feature(never_type)]
+
+#[derive(Copy, Clone)]
+pub enum E {
+    A(!, u32),
+}
+
+pub union U {
+    i: u32,
+    e: E,
+}
+
+// EMIT_MIR gvn_uninhabited.f.GVN.diff
+pub const fn f() -> u32 {
+    let E::A(_, i) = unsafe { (&U { i: 0 }).e };
+    i
+}
+
+fn main() {}
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
index 8e53427e7e0..a38b8246bde 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
@@ -36,7 +36,7 @@
 -         _4 = g() -> [return: bb1, unwind unreachable];
 +         _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)};
 +         _3 = &mut _4;
-+         _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: _3 };
++         _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 };
 +         StorageDead(_3);
 +         StorageLive(_5);
 +         _5 = const false;
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
index b06db41af9d..dc6628ab44c 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
@@ -36,7 +36,7 @@
 -         _4 = g() -> [return: bb1, unwind continue];
 +         _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)};
 +         _3 = &mut _4;
-+         _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: _3 };
++         _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 };
 +         StorageDead(_3);
 +         StorageLive(_5);
 +         _5 = const false;
diff --git a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff b/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff
index cb623e83f52..be7f9cd4412 100644
--- a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff
+++ b/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff
@@ -4,7 +4,7 @@
   fn adt_transmutes() -> () {
       let mut _0: ();
       let _1: u8;
-      let mut _2: std::option::Option<std::num::NonZeroU8>;
+      let mut _2: std::option::Option<std::num::NonZero<u8>>;
       let mut _4: std::num::Wrapping<i16>;
       let mut _6: std::num::Wrapping<i16>;
       let mut _8: Union32;
@@ -37,7 +37,7 @@
       bb0: {
           StorageLive(_1);
           StorageLive(_2);
-          _2 = Option::<NonZeroU8>::Some(const _);
+          _2 = Option::<NonZero<u8>>::Some(const _);
           _1 = move _2 as u8 (Transmute);
           StorageDead(_2);
           StorageLive(_3);
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
index 36329f8fc68..dc37c1b4cbf 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
@@ -42,7 +42,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
                                 debug self => _8;
                             }
                             scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
-                                debug data_address => _9;
+                                debug data_pointer => _9;
                                 debug metadata => _6;
                                 let mut _10: *const ();
                                 let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
@@ -90,7 +90,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         StorageLive(_11);
         StorageLive(_10);
         _10 = _9 as *const () (PointerCoercion(MutToConstPointer));
-        _11 = std::ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 };
+        _11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
         StorageDead(_10);
         _12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
         StorageDead(_11);
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
index 36329f8fc68..dc37c1b4cbf 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
@@ -42,7 +42,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
                                 debug self => _8;
                             }
                             scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
-                                debug data_address => _9;
+                                debug data_pointer => _9;
                                 debug metadata => _6;
                                 let mut _10: *const ();
                                 let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
@@ -90,7 +90,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         StorageLive(_11);
         StorageLive(_10);
         _10 = _9 as *const () (PointerCoercion(MutToConstPointer));
-        _11 = std::ptr::metadata::PtrComponents::<[u32]> { data_address: move _10, metadata: _6 };
+        _11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
         StorageDead(_10);
         _12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
         StorageDead(_11);
diff --git a/tests/pretty/delimited-token-groups.rs b/tests/pretty/delimited-token-groups.rs
index c7c9277faf6..b24c35bf081 100644
--- a/tests/pretty/delimited-token-groups.rs
+++ b/tests/pretty/delimited-token-groups.rs
@@ -9,7 +9,7 @@ mac! {
     {
         fn clone() -> S
         {
-            panic! () ;
+            panic! ();
 
         }
     }
diff --git a/tests/pretty/macro_rules.rs b/tests/pretty/macro_rules.rs
index 01adb14133b..a5265446ee7 100644
--- a/tests/pretty/macro_rules.rs
+++ b/tests/pretty/macro_rules.rs
@@ -1,19 +1,19 @@
 // pp-exact
 
-macro_rules! brace { () => {} ; }
+macro_rules! brace { () => {}; }
 
-macro_rules! bracket[() => {} ;];
+macro_rules! bracket[() => {};];
 
-macro_rules! paren(() => {} ;);
+macro_rules! paren(() => {};);
 
 macro_rules! matcher_brackets {
-    (paren) => {} ; (bracket) => {} ; (brace) => {} ;
+    (paren) => {}; (bracket) => {}; (brace) => {};
 }
 
 macro_rules! all_fragments {
     ($b : block, $e : expr, $i : ident, $it : item, $l : lifetime, $lit :
     literal, $m : meta, $p : pat, $pth : path, $s : stmt, $tt : tt, $ty : ty,
-    $vis : vis) => {} ;
+    $vis : vis) => {};
 }
 
 fn main() {}
diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs
index 052c45f2cb8..69b15317561 100644
--- a/tests/pretty/stmt_expr_attributes.rs
+++ b/tests/pretty/stmt_expr_attributes.rs
@@ -113,7 +113,7 @@ fn _8() {
 }
 
 fn _9() {
-    macro_rules! stmt_mac { () => { let _ = () ; } }
+    macro_rules! stmt_mac { () => { let _ = (); } }
 
     #[rustc_dummy]
     stmt_mac!();
diff --git a/tests/run-make/symbol-mangling-hashed/Makefile b/tests/run-make/symbol-mangling-hashed/Makefile
new file mode 100644
index 00000000000..68894b2192a
--- /dev/null
+++ b/tests/run-make/symbol-mangling-hashed/Makefile
@@ -0,0 +1,48 @@
+include ../tools.mk
+
+# ignore-cross-compile
+# only-linux
+# only-x86_64
+
+NM=nm -D
+RLIB_NAME=liba_rlib.rlib
+DYLIB_NAME=liba_dylib.so
+SO_NAME=libb_dylib.so
+BIN_NAME=b_bin
+
+ifeq ($(UNAME),Darwin)
+NM=nm -gU
+RLIB_NAME=liba_rlib.rlib
+DYLIB_NAME=liba_dylib.dylib
+SO_NAME=libb_dylib.dylib
+BIN_NAME=b_bin
+endif
+
+ifdef IS_WINDOWS
+NM=nm -g
+RLIB_NAME=liba_rlib.dll.a
+DYLIB_NAME=liba_dylib.dll
+SO_NAME=libb_dylib.dll
+BIN_NAME=b_bin.exe
+endif
+
+all:
+	$(RUSTC) -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=hashed -C metadata=foo a_dylib.rs
+	$(RUSTC) -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=hashed -C metadata=bar a_rlib.rs
+	$(RUSTC) -C prefer-dynamic -L $(TMPDIR) b_dylib.rs
+	$(RUSTC) -C prefer-dynamic -L $(TMPDIR) b_bin.rs
+
+    # Check hashed symbol name
+
+	[ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep -c hello)" -eq "0" ]
+	[ "$$($(NM) $(TMPDIR)/$(DYLIB_NAME) | grep _RNxC7a_dylib | grep -c ' T ')" -eq "1" ]
+
+	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep b_dylib | grep -c hello)" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC6a_rlib | grep -c ' T ')" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(SO_NAME) | grep _RNxC7a_dylib | grep -c ' U ')" -eq "1" ]
+
+	[ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep _RNxC6a_rlib | grep -c ' U ')" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep _RNxC7a_dylib | grep -c ' U ')" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(BIN_NAME) | grep b_dylib | grep hello | grep -c ' U ')" -eq "1" ]
+
+	$(call RUN,$(BIN_NAME))
diff --git a/tests/run-make/symbol-mangling-hashed/a_dylib.rs b/tests/run-make/symbol-mangling-hashed/a_dylib.rs
new file mode 100644
index 00000000000..8aec8fd82a5
--- /dev/null
+++ b/tests/run-make/symbol-mangling-hashed/a_dylib.rs
@@ -0,0 +1,4 @@
+#![crate_type="dylib"]
+pub fn hello() {
+    println!("hello dylib");
+}
diff --git a/tests/run-make/symbol-mangling-hashed/a_rlib.rs b/tests/run-make/symbol-mangling-hashed/a_rlib.rs
new file mode 100644
index 00000000000..873c86c5d0b
--- /dev/null
+++ b/tests/run-make/symbol-mangling-hashed/a_rlib.rs
@@ -0,0 +1,5 @@
+#![crate_type="rlib"]
+
+pub fn hello() {
+    println!("hello rlib");
+}
diff --git a/tests/run-make/symbol-mangling-hashed/b_bin.rs b/tests/run-make/symbol-mangling-hashed/b_bin.rs
new file mode 100644
index 00000000000..bcc53c37e12
--- /dev/null
+++ b/tests/run-make/symbol-mangling-hashed/b_bin.rs
@@ -0,0 +1,9 @@
+extern crate a_rlib;
+extern crate a_dylib;
+extern crate b_dylib;
+
+fn main() {
+    a_rlib::hello();
+    a_dylib::hello();
+    b_dylib::hello();
+}
diff --git a/tests/run-make/symbol-mangling-hashed/b_dylib.rs b/tests/run-make/symbol-mangling-hashed/b_dylib.rs
new file mode 100644
index 00000000000..c26a04b39ec
--- /dev/null
+++ b/tests/run-make/symbol-mangling-hashed/b_dylib.rs
@@ -0,0 +1,9 @@
+#![crate_type="dylib"]
+
+extern crate a_rlib;
+extern crate a_dylib;
+
+pub fn hello() {
+    a_rlib::hello();
+    a_dylib::hello();
+}
diff --git a/tests/run-make/target-specs/Makefile b/tests/run-make/target-specs/Makefile
index 62d5365a73d..161b6602185 100644
--- a/tests/run-make/target-specs/Makefile
+++ b/tests/run-make/target-specs/Makefile
@@ -9,4 +9,4 @@ all:
 	$(RUSTC) -Z unstable-options --target=my-awesome-platform.json --print target-spec-json > $(TMPDIR)/test-platform.json && $(RUSTC) -Z unstable-options --target=$(TMPDIR)/test-platform.json --print target-spec-json | diff -q $(TMPDIR)/test-platform.json -
 	$(RUSTC) foo.rs --target=definitely-not-builtin-target 2>&1 | $(CGREP) 'may not set is_builtin'
 	$(RUSTC) foo.rs --target=endianness-mismatch 2>&1 | $(CGREP) '"data-layout" claims architecture is little-endian'
-	$(RUSTC) foo.rs --target=mismatching-data-layout --crate-type=lib
+	$(RUSTC) foo.rs --target=mismatching-data-layout --crate-type=lib 2>&1 | $(CGREP) 'data-layout for target'
diff --git a/tests/rustdoc/footnote-definition-without-blank-line-100638.rs b/tests/rustdoc/footnote-definition-without-blank-line-100638.rs
new file mode 100644
index 00000000000..b6f62c3bcba
--- /dev/null
+++ b/tests/rustdoc/footnote-definition-without-blank-line-100638.rs
@@ -0,0 +1,15 @@
+#![crate_name = "foo"]
+
+//! Reference to footnotes A[^1], B[^2] and C[^3].
+//!
+//! [^1]: Footnote A.
+//! [^2]: Footnote B.
+//! [^3]: Footnote C.
+
+// @has 'foo/index.html'
+// @has - '//*[@class="docblock"]/*[@class="footnotes"]/ol/li[@id="fn1"]/p' 'Footnote A'
+// @has - '//li[@id="fn1"]/p/a/@href' '#fnref1'
+// @has - '//*[@class="docblock"]/*[@class="footnotes"]/ol/li[@id="fn2"]/p' 'Footnote B'
+// @has - '//li[@id="fn2"]/p/a/@href' '#fnref2'
+// @has - '//*[@class="docblock"]/*[@class="footnotes"]/ol/li[@id="fn3"]/p' 'Footnote C'
+// @has - '//li[@id="fn3"]/p/a/@href' '#fnref3'
diff --git a/tests/ui-fulldeps/internal-lints/query_stability.rs b/tests/ui-fulldeps/internal-lints/query_stability.rs
index 560675b4486..627ffa5cbd0 100644
--- a/tests/ui-fulldeps/internal-lints/query_stability.rs
+++ b/tests/ui-fulldeps/internal-lints/query_stability.rs
@@ -21,4 +21,17 @@ fn main() {
 
     for _ in x {}
     //~^ ERROR using `into_iter`
+
+    let x = FxHashMap::<u32, i32>::default();
+    let _ = x.keys();
+    //~^ ERROR using `keys` can result in unstable query results
+
+    let _ = x.values();
+    //~^ ERROR using `values` can result in unstable query results
+
+    let mut x = FxHashMap::<u32, i32>::default();
+    for val in x.values_mut() {
+        //~^ ERROR using `values_mut` can result in unstable query results
+        *val = *val + 10;
+    }
 }
diff --git a/tests/ui-fulldeps/internal-lints/query_stability.stderr b/tests/ui-fulldeps/internal-lints/query_stability.stderr
index ee4ef998237..43b156dc20a 100644
--- a/tests/ui-fulldeps/internal-lints/query_stability.stderr
+++ b/tests/ui-fulldeps/internal-lints/query_stability.stderr
@@ -35,5 +35,29 @@ LL |     for _ in x {}
    |
    = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
-error: aborting due to 4 previous errors
+error: using `keys` can result in unstable query results
+  --> $DIR/query_stability.rs:26:15
+   |
+LL |     let _ = x.keys();
+   |               ^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: using `values` can result in unstable query results
+  --> $DIR/query_stability.rs:29:15
+   |
+LL |     let _ = x.values();
+   |               ^^^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: using `values_mut` can result in unstable query results
+  --> $DIR/query_stability.rs:33:18
+   |
+LL |     for val in x.values_mut() {
+   |                  ^^^^^^^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index f553aa96505..d3cfd28082d 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -25,22 +25,26 @@ extern crate rustc_middle;
 use rustc_middle::ty::Ty;
 
 extern crate rustc_errors;
-use rustc_errors::{Applicability, DiagnosticMessage, MultiSpan, SubdiagnosticMessage};
+use rustc_errors::{Applicability, DiagnosticMessage, ErrCode, MultiSpan, SubdiagnosticMessage};
 
 extern crate rustc_session;
 
 rustc_fluent_macro::fluent_messages! { "./example.ftl" }
 
+// E0123 and E0456 are no longer used, so we define our own constants here just for this test.
+const E0123: ErrCode = ErrCode::from_u32(0123);
+const E0456: ErrCode = ErrCode::from_u32(0456);
+
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct Hello {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct HelloWarn {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 //~^ ERROR unsupported type attribute for diagnostic derive enum
 enum DiagnosticOnEnum {
     Foo,
@@ -50,53 +54,53 @@ enum DiagnosticOnEnum {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[diag = "E0123"]
 //~^ ERROR failed to resolve: maybe a missing crate `core`
 struct WrongStructAttrStyle {}
 
 #[derive(Diagnostic)]
-#[nonsense(no_crate_example, code = "E0123")]
+#[nonsense(no_crate_example, code = E0123)]
 //~^ ERROR `#[nonsense(...)]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 //~^^^ ERROR cannot find attribute `nonsense` in this scope
 struct InvalidStructAttr {}
 
 #[derive(Diagnostic)]
-#[diag("E0123")]
+#[diag(code = E0123)]
 //~^ ERROR diagnostic slug not specified
 struct InvalidLitNestedAttr {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense, code = "E0123")]
+#[diag(nonsense, code = E0123)]
 //~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated`
 struct InvalidNestedStructAttr {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+#[diag(nonsense("foo"), code = E0123, slug = "foo")]
 //~^ ERROR diagnostic slug must be the first argument
 //~| ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr1 {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense = "...", code = "E0123", slug = "foo")]
+#[diag(nonsense = "...", code = E0123, slug = "foo")]
 //~^ ERROR unknown argument
 //~| ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr2 {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense = 4, code = "E0123", slug = "foo")]
+#[diag(nonsense = 4, code = E0123, slug = "foo")]
 //~^ ERROR unknown argument
 //~| ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr3 {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123", slug = "foo")]
+#[diag(no_crate_example, code = E0123, slug = "foo")]
 //~^ ERROR unknown argument
 struct InvalidNestedStructAttr4 {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct WrongPlaceField {
     #[suggestion = "bar"]
     //~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -104,19 +108,19 @@ struct WrongPlaceField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
-#[diag(no_crate_example, code = "E0456")]
+#[diag(no_crate_example, code = E0123)]
+#[diag(no_crate_example, code = E0456)]
 //~^ ERROR specified multiple times
 //~^^ ERROR specified multiple times
 struct DiagSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0456", code = "E0457")]
+#[diag(no_crate_example, code = E0123, code = E0456)]
 //~^ ERROR specified multiple times
 struct CodeSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, no_crate::example, code = "E0456")]
+#[diag(no_crate_example, no_crate::example, code = E0123)]
 //~^ ERROR diagnostic slug must be the first argument
 struct SlugSpecifiedTwice {}
 
@@ -124,7 +128,7 @@ struct SlugSpecifiedTwice {}
 struct KindNotProvided {} //~ ERROR diagnostic slug not specified
 
 #[derive(Diagnostic)]
-#[diag(code = "E0456")]
+#[diag(code = E0123)]
 //~^ ERROR diagnostic slug not specified
 struct SlugNotProvided {}
 
@@ -133,7 +137,7 @@ struct SlugNotProvided {}
 struct CodeNotProvided {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct MessageWrongType {
     #[primary_span]
     //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -141,7 +145,7 @@ struct MessageWrongType {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct InvalidPathFieldAttr {
     #[nonsense]
     //~^ ERROR `#[nonsense]` is not a valid attribute
@@ -150,7 +154,7 @@ struct InvalidPathFieldAttr {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithField {
     name: String,
     #[label(no_crate_label)]
@@ -158,7 +162,7 @@ struct ErrorWithField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithMessageAppliedToField {
     #[label(no_crate_label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -166,7 +170,7 @@ struct ErrorWithMessageAppliedToField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithNonexistentField {
     #[suggestion(no_crate_suggestion, code = "{name}")]
     //~^ ERROR `name` doesn't refer to a field on this type
@@ -175,7 +179,7 @@ struct ErrorWithNonexistentField {
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: expected `'}'`
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorMissingClosingBrace {
     #[suggestion(no_crate_suggestion, code = "{name")]
     suggestion: (Span, Applicability),
@@ -185,7 +189,7 @@ struct ErrorMissingClosingBrace {
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: unmatched `}`
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorMissingOpeningBrace {
     #[suggestion(no_crate_suggestion, code = "name}")]
     suggestion: (Span, Applicability),
@@ -194,14 +198,14 @@ struct ErrorMissingOpeningBrace {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelOnSpan {
     #[label(no_crate_label)]
     sp: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelOnNonSpan {
     #[label(no_crate_label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -209,7 +213,7 @@ struct LabelOnNonSpan {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct Suggest {
     #[suggestion(no_crate_suggestion, code = "This is the suggested code")]
     #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "normal")]
@@ -220,7 +224,7 @@ struct Suggest {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithoutCode {
     #[suggestion(no_crate_suggestion)]
     //~^ ERROR suggestion without `code = "..."`
@@ -228,7 +232,7 @@ struct SuggestWithoutCode {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithBadKey {
     #[suggestion(nonsense = "bar")]
     //~^ ERROR invalid nested attribute
@@ -237,7 +241,7 @@ struct SuggestWithBadKey {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithShorthandMsg {
     #[suggestion(msg = "bar")]
     //~^ ERROR invalid nested attribute
@@ -246,21 +250,21 @@ struct SuggestWithShorthandMsg {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithoutMsg {
     #[suggestion(code = "bar")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithTypesSwapped {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Span),
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithWrongTypeApplicabilityOnly {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     //~^ ERROR wrong field type for suggestion
@@ -268,14 +272,14 @@ struct SuggestWithWrongTypeApplicabilityOnly {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithSpanOnly {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithDuplicateSpanAndApplicability {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Span, Span, Applicability),
@@ -283,7 +287,7 @@ struct SuggestWithDuplicateSpanAndApplicability {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithDuplicateApplicabilityAndSpan {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Applicability, Span),
@@ -291,7 +295,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct WrongKindOfAnnotation {
     #[label = "bar"]
     //~^ ERROR `#[label = ...]` is not a valid attribute
@@ -299,7 +303,7 @@ struct WrongKindOfAnnotation {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct OptionsInErrors {
     #[label(no_crate_label)]
     label: Option<Span>,
@@ -308,7 +312,7 @@ struct OptionsInErrors {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0456")]
+#[diag(no_crate_example, code = E0123)]
 struct MoveOutOfBorrowError<'tcx> {
     name: Ident,
     ty: Ty<'tcx>,
@@ -322,7 +326,7 @@ struct MoveOutOfBorrowError<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithLifetime<'a> {
     #[label(no_crate_label)]
     span: Span,
@@ -330,7 +334,7 @@ struct ErrorWithLifetime<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithDefaultLabelAttr<'a> {
     #[label]
     span: Span,
@@ -338,7 +342,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ArgFieldWithoutSkip {
     #[primary_span]
     span: Span,
@@ -347,7 +351,7 @@ struct ArgFieldWithoutSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ArgFieldWithSkip {
     #[primary_span]
     span: Span,
@@ -358,56 +362,56 @@ struct ArgFieldWithSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedNote {
     #[note]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedNoteCustom {
     #[note(no_crate_note)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[note]
 struct ErrorWithNote {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[note(no_crate_note)]
 struct ErrorWithNoteCustom {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedHelp {
     #[help]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedHelpCustom {
     #[help(no_crate_help)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[help]
 struct ErrorWithHelp {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[help(no_crate_help)]
 struct ErrorWithHelpCustom {
     val: String,
@@ -415,34 +419,34 @@ struct ErrorWithHelpCustom {
 
 #[derive(Diagnostic)]
 #[help]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithHelpWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[help(no_crate_help)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithHelpCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[note]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithNoteWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[note(no_crate_note)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithNoteCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ApplicabilityInBoth {
     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
     //~^ ERROR specified multiple times
@@ -450,7 +454,7 @@ struct ApplicabilityInBoth {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct InvalidApplicability {
     #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")]
     //~^ ERROR invalid applicability
@@ -458,14 +462,14 @@ struct InvalidApplicability {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ValidApplicability {
     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct NoApplicability {
     #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: Span,
@@ -483,7 +487,7 @@ struct Subdiagnostic {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct VecField {
     #[primary_span]
     #[label]
@@ -491,7 +495,7 @@ struct VecField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct UnitField {
     #[primary_span]
     spans: Span,
@@ -502,7 +506,7 @@ struct UnitField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct OptUnitField {
     #[primary_span]
     spans: Span,
@@ -526,7 +530,7 @@ struct BoolField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelWithTrailingPath {
     #[label(no_crate_label, foo)]
     //~^ ERROR a diagnostic slug must be the first argument to the attribute
@@ -534,7 +538,7 @@ struct LabelWithTrailingPath {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelWithTrailingNameValue {
     #[label(no_crate_label, foo = "...")]
     //~^ ERROR only `no_span` is a valid nested attribute
@@ -542,7 +546,7 @@ struct LabelWithTrailingNameValue {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelWithTrailingList {
     #[label(no_crate_label, foo("..."))]
     //~^ ERROR only `no_span` is a valid nested attribute
@@ -562,42 +566,42 @@ struct PrimarySpanOnLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithMultiSpan {
     #[primary_span]
     span: MultiSpan,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[warning]
 struct ErrorWithWarn {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[error(no_crate_example, code = "E0123")]
+#[error(no_crate_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_(no_crate_example, code = "E0123")]
+#[warn_(no_crate_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(no_crate_example, code = "E0123")]
+#[lint(no_crate_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(no_crate_example, code = "E0123")]
+#[lint(no_crate_example, code = E0123)]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
@@ -605,7 +609,7 @@ struct LintAttributeOnSessionDiag {}
 struct LintAttributeOnLintDiag {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct DuplicatedSuggestionCode {
     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
     //~^ ERROR specified multiple times
@@ -613,7 +617,7 @@ struct DuplicatedSuggestionCode {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct InvalidTypeInSuggestionTuple {
     #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: (Span, usize),
@@ -621,7 +625,7 @@ struct InvalidTypeInSuggestionTuple {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct MissingApplicabilityInSuggestionTuple {
     #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: (Span,),
@@ -629,7 +633,7 @@ struct MissingApplicabilityInSuggestionTuple {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct MissingCodeInSuggestion {
     #[suggestion(no_crate_suggestion)]
     //~^ ERROR suggestion without `code = "..."`
@@ -637,7 +641,7 @@ struct MissingCodeInSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[multipart_suggestion(no_crate_suggestion)]
 //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
 //~| ERROR cannot find attribute `multipart_suggestion` in this scope
@@ -652,7 +656,7 @@ struct MultipartSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[suggestion(no_crate_suggestion, code = "...")]
 //~^ ERROR `#[suggestion(...)]` is not a valid attribute
 struct SuggestionOnStruct {
@@ -661,7 +665,7 @@ struct SuggestionOnStruct {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[label]
 //~^ ERROR `#[label]` is not a valid attribute
 struct LabelOnStruct {
@@ -688,7 +692,7 @@ enum ExampleEnum {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct RawIdentDiagnosticArg {
     pub r#type: String,
 }
@@ -762,7 +766,7 @@ struct SubdiagnosticEagerSuggestion {
 
 /// with a doc comment on the type..
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct WithDocComment {
     /// ..and the field
     #[primary_span]
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index f376c034587..67257c28b6e 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,11 +1,11 @@
 error: unsupported type attribute for diagnostic derive enum
-  --> $DIR/diagnostic-derive.rs:43:1
+  --> $DIR/diagnostic-derive.rs:47:1
    |
-LL | #[diag(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:46:5
+  --> $DIR/diagnostic-derive.rs:50:5
    |
 LL |     Foo,
    |     ^^^
@@ -13,7 +13,7 @@ LL |     Foo,
    = 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:48:5
+  --> $DIR/diagnostic-derive.rs:52:5
    |
 LL |     Bar,
    |     ^^^
@@ -21,15 +21,15 @@ LL |     Bar,
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[nonsense(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:59:1
+  --> $DIR/diagnostic-derive.rs:63:1
    |
-LL | #[nonsense(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[nonsense(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:59:1
+  --> $DIR/diagnostic-derive.rs:63:1
    |
-LL | / #[nonsense(no_crate_example, code = "E0123")]
+LL | / #[nonsense(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -39,9 +39,9 @@ LL | | struct InvalidStructAttr {}
    = 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:66:1
+  --> $DIR/diagnostic-derive.rs:70:1
    |
-LL | / #[diag("E0123")]
+LL | / #[diag(code = E0123)]
 LL | |
 LL | | struct InvalidLitNestedAttr {}
    | |______________________________^
@@ -49,15 +49,15 @@ LL | | struct InvalidLitNestedAttr {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug must be the first argument
-  --> $DIR/diagnostic-derive.rs:76:16
+  --> $DIR/diagnostic-derive.rs:80:16
    |
-LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")]
    |                ^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:76:1
+  --> $DIR/diagnostic-derive.rs:80:1
    |
-LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense("foo"), code = E0123, slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr1 {}
@@ -66,17 +66,17 @@ LL | | struct InvalidNestedStructAttr1 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: unknown argument
-  --> $DIR/diagnostic-derive.rs:82:8
+  --> $DIR/diagnostic-derive.rs:86:8
    |
-LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+LL | #[diag(nonsense = "...", code = E0123, slug = "foo")]
    |        ^^^^^^^^
    |
    = note: only the `code` parameter is valid after the slug
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:82:1
+  --> $DIR/diagnostic-derive.rs:86:1
    |
-LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = "...", code = E0123, slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr2 {}
@@ -85,17 +85,17 @@ LL | | struct InvalidNestedStructAttr2 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: unknown argument
-  --> $DIR/diagnostic-derive.rs:88:8
+  --> $DIR/diagnostic-derive.rs:92:8
    |
-LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+LL | #[diag(nonsense = 4, code = E0123, slug = "foo")]
    |        ^^^^^^^^
    |
    = note: only the `code` parameter is valid after the slug
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:88:1
+  --> $DIR/diagnostic-derive.rs:92:1
    |
-LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = 4, code = E0123, slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr3 {}
@@ -104,63 +104,63 @@ LL | | struct InvalidNestedStructAttr3 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: unknown argument
-  --> $DIR/diagnostic-derive.rs:94:42
+  --> $DIR/diagnostic-derive.rs:98:40
    |
-LL | #[diag(no_crate_example, code = "E0123", slug = "foo")]
-   |                                          ^^^^
+LL | #[diag(no_crate_example, code = E0123, slug = "foo")]
+   |                                        ^^^^
    |
    = note: only the `code` parameter is valid after the slug
 
 error: `#[suggestion = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:101:5
+  --> $DIR/diagnostic-derive.rs:105:5
    |
 LL |     #[suggestion = "bar"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:108:8
+  --> $DIR/diagnostic-derive.rs:112:8
    |
-LL | #[diag(no_crate_example, code = "E0456")]
+LL | #[diag(no_crate_example, code = E0456)]
    |        ^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:107:8
+  --> $DIR/diagnostic-derive.rs:111:8
    |
-LL | #[diag(no_crate_example, code = "E0123")]
+LL | #[diag(no_crate_example, code = E0123)]
    |        ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:108:26
+  --> $DIR/diagnostic-derive.rs:112:26
    |
-LL | #[diag(no_crate_example, code = "E0456")]
+LL | #[diag(no_crate_example, code = E0456)]
    |                          ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:107:26
+  --> $DIR/diagnostic-derive.rs:111:26
    |
-LL | #[diag(no_crate_example, code = "E0123")]
+LL | #[diag(no_crate_example, code = E0123)]
    |                          ^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:114:42
+  --> $DIR/diagnostic-derive.rs:118:40
    |
-LL | #[diag(no_crate_example, code = "E0456", code = "E0457")]
-   |                                          ^^^^
+LL | #[diag(no_crate_example, code = E0123, code = E0456)]
+   |                                        ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:114:26
+  --> $DIR/diagnostic-derive.rs:118:26
    |
-LL | #[diag(no_crate_example, code = "E0456", code = "E0457")]
+LL | #[diag(no_crate_example, code = E0123, code = E0456)]
    |                          ^^^^
 
 error: diagnostic slug must be the first argument
-  --> $DIR/diagnostic-derive.rs:119:43
+  --> $DIR/diagnostic-derive.rs:123:43
    |
-LL | #[diag(no_crate_example, no_crate::example, code = "E0456")]
+LL | #[diag(no_crate_example, no_crate::example, code = E0123)]
    |                                           ^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:124:1
+  --> $DIR/diagnostic-derive.rs:128:1
    |
 LL | struct KindNotProvided {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,9 +168,9 @@ LL | struct KindNotProvided {}
    = 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:127:1
+  --> $DIR/diagnostic-derive.rs:131:1
    |
-LL | / #[diag(code = "E0456")]
+LL | / #[diag(code = E0123)]
 LL | |
 LL | | struct SlugNotProvided {}
    | |_________________________^
@@ -178,31 +178,31 @@ LL | | struct SlugNotProvided {}
    = 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:138:5
+  --> $DIR/diagnostic-derive.rs:142:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
 
 error: `#[nonsense]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:146:5
+  --> $DIR/diagnostic-derive.rs:150:5
    |
 LL |     #[nonsense]
    |     ^^^^^^^^^^^
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:163:5
+  --> $DIR/diagnostic-derive.rs:167:5
    |
 LL |     #[label(no_crate_label)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `name` doesn't refer to a field on this type
-  --> $DIR/diagnostic-derive.rs:171:46
+  --> $DIR/diagnostic-derive.rs:175:46
    |
 LL |     #[suggestion(no_crate_suggestion, code = "{name}")]
    |                                              ^^^^^^^^
 
 error: invalid format string: expected `'}'` but string was terminated
-  --> $DIR/diagnostic-derive.rs:176:10
+  --> $DIR/diagnostic-derive.rs:180:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ expected `'}'` in format string
@@ -211,7 +211,7 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid format string: unmatched `}` found
-  --> $DIR/diagnostic-derive.rs:186:10
+  --> $DIR/diagnostic-derive.rs:190:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ unmatched `}` in format string
@@ -220,19 +220,19 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:206:5
+  --> $DIR/diagnostic-derive.rs:210:5
    |
 LL |     #[label(no_crate_label)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:225:5
+  --> $DIR/diagnostic-derive.rs:229:5
    |
 LL |     #[suggestion(no_crate_suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid nested attribute
-  --> $DIR/diagnostic-derive.rs:233:18
+  --> $DIR/diagnostic-derive.rs:237:18
    |
 LL |     #[suggestion(nonsense = "bar")]
    |                  ^^^^^^^^
@@ -240,13 +240,13 @@ LL |     #[suggestion(nonsense = "bar")]
    = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:233:5
+  --> $DIR/diagnostic-derive.rs:237:5
    |
 LL |     #[suggestion(nonsense = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid nested attribute
-  --> $DIR/diagnostic-derive.rs:242:18
+  --> $DIR/diagnostic-derive.rs:246:18
    |
 LL |     #[suggestion(msg = "bar")]
    |                  ^^^
@@ -254,13 +254,13 @@ LL |     #[suggestion(msg = "bar")]
    = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:242:5
+  --> $DIR/diagnostic-derive.rs:246:5
    |
 LL |     #[suggestion(msg = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: wrong field type for suggestion
-  --> $DIR/diagnostic-derive.rs:265:5
+  --> $DIR/diagnostic-derive.rs:269:5
    |
 LL | /     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
 LL | |
@@ -270,79 +270,79 @@ LL | |     suggestion: Applicability,
    = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:281:24
+  --> $DIR/diagnostic-derive.rs:285:24
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                        ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:281:18
+  --> $DIR/diagnostic-derive.rs:285:18
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                  ^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:289:33
+  --> $DIR/diagnostic-derive.rs:293:33
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                                 ^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:289:18
+  --> $DIR/diagnostic-derive.rs:293:18
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                  ^^^^^^^^^^^^^
 
 error: `#[label = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:296:5
+  --> $DIR/diagnostic-derive.rs:300:5
    |
 LL |     #[label = "bar"]
    |     ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:447:5
+  --> $DIR/diagnostic-derive.rs:451:5
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:449:24
+  --> $DIR/diagnostic-derive.rs:453:24
    |
 LL |     suggestion: (Span, Applicability),
    |                        ^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/diagnostic-derive.rs:455:69
+  --> $DIR/diagnostic-derive.rs:459:69
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")]
    |                                                                     ^^^^^^^^
 
 error: the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()`
-  --> $DIR/diagnostic-derive.rs:522:5
+  --> $DIR/diagnostic-derive.rs:526:5
    |
 LL |     #[help(no_crate_help)]
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: a diagnostic slug must be the first argument to the attribute
-  --> $DIR/diagnostic-derive.rs:531:32
+  --> $DIR/diagnostic-derive.rs:535:32
    |
 LL |     #[label(no_crate_label, foo)]
    |                                ^
 
 error: only `no_span` is a valid nested attribute
-  --> $DIR/diagnostic-derive.rs:539:29
+  --> $DIR/diagnostic-derive.rs:543:29
    |
 LL |     #[label(no_crate_label, foo = "...")]
    |                             ^^^
 
 error: only `no_span` is a valid nested attribute
-  --> $DIR/diagnostic-derive.rs:547:29
+  --> $DIR/diagnostic-derive.rs:551:29
    |
 LL |     #[label(no_crate_label, foo("..."))]
    |                             ^^^
 
 error: `#[primary_span]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:559:5
+  --> $DIR/diagnostic-derive.rs:563:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
@@ -350,15 +350,15 @@ LL |     #[primary_span]
    = help: the `primary_span` field attribute is not valid for lint diagnostics
 
 error: `#[error(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:579:1
+  --> $DIR/diagnostic-derive.rs:583:1
    |
-LL | #[error(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:579:1
+  --> $DIR/diagnostic-derive.rs:583:1
    |
-LL | / #[error(no_crate_example, code = "E0123")]
+LL | / #[error(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -368,15 +368,15 @@ LL | | struct ErrorAttribute {}
    = 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:586:1
+  --> $DIR/diagnostic-derive.rs:590:1
    |
-LL | #[warn_(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[warn_(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:586:1
+  --> $DIR/diagnostic-derive.rs:590:1
    |
-LL | / #[warn_(no_crate_example, code = "E0123")]
+LL | / #[warn_(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -386,15 +386,15 @@ LL | | struct WarnAttribute {}
    = 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:593:1
+  --> $DIR/diagnostic-derive.rs:597:1
    |
-LL | #[lint(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:593:1
+  --> $DIR/diagnostic-derive.rs:597:1
    |
-LL | / #[lint(no_crate_example, code = "E0123")]
+LL | / #[lint(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -404,23 +404,23 @@ LL | | struct LintAttributeOnSessionDiag {}
    = 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:600:1
+  --> $DIR/diagnostic-derive.rs:604:1
    |
-LL | #[lint(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:600:1
+  --> $DIR/diagnostic-derive.rs:604:1
    |
-LL | #[lint(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:600:1
+  --> $DIR/diagnostic-derive.rs:604:1
    |
-LL | / #[lint(no_crate_example, code = "E0123")]
+LL | / #[lint(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -431,19 +431,19 @@ LL | | struct LintAttributeOnLintDiag {}
    = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:610:53
+  --> $DIR/diagnostic-derive.rs:614:53
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
    |                                                     ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:610:39
+  --> $DIR/diagnostic-derive.rs:614:39
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
    |                                       ^^^^
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:619:24
+  --> $DIR/diagnostic-derive.rs:623:24
    |
 LL |     suggestion: (Span, usize),
    |                        ^^^^^
@@ -451,7 +451,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:627:17
+  --> $DIR/diagnostic-derive.rs:631:17
    |
 LL |     suggestion: (Span,),
    |                 ^^^^^^^
@@ -459,13 +459,13 @@ 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:634:5
+  --> $DIR/diagnostic-derive.rs:638:5
    |
 LL |     #[suggestion(no_crate_suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:641:1
+  --> $DIR/diagnostic-derive.rs:645:1
    |
 LL | #[multipart_suggestion(no_crate_suggestion)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -473,7 +473,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:644:1
+  --> $DIR/diagnostic-derive.rs:648:1
    |
 LL | #[multipart_suggestion()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -481,7 +481,7 @@ LL | #[multipart_suggestion()]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:648:5
+  --> $DIR/diagnostic-derive.rs:652:5
    |
 LL |     #[multipart_suggestion(no_crate_suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -489,7 +489,7 @@ LL |     #[multipart_suggestion(no_crate_suggestion)]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:656:1
+  --> $DIR/diagnostic-derive.rs:660:1
    |
 LL | #[suggestion(no_crate_suggestion, code = "...")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -497,7 +497,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")]
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `#[label]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:665:1
+  --> $DIR/diagnostic-derive.rs:669:1
    |
 LL | #[label]
    | ^^^^^^^^
@@ -505,31 +505,31 @@ LL | #[label]
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `eager` is the only supported nested attribute for `subdiagnostic`
-  --> $DIR/diagnostic-derive.rs:699:7
+  --> $DIR/diagnostic-derive.rs:703:7
    |
 LL |     #[subdiagnostic(bad)]
    |       ^^^^^^^^^^^^^^^^^^
 
 error: `#[subdiagnostic = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:707:5
+  --> $DIR/diagnostic-derive.rs:711:5
    |
 LL |     #[subdiagnostic = "bad"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `eager` is the only supported nested attribute for `subdiagnostic`
-  --> $DIR/diagnostic-derive.rs:715:7
+  --> $DIR/diagnostic-derive.rs:719:7
    |
 LL |     #[subdiagnostic(bad, bad)]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `eager` is the only supported nested attribute for `subdiagnostic`
-  --> $DIR/diagnostic-derive.rs:723:7
+  --> $DIR/diagnostic-derive.rs:727:7
    |
 LL |     #[subdiagnostic("bad")]
    |       ^^^^^^^^^^^^^^^^^^^^
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:731:5
+  --> $DIR/diagnostic-derive.rs:735:5
    |
 LL |     #[subdiagnostic(eager)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -537,19 +537,19 @@ LL |     #[subdiagnostic(eager)]
    = help: eager subdiagnostics are not supported on lints
 
 error: expected at least one string literal for `code(...)`
-  --> $DIR/diagnostic-derive.rs:789:23
+  --> $DIR/diagnostic-derive.rs:793:23
    |
 LL |     #[suggestion(code())]
    |                       ^
 
 error: `code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:797:23
+  --> $DIR/diagnostic-derive.rs:801:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:821:5
+  --> $DIR/diagnostic-derive.rs:825:5
    |
 LL |     #[suggestion(no_crate_suggestion, code = "")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -559,85 +559,85 @@ LL |     #[suggestion(no_crate_suggestion, code = "")]
    = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]`
 
 error[E0433]: failed to resolve: maybe a missing crate `core`?
-  --> $DIR/diagnostic-derive.rs:54:8
+  --> $DIR/diagnostic-derive.rs:58:8
    |
 LL | #[diag = "E0123"]
    |        ^ maybe a missing crate `core`?
 
 error[E0433]: failed to resolve: maybe a missing crate `core`?
-  --> $DIR/diagnostic-derive.rs:797:23
+  --> $DIR/diagnostic-derive.rs:801:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^ maybe a missing crate `core`?
 
 error[E0433]: failed to resolve: maybe a missing crate `core`?
-  --> $DIR/diagnostic-derive.rs:806:25
+  --> $DIR/diagnostic-derive.rs:810:25
    |
 LL |     #[suggestion(code = 3)]
    |                         ^ maybe a missing crate `core`?
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:59:3
+  --> $DIR/diagnostic-derive.rs:63:3
    |
-LL | #[nonsense(no_crate_example, code = "E0123")]
+LL | #[nonsense(no_crate_example, code = E0123)]
    |   ^^^^^^^^
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:146:7
+  --> $DIR/diagnostic-derive.rs:150:7
    |
 LL |     #[nonsense]
    |       ^^^^^^^^
 
 error: cannot find attribute `error` in this scope
-  --> $DIR/diagnostic-derive.rs:579:3
+  --> $DIR/diagnostic-derive.rs:583:3
    |
-LL | #[error(no_crate_example, code = "E0123")]
+LL | #[error(no_crate_example, code = E0123)]
    |   ^^^^^
 
 error: cannot find attribute `warn_` in this scope
-  --> $DIR/diagnostic-derive.rs:586:3
+  --> $DIR/diagnostic-derive.rs:590:3
    |
-LL | #[warn_(no_crate_example, code = "E0123")]
+LL | #[warn_(no_crate_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:593:3
+  --> $DIR/diagnostic-derive.rs:597:3
    |
-LL | #[lint(no_crate_example, code = "E0123")]
+LL | #[lint(no_crate_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:600:3
+  --> $DIR/diagnostic-derive.rs:604:3
    |
-LL | #[lint(no_crate_example, code = "E0123")]
+LL | #[lint(no_crate_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:641:3
+  --> $DIR/diagnostic-derive.rs:645:3
    |
 LL | #[multipart_suggestion(no_crate_suggestion)]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:644:3
+  --> $DIR/diagnostic-derive.rs:648:3
    |
 LL | #[multipart_suggestion()]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:648:7
+  --> $DIR/diagnostic-derive.rs:652:7
    |
 LL |     #[multipart_suggestion(no_crate_suggestion)]
    |       ^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated`
-  --> $DIR/diagnostic-derive.rs:71:8
+  --> $DIR/diagnostic-derive.rs:75:8
    |
-LL | #[diag(nonsense, code = "E0123")]
+LL | #[diag(nonsense, code = E0123)]
    |        ^^^^^^^^ not found in `crate::fluent_generated`
 
 error[E0425]: cannot find value `__code_34` in this scope
-  --> $DIR/diagnostic-derive.rs:803:10
+  --> $DIR/diagnostic-derive.rs:807:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ not found in this scope
@@ -645,7 +645,7 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-  --> $DIR/diagnostic-derive.rs:345:12
+  --> $DIR/diagnostic-derive.rs:349:12
    |
 LL | #[derive(Diagnostic)]
    |          ---------- required by a bound introduced by this call
diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
index a0a8114e0c5..785da11b9b2 100644
--- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
+++ b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
@@ -19,6 +19,6 @@ use rustc_errors::{Applicability, MultiSpan};
 extern crate rustc_session;
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(compiletest_example, code = 0123)]
 //~^ ERROR diagnostic slug and crate name do not match
 struct Hello {}
diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
index 4cdc24e6a6b..eda24a555f8 100644
--- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
@@ -1,7 +1,7 @@
 error: diagnostic slug and crate name do not match
   --> $DIR/enforce_slug_naming.rs:22:8
    |
-LL | #[diag(compiletest_example, code = "E0123")]
+LL | #[diag(compiletest_example, code = 0123)]
    |        ^^^^^^^^^^^^^^^^^^^
    |
    = note: slug is `compiletest_example` but the crate name is `rustc_dummy`
diff --git a/tests/ui/anonymous-higher-ranked-lifetime.stderr b/tests/ui/anonymous-higher-ranked-lifetime.stderr
index e441cbdc866..cc27a0fcf95 100644
--- a/tests/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/tests/ui/anonymous-higher-ranked-lifetime.stderr
@@ -2,8 +2,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
    |
 LL |     f1(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a, 'b> fn(&'a (), &'b ()) -> _`
@@ -22,8 +23,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
    |
 LL |     f2(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a, 'b> fn(&'a (), &'b ()) -> _`
@@ -42,8 +44,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
    |
 LL |     f3(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a> fn(&(), &'a ()) -> _`
@@ -62,8 +65,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
    |
 LL |     f4(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'r, 'a> fn(&'a (), &'r ()) -> _`
@@ -82,8 +86,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
    |
 LL |     f5(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'r> fn(&'r (), &'r ()) -> _`
@@ -102,8 +107,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
    |
 LL |     g1(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
@@ -122,8 +128,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
    |
 LL |     g2(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a> fn(&'a (), for<'a> fn(&'a ())) -> _`
@@ -142,8 +149,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
    |
 LL |     g3(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
@@ -162,8 +170,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
    |
 LL |     g4(|_: (), _: ()| {});
-   |     ^^ -------------- found signature defined here
-   |     |
+   |     ^^^--------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a> fn(&'a (), for<'r> fn(&'r ())) -> _`
@@ -182,8 +191,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
    |
 LL |     h1(|_: (), _: (), _: (), _: ()| {});
-   |     ^^ ---------------------------- found signature defined here
-   |     |
+   |     ^^^----------------------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'a, 'b> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'b (), for<'a, 'b> fn(&'a (), &'b ())) -> _`
@@ -202,8 +212,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
    |
 LL |     h2(|_: (), _: (), _: (), _: ()| {});
-   |     ^^ ---------------------------- found signature defined here
-   |     |
+   |     ^^^----------------------------^^^^
+   |     |  |
+   |     |  found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `for<'t0, 'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _`
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
index 650b5946064..1613af6b8b1 100644
--- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
@@ -4,10 +4,7 @@ error: the associated type `X` exists for `S<Featureless, Featureless>`, but its
 LL | struct S<A, B>(A, B);
    | -------------- associated item `X` not found for this struct
 LL | struct Featureless;
-   | ------------------
-   | |
-   | doesn't satisfy `Featureless: One`
-   | doesn't satisfy `Featureless: Two`
+   | ------------------ doesn't satisfy `Featureless: One` or `Featureless: Two`
 ...
 LL |     let _: S::<Featureless, Featureless>::X;
    |                                           ^ associated type cannot be referenced on `S<Featureless, Featureless>` due to unsatisfied trait bounds
diff --git a/tests/ui/associated-types/associated-types-path-2.rs b/tests/ui/associated-types/associated-types-path-2.rs
index 00066efccb8..c993e1d2720 100644
--- a/tests/ui/associated-types/associated-types-path-2.rs
+++ b/tests/ui/associated-types/associated-types-path-2.rs
@@ -29,14 +29,12 @@ pub fn f1_uint_uint() {
     f1(2u32, 4u32);
     //~^ ERROR `u32: Foo` is not satisfied
     //~| ERROR `u32: Foo` is not satisfied
-    //~| ERROR `u32: Foo` is not satisfied
 }
 
 pub fn f1_uint_int() {
     f1(2u32, 4i32);
     //~^ ERROR `u32: Foo` is not satisfied
     //~| ERROR `u32: Foo` is not satisfied
-    //~| ERROR `u32: Foo` is not satisfied
 }
 
 pub fn f2_int() {
diff --git a/tests/ui/associated-types/associated-types-path-2.stderr b/tests/ui/associated-types/associated-types-path-2.stderr
index 206f4902410..5edd5c864e1 100644
--- a/tests/ui/associated-types/associated-types-path-2.stderr
+++ b/tests/ui/associated-types/associated-types-path-2.stderr
@@ -32,14 +32,6 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
    |              ^^^ required by this bound in `f1`
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:29:5
-   |
-LL |     f1(2u32, 4u32);
-   |     ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
-   |
-   = help: the trait `Foo` is implemented for `i32`
-
-error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:29:14
    |
 LL |     f1(2u32, 4u32);
@@ -48,7 +40,7 @@ LL |     f1(2u32, 4u32);
    = help: the trait `Foo` is implemented for `i32`
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:36:8
+  --> $DIR/associated-types-path-2.rs:35:8
    |
 LL |     f1(2u32, 4i32);
    |     -- ^^^^ the trait `Foo` is not implemented for `u32`
@@ -63,15 +55,7 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
    |              ^^^ required by this bound in `f1`
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:36:5
-   |
-LL |     f1(2u32, 4i32);
-   |     ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
-   |
-   = help: the trait `Foo` is implemented for `i32`
-
-error[E0277]: the trait bound `u32: Foo` is not satisfied
-  --> $DIR/associated-types-path-2.rs:36:14
+  --> $DIR/associated-types-path-2.rs:35:14
    |
 LL |     f1(2u32, 4i32);
    |              ^^^^ the trait `Foo` is not implemented for `u32`
@@ -79,7 +63,7 @@ LL |     f1(2u32, 4i32);
    = help: the trait `Foo` is implemented for `i32`
 
 error[E0308]: mismatched types
-  --> $DIR/associated-types-path-2.rs:43:18
+  --> $DIR/associated-types-path-2.rs:41:18
    |
 LL |     let _: i32 = f2(2i32);
    |            ---   ^^^^^^^^ expected `i32`, found `u32`
@@ -91,7 +75,7 @@ help: you can convert a `u32` to an `i32` and panic if the converted value doesn
 LL |     let _: i32 = f2(2i32).try_into().unwrap();
    |                          ++++++++++++++++++++
 
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-types/associated-types-unconstrained.stderr b/tests/ui/associated-types/associated-types-unconstrained.stderr
index 4221a064ff9..83b7f61fd69 100644
--- a/tests/ui/associated-types/associated-types-unconstrained.stderr
+++ b/tests/ui/associated-types/associated-types-unconstrained.stderr
@@ -5,7 +5,7 @@ LL |     fn bar() -> isize;
    |     ------------------ `Foo::bar` defined here
 ...
 LL |     let x: isize = Foo::bar();
-   |                    ^^^^^^^^ cannot call associated function of trait
+   |                    ^^^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
diff --git a/tests/ui/async-await/async-closures/def-path.rs b/tests/ui/async-await/async-closures/def-path.rs
new file mode 100644
index 00000000000..2883a1715b0
--- /dev/null
+++ b/tests/ui/async-await/async-closures/def-path.rs
@@ -0,0 +1,14 @@
+// compile-flags: -Zverbose-internals
+// edition:2021
+
+#![feature(async_closure)]
+
+fn main() {
+    let x = async || {};
+    //~^ NOTE the expected `async` closure body
+    let () = x();
+    //~^ ERROR mismatched types
+    //~| NOTE this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=
+    //~| NOTE expected `async` closure body, found `()`
+    //~| NOTE expected `async` closure body `{static main::{closure#0}::{closure#0}
+}
diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr
new file mode 100644
index 00000000000..4b37e50aac4
--- /dev/null
+++ b/tests/ui/async-await/async-closures/def-path.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/def-path.rs:9:9
+   |
+LL |     let x = async || {};
+   |                      -- the expected `async` closure body
+LL |
+LL |     let () = x();
+   |         ^^   --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}`
+   |         |
+   |         expected `async` closure body, found `()`
+   |
+   = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?7t witness=?8t}`
+                         found unit type `()`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/async-closures/higher-ranked.rs b/tests/ui/async-await/async-closures/higher-ranked.rs
new file mode 100644
index 00000000000..f0bdcf691ae
--- /dev/null
+++ b/tests/ui/async-await/async-closures/higher-ranked.rs
@@ -0,0 +1,12 @@
+// edition:2021
+
+#![feature(async_closure)]
+
+fn main() {
+    let x = async move |x: &str| {
+        //~^ ERROR lifetime may not live long enough
+        // This error is proof that the `&str` type is higher-ranked.
+        // This won't work until async closures are fully impl'd.
+        println!("{x}");
+    };
+}
diff --git a/tests/ui/async-await/async-closures/higher-ranked.stderr b/tests/ui/async-await/async-closures/higher-ranked.stderr
new file mode 100644
index 00000000000..fb02a15b079
--- /dev/null
+++ b/tests/ui/async-await/async-closures/higher-ranked.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+  --> $DIR/higher-ranked.rs:6:34
+   |
+LL |       let x = async move |x: &str| {
+   |  ____________________________-___-_^
+   | |                            |   |
+   | |                            |   return type of closure `{async closure body@$DIR/higher-ranked.rs:6:34: 11:6}` contains a lifetime `'2`
+   | |                            let's call the lifetime of this reference `'1`
+LL | |
+LL | |         // This error is proof that the `&str` type is higher-ranked.
+LL | |         // This won't work until async closures are fully impl'd.
+LL | |         println!("{x}");
+LL | |     };
+   | |_____^ returning this value requires that `'1` must outlive `'2`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/async-is-unwindsafe.stderr b/tests/ui/async-await/async-is-unwindsafe.stderr
index 99bce89e8d3..4098b29c557 100644
--- a/tests/ui/async-await/async-is-unwindsafe.stderr
+++ b/tests/ui/async-await/async-is-unwindsafe.stderr
@@ -1,17 +1,19 @@
 error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
   --> $DIR/async-is-unwindsafe.rs:12:5
    |
-LL |       is_unwindsafe(async {
-   |  _____^^^^^^^^^^^^^_-
-   | |     |
-   | |     `&mut Context<'_>` may not be safely transferred across an unwind boundary
-LL | |
-LL | |         use std::ptr::null;
-LL | |         use std::task::{Context, RawWaker, RawWakerVTable, Waker};
-...  |
-LL | |         drop(cx_ref);
-LL | |     });
-   | |_____- within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
+LL |        is_unwindsafe(async {
+   |   _____^_____________-
+   |  |_____|
+   | ||
+LL | ||
+LL | ||         use std::ptr::null;
+LL | ||         use std::task::{Context, RawWaker, RawWakerVTable, Waker};
+...  ||
+LL | ||         drop(cx_ref);
+LL | ||     });
+   | ||_____-^ `&mut Context<'_>` may not be safely transferred across an unwind boundary
+   |  |_____|
+   |        within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
    |
    = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`
    = note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
diff --git a/tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs b/tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs
new file mode 100644
index 00000000000..72f02679d77
--- /dev/null
+++ b/tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs
@@ -0,0 +1,18 @@
+// check-pass
+// edition:2021
+
+#![deny(opaque_hidden_inferred_bound)]
+
+trait Repository /* : ?Sized */ {
+    async fn new() -> Self;
+}
+
+struct MyRepository {}
+
+impl Repository for MyRepository {
+    async fn new() -> Self {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.stderr b/tests/ui/async-await/issue-67252-unnamed-future.stderr
index e1c5a22967e..62ffb7d2eda 100644
--- a/tests/ui/async-await/issue-67252-unnamed-future.stderr
+++ b/tests/ui/async-await/issue-67252-unnamed-future.stderr
@@ -1,8 +1,12 @@
 error: future cannot be sent between threads safely
   --> $DIR/issue-67252-unnamed-future.rs:18:5
    |
-LL |     spawn(async {
-   |     ^^^^^ future created by async block is not `Send`
+LL | /     spawn(async {
+LL | |         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
+LL | |         AFuture.await;
+LL | |         let _a = a;
+LL | |     });
+   | |______^ future created by async block is not `Send`
    |
    = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:18:11: 22:6}`, the trait `Send` is not implemented for `*mut ()`
 note: future is not `Send` as this value is used across an await
diff --git a/tests/ui/async-await/issue-68112.stderr b/tests/ui/async-await/issue-68112.stderr
index 1cd8beac260..438782e0e45 100644
--- a/tests/ui/async-await/issue-68112.stderr
+++ b/tests/ui/async-await/issue-68112.stderr
@@ -2,7 +2,7 @@ error: future cannot be sent between threads safely
   --> $DIR/issue-68112.rs:34:5
    |
 LL |     require_send(send_fut);
-   |     ^^^^^^^^^^^^ future created by async block is not `Send`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
@@ -21,7 +21,7 @@ error: future cannot be sent between threads safely
   --> $DIR/issue-68112.rs:43:5
    |
 LL |     require_send(send_fut);
-   |     ^^^^^^^^^^^^ future created by async block is not `Send`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
@@ -40,7 +40,7 @@ error[E0277]: `RefCell<i32>` cannot be shared between threads safely
   --> $DIR/issue-68112.rs:62:5
    |
 LL |     require_send(send_fut);
-   |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+   |     ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
diff --git a/tests/ui/box/unit/unique-object-noncopyable.stderr b/tests/ui/box/unit/unique-object-noncopyable.stderr
index 1b98d09ccdd..49547872d1a 100644
--- a/tests/ui/box/unit/unique-object-noncopyable.stderr
+++ b/tests/ui/box/unit/unique-object-noncopyable.stderr
@@ -1,18 +1,11 @@
 error[E0599]: the method `clone` exists for struct `Box<dyn Foo>`, but its trait bounds were not satisfied
   --> $DIR/unique-object-noncopyable.rs:24:16
    |
-LL |   trait Foo {
-   |   ---------
-   |   |
-   |   doesn't satisfy `dyn Foo: Clone`
-   |   doesn't satisfy `dyn Foo: Sized`
+LL | trait Foo {
+   | --------- doesn't satisfy `dyn Foo: Clone` or `dyn Foo: Sized`
 ...
-LL |       let _z = y.clone();
-   |                  ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
-  ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
-   |
-   = note: doesn't satisfy `Box<dyn Foo>: Clone`
+LL |     let _z = y.clone();
+   |                ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `dyn Foo: Sized`
diff --git a/tests/ui/box/unit/unique-pinned-nocopy.stderr b/tests/ui/box/unit/unique-pinned-nocopy.stderr
index d662a2d6d05..d2bf72249c4 100644
--- a/tests/ui/box/unit/unique-pinned-nocopy.stderr
+++ b/tests/ui/box/unit/unique-pinned-nocopy.stderr
@@ -1,15 +1,11 @@
 error[E0599]: the method `clone` exists for struct `Box<R>`, but its trait bounds were not satisfied
   --> $DIR/unique-pinned-nocopy.rs:12:16
    |
-LL |   struct R {
-   |   -------- doesn't satisfy `R: Clone`
+LL | struct R {
+   | -------- doesn't satisfy `R: Clone`
 ...
-LL |       let _j = i.clone();
-   |                  ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
-  ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
-   |
-   = note: doesn't satisfy `Box<R>: Clone`
+LL |     let _j = i.clone();
+   |                ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `R: Clone`
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index d7d538c0b9e..814d4736197 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -125,7 +125,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_env = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_env` are: ``, `eabihf`, `gnu`, `gnueabihf`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `preview2`, `psx`, `relibc`, `sgx`, `uclibc`
+   = note: expected values for `target_env` are: ``, `eabihf`, `gnu`, `gnueabihf`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `psx`, `relibc`, `sgx`, `uclibc`
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -134,7 +134,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_family = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_family` are: `unix`, `wasi`, `wasm`, `windows`
+   = note: expected values for `target_family` are: `unix`, `wasm`, `windows`
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
diff --git a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
index d3cd8185f92..e2a2db7c3f0 100644
--- a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
+++ b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
@@ -1,10 +1,13 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-infer-var-appearing-twice.rs:14:5
    |
-LL |     with_closure(|x: u32, y: i32| {
-   |     ^^^^^^^^^^^^ ---------------- found signature defined here
-   |     |
-   |     expected due to this
+LL |       with_closure(|x: u32, y: i32| {
+   |       ^            ---------------- found signature defined here
+   |  _____|
+   | |
+LL | |
+LL | |     });
+   | |______^ expected due to this
    |
    = note: expected closure signature `fn(_, _) -> _`
               found closure signature `fn(u32, i32) -> _`
diff --git a/tests/ui/closures/closure-return-type-must-be-sized.stderr b/tests/ui/closures/closure-return-type-must-be-sized.stderr
index d4fc723fa81..04ae7343bbe 100644
--- a/tests/ui/closures/closure-return-type-must-be-sized.stderr
+++ b/tests/ui/closures/closure-return-type-must-be-sized.stderr
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `dyn A` cannot be known at compilation
   --> $DIR/closure-return-type-must-be-sized.rs:54:5
    |
 LL |     a::foo::<fn() -> dyn A>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
    = note: required because it appears within the type `fn() -> dyn A`
@@ -25,7 +25,7 @@ error[E0277]: the size for values of type `dyn A` cannot be known at compilation
   --> $DIR/closure-return-type-must-be-sized.rs:56:5
    |
 LL |     a::baz::<fn() -> dyn A>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
    = note: required because it appears within the type `fn() -> dyn A`
@@ -34,7 +34,7 @@ error[E0277]: the size for values of type `dyn A` cannot be known at compilation
   --> $DIR/closure-return-type-must-be-sized.rs:61:5
    |
 LL |     b::foo::<fn() -> dyn A>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
    = note: required because it appears within the type `fn() -> dyn A`
@@ -57,7 +57,7 @@ error[E0277]: the size for values of type `dyn A` cannot be known at compilation
   --> $DIR/closure-return-type-must-be-sized.rs:63:5
    |
 LL |     b::baz::<fn() -> dyn A>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
    = note: required because it appears within the type `fn() -> dyn A`
@@ -66,7 +66,7 @@ error[E0277]: the size for values of type `dyn A` cannot be known at compilation
   --> $DIR/closure-return-type-must-be-sized.rs:68:5
    |
 LL |     c::foo::<fn() -> dyn A>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
    = note: required because it appears within the type `fn() -> dyn A`
@@ -89,7 +89,7 @@ error[E0277]: the size for values of type `dyn A` cannot be known at compilation
   --> $DIR/closure-return-type-must-be-sized.rs:70:5
    |
 LL |     c::baz::<fn() -> dyn A>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
    = note: required because it appears within the type `fn() -> dyn A`
diff --git a/tests/ui/closures/multiple-fn-bounds.stderr b/tests/ui/closures/multiple-fn-bounds.stderr
index 325652ef14c..9a49fc99ac3 100644
--- a/tests/ui/closures/multiple-fn-bounds.stderr
+++ b/tests/ui/closures/multiple-fn-bounds.stderr
@@ -2,8 +2,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/multiple-fn-bounds.rs:10:5
    |
 LL |     foo(move |x| v);
-   |     ^^^ -------- found signature defined here
-   |     |
+   |     ^^^^--------^^^
+   |     |   |
+   |     |   found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `fn(_) -> _`
diff --git a/tests/ui/codegen/mismatched-data-layout.json b/tests/ui/codegen/mismatched-data-layout.json
new file mode 100644
index 00000000000..4cb0602dc75
--- /dev/null
+++ b/tests/ui/codegen/mismatched-data-layout.json
@@ -0,0 +1,13 @@
+{
+    "llvm-target": "x86_64-unknown-none-gnu",
+    "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
+    "arch": "x86_64",
+    "target-endian": "little",
+    "target-pointer-width": "64",
+    "target-c-int-width": "32",
+    "os": "unknown",
+    "linker-flavor": "ld.lld",
+    "linker": "rust-lld",
+    "executables": true
+}
+
diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs
new file mode 100644
index 00000000000..047ec155fdc
--- /dev/null
+++ b/tests/ui/codegen/mismatched-data-layouts.rs
@@ -0,0 +1,14 @@
+// This test checks that data layout mismatches emit an error.
+//
+// build-fail
+// needs-llvm-components: x86
+// compile-flags: --crate-type=lib --target={{src-base}}/codegen/mismatched-data-layout.json -Z unstable-options
+// error-pattern: differs from LLVM target's
+// normalize-stderr-test: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`"
+// normalize-stderr-test: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`"
+
+#![feature(lang_items, no_core, auto_traits)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
diff --git a/tests/ui/codegen/mismatched-data-layouts.stderr b/tests/ui/codegen/mismatched-data-layouts.stderr
new file mode 100644
index 00000000000..1fe242266df
--- /dev/null
+++ b/tests/ui/codegen/mismatched-data-layouts.stderr
@@ -0,0 +1,4 @@
+error: data-layout for target `mismatched-data-layout-7814813422914914169`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/const-generics/ensure_is_evaluatable.stderr b/tests/ui/const-generics/ensure_is_evaluatable.stderr
index a6f36230820..b9bd9160b13 100644
--- a/tests/ui/const-generics/ensure_is_evaluatable.stderr
+++ b/tests/ui/const-generics/ensure_is_evaluatable.stderr
@@ -2,7 +2,7 @@ error: unconstrained generic constant
   --> $DIR/ensure_is_evaluatable.rs:9:5
    |
 LL |     bar()
-   |     ^^^
+   |     ^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); N + 1]:`
 note: required by a bound in `bar`
diff --git a/tests/ui/const-generics/fn_with_two_const_inputs.stderr b/tests/ui/const-generics/fn_with_two_const_inputs.stderr
index ad32a688c03..ec31e02f144 100644
--- a/tests/ui/const-generics/fn_with_two_const_inputs.stderr
+++ b/tests/ui/const-generics/fn_with_two_const_inputs.stderr
@@ -2,7 +2,7 @@ error: unconstrained generic constant
   --> $DIR/fn_with_two_const_inputs.rs:12:5
    |
 LL |     bar()
-   |     ^^^
+   |     ^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); N + 1]:`
 note: required by a bound in `bar`
diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
index f2cc17bc517..6d3b0b8508c 100644
--- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed for `Mask<_, N>`
   --> $DIR/issue-91614.rs:6:9
    |
 LL |     let y = Mask::<_, _>::splat(false);
-   |         ^   ------------------- type must be known at this point
+   |         ^   -------------------------- type must be known at this point
    |
    = note: cannot satisfy `_: MaskElement`
    = help: the following types implement trait `MaskElement`:
diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
index cdf97bd88fd..bd6fd67b89d 100644
--- a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr
@@ -20,7 +20,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:17:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
    |
    = note: expected constant `{ N as u128 }`
               found constant `{ O as u128 }`
@@ -52,7 +52,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:20:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
    |
    = note: expected constant `{ N as _ }`
               found constant `{ O as u128 }`
@@ -66,7 +66,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:23:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
    |
    = note: expected constant `12`
               found constant `13`
@@ -80,7 +80,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:25:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
    |
    = note: expected constant `13`
               found constant `14`
@@ -112,7 +112,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:35:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
    |
    = note: expected constant `{ N as u128 }`
               found constant `{ O as u128 }`
@@ -144,7 +144,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:38:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
    |
    = note: expected constant `{ N as _ }`
               found constant `{ O as u128 }`
@@ -158,7 +158,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:41:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13`
    |
    = note: expected constant `12`
               found constant `13`
@@ -172,7 +172,7 @@ error[E0308]: mismatched types
   --> $DIR/abstract-const-as-cast-3.rs:43:5
    |
 LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14`
    |
    = note: expected constant `13`
               found constant `14`
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
index 9391b1c1a17..8b7120035ca 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr
@@ -58,7 +58,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-85848.rs:24:5
    |
 LL |     writes_to_specific_path(&cap);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `{ contains::<T, U>() }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `{ contains::<T, U>() }`
    |
    = note: expected constant `true`
               found constant `{ contains::<T, U>() }`
diff --git a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
index eba8b9b6257..7f6a154865c 100644
--- a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/obligation-cause.rs:20:5
    |
 LL |     g::<usize>();
-   |     ^^^^^^^^^^ expected `false`, found `true`
+   |     ^^^^^^^^^^^^ expected `false`, found `true`
    |
    = note: expected constant `false`
               found constant `true`
diff --git a/tests/ui/const-generics/issues/issue-79674.stderr b/tests/ui/const-generics/issues/issue-79674.stderr
index 1e7878e8da9..595bb6faf8c 100644
--- a/tests/ui/const-generics/issues/issue-79674.stderr
+++ b/tests/ui/const-generics/issues/issue-79674.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-79674.rs:26:5
    |
 LL |     requires_distinct("str", 12);
-   |     ^^^^^^^^^^^^^^^^^ expected `true`, found `false`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `true`, found `false`
    |
    = note: expected constant `true`
               found constant `false`
diff --git a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr
index 07da6ede725..989be74d1b0 100644
--- a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr
+++ b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr
@@ -2,7 +2,7 @@ error[E0284]: type annotations needed
   --> $DIR/parent_generics_of_encoding_impl_trait.rs:9:5
    |
 LL |     generics_of_parent_impl_trait::foo([()]);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo`
    |
 note: required by a bound in `foo`
   --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:6:48
diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr
index 03c47030c0e..b8c983eb7b8 100644
--- a/tests/ui/consts/issue-54954.stderr
+++ b/tests/ui/consts/issue-54954.stderr
@@ -11,7 +11,7 @@ error[E0790]: cannot call associated function on trait without specifying the co
   --> $DIR/issue-54954.rs:1:24
    |
 LL |   const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
 ...
 LL | /     const fn const_val<T: Sized>() -> usize {
 LL | |
diff --git a/tests/ui/consts/let-irrefutable-pattern-ice-120337.rs b/tests/ui/consts/let-irrefutable-pattern-ice-120337.rs
new file mode 100644
index 00000000000..7da6b7ca285
--- /dev/null
+++ b/tests/ui/consts/let-irrefutable-pattern-ice-120337.rs
@@ -0,0 +1,10 @@
+// check-pass
+#![feature(never_type)]
+#[derive(Copy, Clone)]
+pub enum E { A(!), }
+pub union U { u: (), e: E, }
+pub const C: () = {
+    let E::A(ref a) = unsafe { &(&U { u: () }).e};
+};
+
+fn main() {}
diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr
index 82a6d0495c0..9ee011ebc36 100644
--- a/tests/ui/coroutine/clone-impl.stderr
+++ b/tests/ui/coroutine/clone-impl.stderr
@@ -5,7 +5,7 @@ LL |     let gen_clone_0 = move || {
    |                       ------- within this `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |     ^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<u32>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<u32>`
    |
 note: captured value does not implement `Copy`
   --> $DIR/clone-impl.rs:40:14
@@ -25,7 +25,7 @@ LL |     let gen_clone_0 = move || {
    |                       ------- within this `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |     ^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<char>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<char>`
    |
 note: coroutine does not implement `Copy` as this value is used across a yield
   --> $DIR/clone-impl.rs:38:9
@@ -47,7 +47,7 @@ LL |     let gen_clone_1 = move || {
    |                       ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |     ^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<u32>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<u32>`
    |
 note: captured value does not implement `Copy`
   --> $DIR/clone-impl.rs:56:14
@@ -67,7 +67,7 @@ LL |     let gen_clone_1 = move || {
    |                       ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |     ^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<char>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<char>`
    |
 note: coroutine does not implement `Copy` as this value is used across a yield
   --> $DIR/clone-impl.rs:52:9
@@ -90,7 +90,7 @@ LL |     let gen_non_clone = move || {
    |                         ------- within this `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`
 ...
 LL |     check_copy(&gen_non_clone);
-   |     ^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Copy` is not implemented for `NonClone`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Copy` is not implemented for `NonClone`
    |
 note: captured value does not implement `Copy`
   --> $DIR/clone-impl.rs:64:14
@@ -115,7 +115,7 @@ LL |     let gen_non_clone = move || {
    |                         ------- within this `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`
 ...
 LL |     check_clone(&gen_non_clone);
-   |     ^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Clone` is not implemented for `NonClone`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Clone` is not implemented for `NonClone`
    |
 note: captured value does not implement `Clone`
   --> $DIR/clone-impl.rs:64:14
diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.stderr b/tests/ui/coroutine/drop-tracking-parent-expression.stderr
index 6cd4ec83377..a57b7ffab4d 100644
--- a/tests/ui/coroutine/drop-tracking-parent-expression.stderr
+++ b/tests/ui/coroutine/drop-tracking-parent-expression.stderr
@@ -2,7 +2,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/drop-tracking-parent-expression.rs:23:13
    |
 LL |               assert_send(g);
-   |               ^^^^^^^^^^^ coroutine is not `Send`
+   |               ^^^^^^^^^^^^^^ coroutine is not `Send`
 ...
 LL | /     type_combinations!(
 LL | |         // OK
@@ -42,7 +42,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/drop-tracking-parent-expression.rs:23:13
    |
 LL |               assert_send(g);
-   |               ^^^^^^^^^^^ coroutine is not `Send`
+   |               ^^^^^^^^^^^^^^ coroutine is not `Send`
 ...
 LL | /     type_combinations!(
 LL | |         // OK
@@ -82,7 +82,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/drop-tracking-parent-expression.rs:23:13
    |
 LL |               assert_send(g);
-   |               ^^^^^^^^^^^ coroutine is not `Send`
+   |               ^^^^^^^^^^^^^^ coroutine is not `Send`
 ...
 LL | /     type_combinations!(
 LL | |         // OK
diff --git a/tests/ui/coroutine/drop-yield-twice.stderr b/tests/ui/coroutine/drop-yield-twice.stderr
index b37c27015fb..5766e95f088 100644
--- a/tests/ui/coroutine/drop-yield-twice.stderr
+++ b/tests/ui/coroutine/drop-yield-twice.stderr
@@ -1,8 +1,13 @@
 error: coroutine cannot be sent between threads safely
   --> $DIR/drop-yield-twice.rs:7:5
    |
-LL |     assert_send(|| {
-   |     ^^^^^^^^^^^ coroutine is not `Send`
+LL | /     assert_send(|| {
+LL | |         let guard = Foo(42);
+LL | |         yield;
+LL | |         drop(guard);
+LL | |         yield;
+LL | |     })
+   | |______^ coroutine is not `Send`
    |
    = help: within `{coroutine@$DIR/drop-yield-twice.rs:7:17: 7:19}`, the trait `Send` is not implemented for `Foo`
 note: coroutine is not `Send` as this value is used across a yield
diff --git a/tests/ui/coroutine/issue-105084.stderr b/tests/ui/coroutine/issue-105084.stderr
index 38f114ff774..34e97752f6c 100644
--- a/tests/ui/coroutine/issue-105084.stderr
+++ b/tests/ui/coroutine/issue-105084.stderr
@@ -29,7 +29,7 @@ LL |     let mut g = || {
    |                 -- within this `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`
 ...
 LL |     let mut h = copy(g);
-   |                 ^^^^ within `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
+   |                 ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
    |
 note: coroutine does not implement `Copy` as this value is used across a yield
   --> $DIR/issue-105084.rs:21:22
diff --git a/tests/ui/coroutine/issue-68112.stderr b/tests/ui/coroutine/issue-68112.stderr
index 5efa72ad5fe..32035003487 100644
--- a/tests/ui/coroutine/issue-68112.stderr
+++ b/tests/ui/coroutine/issue-68112.stderr
@@ -2,7 +2,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/issue-68112.rs:40:5
    |
 LL |     require_send(send_gen);
-   |     ^^^^^^^^^^^^ coroutine is not `Send`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ coroutine is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
@@ -24,7 +24,7 @@ error[E0277]: `RefCell<i32>` cannot be shared between threads safely
   --> $DIR/issue-68112.rs:64:5
    |
 LL |     require_send(send_gen);
-   |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+   |     ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
diff --git a/tests/ui/coroutine/not-send-sync.stderr b/tests/ui/coroutine/not-send-sync.stderr
index b33a1e63aaf..e00c0d9158c 100644
--- a/tests/ui/coroutine/not-send-sync.stderr
+++ b/tests/ui/coroutine/not-send-sync.stderr
@@ -1,8 +1,13 @@
 error: coroutine cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:14:5
    |
-LL |     assert_sync(|| {
-   |     ^^^^^^^^^^^ coroutine is not `Sync`
+LL | /     assert_sync(|| {
+LL | |
+LL | |         let a = NotSync;
+LL | |         yield;
+LL | |         drop(a);
+LL | |     });
+   | |______^ coroutine is not `Sync`
    |
    = help: within `{coroutine@$DIR/not-send-sync.rs:14:17: 14:19}`, the trait `Sync` is not implemented for `NotSync`
 note: coroutine is not `Sync` as this value is used across a yield
@@ -21,8 +26,13 @@ LL |     fn assert_sync<T: Sync>(_: T) {}
 error: coroutine cannot be sent between threads safely
   --> $DIR/not-send-sync.rs:21:5
    |
-LL |     assert_send(|| {
-   |     ^^^^^^^^^^^ coroutine is not `Send`
+LL | /     assert_send(|| {
+LL | |
+LL | |         let a = NotSend;
+LL | |         yield;
+LL | |         drop(a);
+LL | |     });
+   | |______^ coroutine is not `Send`
    |
    = help: within `{coroutine@$DIR/not-send-sync.rs:21:17: 21:19}`, the trait `Send` is not implemented for `NotSend`
 note: coroutine is not `Send` as this value is used across a yield
diff --git a/tests/ui/coroutine/parent-expression.stderr b/tests/ui/coroutine/parent-expression.stderr
index 6b611bc3f10..d2c09432b3a 100644
--- a/tests/ui/coroutine/parent-expression.stderr
+++ b/tests/ui/coroutine/parent-expression.stderr
@@ -2,7 +2,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/parent-expression.rs:23:13
    |
 LL |               assert_send(g);
-   |               ^^^^^^^^^^^ coroutine is not `Send`
+   |               ^^^^^^^^^^^^^^ coroutine is not `Send`
 ...
 LL | /     type_combinations!(
 LL | |         // OK
@@ -42,7 +42,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/parent-expression.rs:23:13
    |
 LL |               assert_send(g);
-   |               ^^^^^^^^^^^ coroutine is not `Send`
+   |               ^^^^^^^^^^^^^^ coroutine is not `Send`
 ...
 LL | /     type_combinations!(
 LL | |         // OK
@@ -82,7 +82,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/parent-expression.rs:23:13
    |
 LL |               assert_send(g);
-   |               ^^^^^^^^^^^ coroutine is not `Send`
+   |               ^^^^^^^^^^^^^^ coroutine is not `Send`
 ...
 LL | /     type_combinations!(
 LL | |         // OK
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
index bcdcbc154cf..6cf0f6e73ac 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr
@@ -2,7 +2,7 @@ error: coroutine cannot be sent between threads safely
   --> $DIR/coroutine-print-verbose-1.rs:37:5
    |
 LL |     require_send(send_gen);
-   |     ^^^^^^^^^^^^ coroutine is not `Send`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ coroutine is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
@@ -23,7 +23,7 @@ error[E0277]: `RefCell<i32>` cannot be shared between threads safely
   --> $DIR/coroutine-print-verbose-1.rs:56:5
    |
 LL |     require_send(send_gen);
-   |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
+   |     ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
index 165302ab140..aef48b7522b 100644
--- a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
+++ b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr
@@ -1,8 +1,13 @@
 error: coroutine cannot be shared between threads safely
   --> $DIR/coroutine-print-verbose-2.rs:17:5
    |
-LL |     assert_sync(|| {
-   |     ^^^^^^^^^^^ coroutine is not `Sync`
+LL | /     assert_sync(|| {
+LL | |
+LL | |         let a = NotSync;
+LL | |         yield;
+LL | |         drop(a);
+LL | |     });
+   | |______^ coroutine is not `Sync`
    |
    = help: within `{main::{closure#0} upvar_tys=() witness={main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
 note: coroutine is not `Sync` as this value is used across a yield
@@ -21,8 +26,13 @@ LL |     fn assert_sync<T: Sync>(_: T) {}
 error: coroutine cannot be sent between threads safely
   --> $DIR/coroutine-print-verbose-2.rs:24:5
    |
-LL |     assert_send(|| {
-   |     ^^^^^^^^^^^ coroutine is not `Send`
+LL | /     assert_send(|| {
+LL | |
+LL | |         let a = NotSend;
+LL | |         yield;
+LL | |         drop(a);
+LL | |     });
+   | |______^ coroutine is not `Send`
    |
    = help: within `{main::{closure#1} upvar_tys=() witness={main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
 note: coroutine is not `Send` as this value is used across a yield
diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr
index 6cbcb455f87..61268ffc7f8 100644
--- a/tests/ui/derives/derive-assoc-type-not-impl.stderr
+++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr
@@ -2,10 +2,7 @@ error[E0599]: the method `clone` exists for struct `Bar<NotClone>`, but its trai
   --> $DIR/derive-assoc-type-not-impl.rs:18:30
    |
 LL | struct Bar<T: Foo> {
-   | ------------------
-   | |
-   | method `clone` not found for this struct
-   | doesn't satisfy `Bar<NotClone>: Clone`
+   | ------------------ method `clone` not found for this struct because it doesn't satisfy `Bar<NotClone>: Clone`
 ...
 LL | struct NotClone;
    | --------------- doesn't satisfy `NotClone: Clone`
diff --git a/tests/ui/derives/deriving-with-repr-packed-2.stderr b/tests/ui/derives/deriving-with-repr-packed-2.stderr
index 0eaca7e2360..96f51a4e7a2 100644
--- a/tests/ui/derives/deriving-with-repr-packed-2.stderr
+++ b/tests/ui/derives/deriving-with-repr-packed-2.stderr
@@ -2,16 +2,10 @@ error[E0599]: the method `clone` exists for struct `Foo<NonCopy>`, but its trait
   --> $DIR/deriving-with-repr-packed-2.rs:18:11
    |
 LL | pub struct Foo<T>(T, T, T);
-   | -----------------
-   | |
-   | method `clone` not found for this struct
-   | doesn't satisfy `Foo<NonCopy>: Clone`
+   | ----------------- method `clone` not found for this struct because it doesn't satisfy `Foo<NonCopy>: Clone`
 LL |
 LL | struct NonCopy;
-   | --------------
-   | |
-   | doesn't satisfy `NonCopy: Clone`
-   | doesn't satisfy `NonCopy: Copy`
+   | -------------- doesn't satisfy `NonCopy: Clone` or `NonCopy: Copy`
 ...
 LL |     _ = x.clone();
    |           ^^^^^ method cannot be called on `Foo<NonCopy>` due to unsatisfied trait bounds
diff --git a/tests/ui/derives/issue-36617.rs b/tests/ui/derives/issue-36617.rs
index 08f293d2ebb..236ec7748cb 100644
--- a/tests/ui/derives/issue-36617.rs
+++ b/tests/ui/derives/issue-36617.rs
@@ -1,16 +1,16 @@
-#![derive(Copy)] //~ ERROR cannot determine resolution for the attribute macro `derive`
+#![derive(Copy)]
 //~^ ERROR `derive` attribute cannot be used at crate level
 
-#![test]//~ ERROR cannot determine resolution for the attribute macro `test`
+#![test]
 //~^ ERROR `test` attribute cannot be used at crate level
 
-#![test_case]//~ ERROR cannot determine resolution for the attribute macro `test_case`
+#![test_case]
 //~^ ERROR `test_case` attribute cannot be used at crate level
 
-#![bench]//~ ERROR cannot determine resolution for the attribute macro `bench`
+#![bench]
 //~^ ERROR `bench` attribute cannot be used at crate level
 
-#![global_allocator]//~ ERROR cannot determine resolution for the attribute macro `global_allocator`
+#![global_allocator]
 //~^ ERROR `global_allocator` attribute cannot be used at crate level
 
 fn main() {}
diff --git a/tests/ui/derives/issue-36617.stderr b/tests/ui/derives/issue-36617.stderr
index 98be7963e5e..3de1d87c504 100644
--- a/tests/ui/derives/issue-36617.stderr
+++ b/tests/ui/derives/issue-36617.stderr
@@ -1,43 +1,3 @@
-error: cannot determine resolution for the attribute macro `derive`
-  --> $DIR/issue-36617.rs:1:4
-   |
-LL | #![derive(Copy)]
-   |    ^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: cannot determine resolution for the attribute macro `test`
-  --> $DIR/issue-36617.rs:4:4
-   |
-LL | #![test]
-   |    ^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: cannot determine resolution for the attribute macro `test_case`
-  --> $DIR/issue-36617.rs:7:4
-   |
-LL | #![test_case]
-   |    ^^^^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: cannot determine resolution for the attribute macro `bench`
-  --> $DIR/issue-36617.rs:10:4
-   |
-LL | #![bench]
-   |    ^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: cannot determine resolution for the attribute macro `global_allocator`
-  --> $DIR/issue-36617.rs:13:4
-   |
-LL | #![global_allocator]
-   |    ^^^^^^^^^^^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: `derive` attribute cannot be used at crate level
   --> $DIR/issue-36617.rs:1:1
    |
@@ -113,5 +73,5 @@ LL - #![global_allocator]
 LL + #[global_allocator]
    |
 
-error: aborting due to 10 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr
index 1324b80b5fc..9e171896718 100644
--- a/tests/ui/derives/issue-91550.stderr
+++ b/tests/ui/derives/issue-91550.stderr
@@ -2,11 +2,7 @@ error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its tr
   --> $DIR/issue-91550.rs:8:8
    |
 LL | struct Value(u32);
-   | ------------
-   | |
-   | doesn't satisfy `Value: Eq`
-   | doesn't satisfy `Value: Hash`
-   | doesn't satisfy `Value: PartialEq`
+   | ------------ doesn't satisfy `Value: Eq`, `Value: Hash` or `Value: PartialEq`
 ...
 LL |     hs.insert(Value(0));
    |        ^^^^^^
@@ -26,10 +22,7 @@ error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its
   --> $DIR/issue-91550.rs:26:9
    |
 LL | pub struct NoDerives;
-   | --------------------
-   | |
-   | doesn't satisfy `NoDerives: Eq`
-   | doesn't satisfy `NoDerives: PartialEq`
+   | -------------------- doesn't satisfy `NoDerives: Eq` or `NoDerives: PartialEq`
 LL |
 LL | struct Object<T>(T);
    | ---------------- method `use_eq` not found for this struct
@@ -57,12 +50,7 @@ error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but it
   --> $DIR/issue-91550.rs:27:9
    |
 LL | pub struct NoDerives;
-   | --------------------
-   | |
-   | doesn't satisfy `NoDerives: Eq`
-   | doesn't satisfy `NoDerives: Ord`
-   | doesn't satisfy `NoDerives: PartialEq`
-   | doesn't satisfy `NoDerives: PartialOrd`
+   | -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
 LL |
 LL | struct Object<T>(T);
    | ---------------- method `use_ord` not found for this struct
@@ -94,12 +82,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
   --> $DIR/issue-91550.rs:28:9
    |
 LL | pub struct NoDerives;
-   | --------------------
-   | |
-   | doesn't satisfy `NoDerives: Eq`
-   | doesn't satisfy `NoDerives: Ord`
-   | doesn't satisfy `NoDerives: PartialEq`
-   | doesn't satisfy `NoDerives: PartialOrd`
+   | -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
 LL |
 LL | struct Object<T>(T);
    | ---------------- method `use_ord_and_partial_ord` not found for this struct
diff --git a/tests/ui/did_you_mean/recursion_limit.stderr b/tests/ui/did_you_mean/recursion_limit.stderr
index bff57a63deb..2ecee2030b0 100644
--- a/tests/ui/did_you_mean/recursion_limit.stderr
+++ b/tests/ui/did_you_mean/recursion_limit.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `J: Send`
   --> $DIR/recursion_limit.rs:34:5
    |
 LL |     is_send::<A>();
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`recursion_limit`)
 note: required because it appears within the type `I`
diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
index 6752a484448..2d7956f1958 100644
--- a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
+++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied
   --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:11:22
    |
 LL |     let x: [u8; 1] = needs_test();
-   |                      ^^^^^^^^^^ the trait `Test` is not implemented for `[u8; 1]`
+   |                      ^^^^^^^^^^^^ the trait `Test` is not implemented for `[u8; 1]`
    |
    = help: the trait `Test` is implemented for `&[u8]`
 note: required by a bound in `needs_test`
diff --git a/tests/ui/error-codes/E0283.stderr b/tests/ui/error-codes/E0283.stderr
index 6008809f050..fc08395a2b0 100644
--- a/tests/ui/error-codes/E0283.stderr
+++ b/tests/ui/error-codes/E0283.stderr
@@ -5,7 +5,7 @@ LL |     fn create() -> u32;
    |     ------------------- `Coroutine::create` defined here
 ...
 LL |     let cont: u32 = Coroutine::create();
-   |                     ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |                     ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use a fully-qualified path to a specific available implementation
    |
diff --git a/tests/ui/error-codes/E0790.stderr b/tests/ui/error-codes/E0790.stderr
index f559abae397..6338a10b6af 100644
--- a/tests/ui/error-codes/E0790.stderr
+++ b/tests/ui/error-codes/E0790.stderr
@@ -5,7 +5,7 @@ LL |         fn my_fn();
    |         ----------- `MyTrait::my_fn` defined here
 ...
 LL |         MyTrait::my_fn();
-   |         ^^^^^^^^^^^^^^ cannot call associated function of trait
+   |         ^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
@@ -33,7 +33,7 @@ LL |         fn my_fn();
    |         ----------- `MyTrait::my_fn` defined here
 ...
 LL |     inner::MyTrait::my_fn();
-   |     ^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
@@ -61,7 +61,7 @@ LL |     fn my_fn();
    |     ----------- `MyTrait2::my_fn` defined here
 ...
 LL |     MyTrait2::my_fn();
-   |     ^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |     ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use a fully-qualified path to a specific available implementation
    |
diff --git a/tests/ui/extenv/issue-55897.rs b/tests/ui/extenv/issue-55897.rs
index b7533f41351..b6500e54059 100644
--- a/tests/ui/extenv/issue-55897.rs
+++ b/tests/ui/extenv/issue-55897.rs
@@ -4,7 +4,6 @@ mod unresolved_env {
     use env; //~ ERROR unresolved import `env`
 
     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
-    //~^ ERROR cannot determine resolution for the macro `env`
 }
 
 mod nonexistent_env {
diff --git a/tests/ui/extenv/issue-55897.stderr b/tests/ui/extenv/issue-55897.stderr
index 401db827813..2e8c05cca86 100644
--- a/tests/ui/extenv/issue-55897.stderr
+++ b/tests/ui/extenv/issue-55897.stderr
@@ -1,5 +1,5 @@
 error: environment variable `NON_EXISTENT` not defined at compile time
-  --> $DIR/issue-55897.rs:11:22
+  --> $DIR/issue-55897.rs:10:22
    |
 LL |     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
    |                      ^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
    = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: suffixes on string literals are invalid
-  --> $DIR/issue-55897.rs:16:22
+  --> $DIR/issue-55897.rs:15:22
    |
 LL |     include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
    |                      ^^^^^^^^^^^^^^^^^^^^ invalid suffix `suffix`
@@ -33,14 +33,6 @@ help: consider importing this module instead
 LL |     use std::env;
    |         ~~~~~~~~
 
-error: cannot determine resolution for the macro `env`
-  --> $DIR/issue-55897.rs:6:22
-   |
-LL |     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
-   |                      ^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
index 134ea25b75a..594a2672d43 100644
--- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
+++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
@@ -7,7 +7,7 @@ use core::{marker::PhantomPinned, pin::Pin};
 
 /// The `unsafe_pin_internals` is indeed unsound.
 fn non_unsafe_pin_new_unchecked<T>(pointer: &mut T) -> Pin<&mut T> {
-    Pin { pointer }
+    Pin { __pointer: pointer }
 }
 
 fn main() {
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-bench.rs b/tests/ui/feature-gates/issue-43106-gating-of-bench.rs
index 796325b79af..841383a008f 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-bench.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-bench.rs
@@ -5,6 +5,5 @@
 #![feature(custom_inner_attributes)]
 
 #![bench                   = "4100"]
-//~^ ERROR cannot determine resolution for the attribute macro `bench`
-//~^^ ERROR `bench` attribute cannot be used at crate level
+//~^ ERROR `bench` attribute cannot be used at crate level
 fn main() {}
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr b/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr
index 8270d46d492..912c2746f38 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr
@@ -1,17 +1,9 @@
-error: cannot determine resolution for the attribute macro `bench`
-  --> $DIR/issue-43106-gating-of-bench.rs:7:4
-   |
-LL | #![bench                   = "4100"]
-   |    ^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: `bench` attribute cannot be used at crate level
   --> $DIR/issue-43106-gating-of-bench.rs:7:1
    |
 LL | #![bench                   = "4100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
+LL |
 LL | fn main() {}
    |    ---- the inner attribute doesn't annotate this function
    |
@@ -21,5 +13,5 @@ LL - #![bench                   = "4100"]
 LL + #[bench                   = "4100"]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-test.rs b/tests/ui/feature-gates/issue-43106-gating-of-test.rs
index 39835c9268e..38c92d933fd 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-test.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-test.rs
@@ -2,6 +2,5 @@
 
 #![allow(soft_unstable)]
 #![test                    = "4200"]
-//~^ ERROR cannot determine resolution for the attribute macro `test`
-//~^^ ERROR `test` attribute cannot be used at crate level
+//~^ ERROR `test` attribute cannot be used at crate level
 fn main() {}
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-test.stderr b/tests/ui/feature-gates/issue-43106-gating-of-test.stderr
index 922c9861aa3..2fc220dc47b 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-test.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-test.stderr
@@ -1,17 +1,9 @@
-error: cannot determine resolution for the attribute macro `test`
-  --> $DIR/issue-43106-gating-of-test.rs:4:4
-   |
-LL | #![test                    = "4200"]
-   |    ^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: `test` attribute cannot be used at crate level
   --> $DIR/issue-43106-gating-of-test.rs:4:1
    |
 LL | #![test                    = "4200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
+LL |
 LL | fn main() {}
    |    ---- the inner attribute doesn't annotate this function
    |
@@ -21,5 +13,5 @@ LL - #![test                    = "4200"]
 LL + #[test                    = "4200"]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr
index 28dbdf4c374..3d753b9c8b8 100644
--- a/tests/ui/for/issue-20605.next.stderr
+++ b/tests/ui/for/issue-20605.next.stderr
@@ -34,15 +34,11 @@ error: the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIte
 LL |     for item in *things { *item = 0 }
    |                 ^^^^^^^
 
-error[E0277]: the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
-  --> $DIR/issue-20605.rs:5:9
+error: the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
+  --> $DIR/issue-20605.rs:5:17
    |
 LL |     for item in *things { *item = 0 }
-   |         ^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item`
-   = note: all local variables must have a statically known size
-   = help: unsized locals are gated as an unstable feature
+   |                 ^^^^^^^
 
 error[E0277]: the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
   --> $DIR/issue-20605.rs:5:5
@@ -54,11 +50,15 @@ LL |     for item in *things { *item = 0 }
 note: required by a bound in `None`
   --> $SRC_DIR/core/src/option.rs:LL:COL
 
-error: the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
-  --> $DIR/issue-20605.rs:5:17
+error[E0277]: the size for values of type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be known at compilation time
+  --> $DIR/issue-20605.rs:5:9
    |
 LL |     for item in *things { *item = 0 }
-   |                 ^^^^^^^
+   |         ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item`
+   = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0614]: type `<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item` cannot be dereferenced
   --> $DIR/issue-20605.rs:5:27
diff --git a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr
index 3a973d356dc..7813370ae63 100644
--- a/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr
+++ b/tests/ui/generic-associated-types/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.stderr
@@ -19,16 +19,10 @@ error[E0599]: the size for values of type `Node<i32, RcFamily>` cannot be known
   --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:31:35
    |
 LL | enum Node<T, P: PointerFamily> {
-   | ------------------------------
-   | |
-   | variant or associated item `new` not found for this enum
-   | doesn't satisfy `Node<i32, RcFamily>: Sized`
+   | ------------------------------ variant or associated item `new` not found for this enum because it doesn't satisfy `Node<i32, RcFamily>: Sized`
 ...
 LL |     let mut list = RcNode::<i32>::new();
    |                                   ^^^ doesn't have a size known at compile-time
-  --> $SRC_DIR/core/src/ops/deref.rs:LL:COL
-   |
-   = note: doesn't satisfy `_: Sized`
    |
 note: trait bound `Node<i32, RcFamily>: Sized` was not satisfied
   --> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:4:18
diff --git a/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs
index 83655341d6a..add4d58f86a 100644
--- a/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs
+++ b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs
@@ -16,9 +16,7 @@ impl<T: X<Y<i32> = i32>> M for T {}
 //~| NOTE
 
 struct S;
-//~^ NOTE method `f` not found for this
-//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32`
-//~| NOTE doesn't satisfy `S: M`
+//~^ NOTE method `f` not found for this struct because it doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
 
 impl X for S {
     type Y<T> = bool;
diff --git a/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr
index 7ca0b2912a6..1dd463f996c 100644
--- a/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr
+++ b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr
@@ -1,12 +1,8 @@
 error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
-  --> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7
+  --> $DIR/method-unsatisfied-assoc-type-predicate.rs:26:7
    |
 LL | struct S;
-   | --------
-   | |
-   | method `f` not found for this struct
-   | doesn't satisfy `<S as X>::Y<i32> = i32`
-   | doesn't satisfy `S: M`
+   | -------- method `f` not found for this struct because it doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
 ...
 LL |     a.f();
    |       ^ method cannot be called on `S` due to unsatisfied trait bounds
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
index 55353999b67..0c050c550c4 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
@@ -17,12 +17,18 @@ fn main() {
         }
         match x as i32 {
             0..5+1 => errors_only.push(x),
-            //~^ error: expected one of `=>`, `if`, or `|`, found `+`
+            //~^ error: expected a pattern range bound, found an expression
+            //~| error: exclusive range pattern syntax is experimental
             1 | -3..0 => first_or.push(x),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ (0..5 | 6) => or_two.push(y),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+            //~^ error: exclusive range pattern syntax is experimental
+            //~| error: inline-const in pattern position is experimental
             y @ -5.. => range_from.push(y),
             y @ ..-7 => assert_eq!(y, -8),
+            //~^ error: exclusive range pattern syntax is experimental
             y => bottom.push(y),
         }
     }
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
index cf3bde9705b..cc481f7a79e 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -1,8 +1,8 @@
-error: expected one of `=>`, `if`, or `|`, found `+`
-  --> $DIR/range_pat_interactions1.rs:19:17
+error: expected a pattern range bound, found an expression
+  --> $DIR/range_pat_interactions1.rs:19:16
    |
 LL |             0..5+1 => errors_only.push(x),
-   |                 ^ expected one of `=>`, `if`, or `|`
+   |                ^^^ arbitrary expressions are not allowed in patterns
 
 error[E0408]: variable `n` is not bound in all patterns
   --> $DIR/range_pat_interactions1.rs:10:25
@@ -12,6 +12,16 @@ LL |         if let n @ 2..3|4 = x {
    |                |
    |                variable not in all patterns
 
+error[E0658]: inline-const in pattern position is experimental
+  --> $DIR/range_pat_interactions1.rs:26:20
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                    ^^^^^
+   |
+   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
+   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0658]: exclusive range pattern syntax is experimental
   --> $DIR/range_pat_interactions1.rs:10:20
    |
@@ -34,7 +44,62 @@ LL |         } else if let 2..3 | 4 = x {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: use an inclusive range pattern, like N..=M
 
-error: aborting due to 4 previous errors
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:19:13
+   |
+LL |             0..5+1 => errors_only.push(x),
+   |             ^^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:22:17
+   |
+LL |             1 | -3..0 => first_or.push(x),
+   |                 ^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:24:18
+   |
+LL |             y @ (0..5 | 6) => or_two.push(y),
+   |                  ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:26:17
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                 ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:30:17
+   |
+LL |             y @ ..-7 => assert_eq!(y, -8),
+   |                 ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0408, E0658.
 For more information about an error, try `rustc --explain E0408`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
index 0e96cfe7858..068104c4b1b 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
@@ -8,12 +8,18 @@ fn main() {
     for x in -9 + 1..=(9 - 2) {
         match x as i32 {
             0..=(5+1) => errors_only.push(x),
-            //~^ error: expected `)`, found `+`
+            //~^ error: expected a pattern range bound, found an expression
+            //~| error: range pattern bounds cannot have parentheses
             1 | -3..0 => first_or.push(x),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ (0..5 | 6) => or_two.push(y),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+            //~^ error: inline-const in pattern position is experimental
+            //~| error: exclusive range pattern syntax is experimental
             y @ -5.. => range_from.push(y),
             y @ ..-7 => assert_eq!(y, -8),
+            //~^ error: exclusive range pattern syntax is experimental
             y => bottom.push(y),
         }
     }
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
index a54f29a3b32..8f21a6149fb 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
@@ -1,8 +1,75 @@
-error: expected `)`, found `+`
-  --> $DIR/range_pat_interactions2.rs:10:19
+error: expected a pattern range bound, found an expression
+  --> $DIR/range_pat_interactions2.rs:10:18
    |
 LL |             0..=(5+1) => errors_only.push(x),
-   |                   ^ expected `)`
+   |                  ^^^ arbitrary expressions are not allowed in patterns
 
-error: aborting due to 1 previous error
+error: range pattern bounds cannot have parentheses
+  --> $DIR/range_pat_interactions2.rs:10:17
+   |
+LL |             0..=(5+1) => errors_only.push(x),
+   |                 ^   ^
+   |
+help: remove these parentheses
+   |
+LL -             0..=(5+1) => errors_only.push(x),
+LL +             0..=5+1 => errors_only.push(x),
+   |
+
+error[E0658]: inline-const in pattern position is experimental
+  --> $DIR/range_pat_interactions2.rs:17:20
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                    ^^^^^
+   |
+   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
+   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:13:17
+   |
+LL |             1 | -3..0 => first_or.push(x),
+   |                 ^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:15:18
+   |
+LL |             y @ (0..5 | 6) => or_two.push(y),
+   |                  ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:17:17
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                 ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:21:17
+   |
+LL |             y @ ..-7 => assert_eq!(y, -8),
+   |                 ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error: aborting due to 7 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr b/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr
index 77aa37cefe3..b322ea41c43 100644
--- a/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr
@@ -2,7 +2,7 @@ error[E0277]: expected a `Fn(&'w ())` closure, found `fn(&'w ())`
   --> $DIR/fn-ptr.rs:12:5
    |
 LL |     ice();
-   |     ^^^ expected an `Fn(&'w ())` closure, found `fn(&'w ())`
+   |     ^^^^^ expected an `Fn(&'w ())` closure, found `fn(&'w ())`
    |
    = help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())`
 note: required by a bound in `ice`
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
index 4f9ceb577c0..73870703cfb 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
@@ -2,10 +2,7 @@ error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@issue
   --> $DIR/issue-30786.rs:120:22
    |
 LL | pub struct Map<S, F> {
-   | --------------------
-   | |
-   | method `filterx` not found for this struct
-   | doesn't satisfy `_: StreamExt`
+   | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
 ...
 LL |     let filter = map.filterx(|x: &_| true);
    |                      ^^^^^^^ method cannot be called on `Map<Repeat, {closure@issue-30786.rs:119:27}>` due to unsatisfied trait bounds
@@ -23,10 +20,7 @@ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64)
   --> $DIR/issue-30786.rs:132:24
    |
 LL | pub struct Filter<S, F> {
-   | -----------------------
-   | |
-   | method `countx` not found for this struct
-   | doesn't satisfy `_: StreamExt`
+   | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt`
 ...
 LL |     let count = filter.countx();
    |                        ^^^^^^ method cannot be called due to unsatisfied trait bounds
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr
index 3240518fbbe..e60531a876b 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied
   --> $DIR/issue-85455.rs:8:5
    |
 LL |     callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
index a2ec96f1a2d..f42fc59536c 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
@@ -2,13 +2,13 @@ error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satis
   --> $DIR/norm-before-method-resolution.rs:22:17
    |
 LL |     let _: () = weird_bound();
-   |                 ^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out`
+   |                 ^^^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out`
    |
 note: this is a known limitation of the trait solver that will be lifted in the future
   --> $DIR/norm-before-method-resolution.rs:22:17
    |
 LL |     let _: () = weird_bound();
-   |                 ^^^^^^^^^^^ try adding turbofish arguments to this expression to specify the types manually, even if it's redundant
+   |                 ^^^^^^^^^^^^^ try adding turbofish arguments to this expression to specify the types manually, even if it's redundant
 note: required by a bound in `weird_bound`
   --> $DIR/norm-before-method-resolution.rs:18:40
    |
diff --git a/tests/ui/impl-trait/cross-return-site-inference.stderr b/tests/ui/impl-trait/cross-return-site-inference.stderr
index 8ee3e9abf9c..5512c234af9 100644
--- a/tests/ui/impl-trait/cross-return-site-inference.stderr
+++ b/tests/ui/impl-trait/cross-return-site-inference.stderr
@@ -13,7 +13,7 @@ error[E0790]: cannot call associated function on trait without specifying the co
   --> $DIR/cross-return-site-inference.rs:38:16
    |
 LL |     return Err(From::from("foo"));
-   |                ^^^^^^^^^^ cannot call associated function of trait
+   |                ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use a fully-qualified path to a specific available implementation
    |
@@ -24,7 +24,7 @@ error[E0790]: cannot call associated function on trait without specifying the co
   --> $DIR/cross-return-site-inference.rs:44:9
    |
 LL |     Err(From::from("foo"))
-   |         ^^^^^^^^^^ cannot call associated function of trait
+   |         ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use a fully-qualified path to a specific available implementation
    |
diff --git a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.rs b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.rs
index 650cb3870d5..daf29a0005d 100644
--- a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.rs
+++ b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.rs
@@ -20,7 +20,6 @@ impl dyn MyTrait {
         MyTrait::foo(&self)
         //~^ ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
         //~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-        //~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
         //~| ERROR the trait `MyTrait` cannot be made into an object
     }
 }
diff --git a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.stderr b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.stderr
index 01de3e53195..90285d512ef 100644
--- a/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.stderr
+++ b/tests/ui/impl-trait/in-trait/cycle-effective-visibilities-during-object-safety.stderr
@@ -32,14 +32,6 @@ LL |         MyTrait::foo(&self)
    |
    = help: the trait `MyTrait` is implemented for `Outer`
 
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/cycle-effective-visibilities-during-object-safety.rs:20:9
-   |
-LL |         MyTrait::foo(&self)
-   |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
 error[E0038]: the trait `MyTrait` cannot be made into an object
   --> $DIR/cycle-effective-visibilities-during-object-safety.rs:16:6
    |
@@ -72,7 +64,7 @@ LL |     fn foo(&self) -> impl Marker;
    = help: consider moving `foo` to another trait
    = help: only type `Outer` implements the trait, consider using it directly instead
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0038, E0277.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.rs b/tests/ui/impl-trait/in-trait/issue-102140.rs
index 7960018482f..9d703cf0df1 100644
--- a/tests/ui/impl-trait/in-trait/issue-102140.rs
+++ b/tests/ui/impl-trait/in-trait/issue-102140.rs
@@ -20,7 +20,6 @@ impl dyn MyTrait {
         MyTrait::foo(&self)
         //~^ ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
         //~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-        //~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
     }
 }
 
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.stderr
index 9cd2cdfd1a5..dc3dcc114ae 100644
--- a/tests/ui/impl-trait/in-trait/issue-102140.stderr
+++ b/tests/ui/impl-trait/in-trait/issue-102140.stderr
@@ -20,14 +20,6 @@ LL |         MyTrait::foo(&self)
    |
    = help: the trait `MyTrait` is implemented for `Outer`
 
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:20:9
-   |
-LL |         MyTrait::foo(&self)
-   |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/imports/issue-28134.rs b/tests/ui/imports/issue-28134.rs
index ef2a5d634a6..0cecdf7a0ec 100644
--- a/tests/ui/imports/issue-28134.rs
+++ b/tests/ui/imports/issue-28134.rs
@@ -1,5 +1,5 @@
 // compile-flags: --test
 
 #![allow(soft_unstable)]
-#![test] //~ ERROR cannot determine resolution for the attribute macro `test`
+#![test]
 //~^ ERROR 4:1: 4:9: `test` attribute cannot be used at crate level
diff --git a/tests/ui/imports/issue-28134.stderr b/tests/ui/imports/issue-28134.stderr
index 5315c2e9fee..e47aa15e87a 100644
--- a/tests/ui/imports/issue-28134.stderr
+++ b/tests/ui/imports/issue-28134.stderr
@@ -1,11 +1,3 @@
-error: cannot determine resolution for the attribute macro `test`
-  --> $DIR/issue-28134.rs:4:4
-   |
-LL | #![test]
-   |    ^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: `test` attribute cannot be used at crate level
   --> $DIR/issue-28134.rs:4:1
    |
@@ -18,5 +10,5 @@ LL - #![test]
 LL + #[test]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/imports/issue-55457.rs b/tests/ui/imports/issue-55457.rs
index c1f048897d9..fd082940255 100644
--- a/tests/ui/imports/issue-55457.rs
+++ b/tests/ui/imports/issue-55457.rs
@@ -1,10 +1,9 @@
 use NonExistent; //~ ERROR unresolved import `NonExistent`
 use non_existent::non_existent; //~ ERROR unresolved import `non_existent`
 
-#[non_existent] //~ ERROR cannot determine resolution for the attribute macro `non_existent`
-#[derive(NonExistent)] //~ ERROR cannot determine resolution for the derive macro `NonExistent`
-                       //~| ERROR cannot determine resolution for the derive macro `NonExistent`
-                       //~| ERROR cannot determine resolution for the derive macro `NonExistent`
+#[non_existent]
+#[derive(NonExistent)]
+
 struct S;
 
 fn main() {}
diff --git a/tests/ui/imports/issue-55457.stderr b/tests/ui/imports/issue-55457.stderr
index 30d2373652b..09bb13a0604 100644
--- a/tests/ui/imports/issue-55457.stderr
+++ b/tests/ui/imports/issue-55457.stderr
@@ -15,40 +15,6 @@ LL | use non_existent::non_existent;
    |
    = help: consider adding `extern crate non_existent` to use the `non_existent` crate
 
-error: cannot determine resolution for the derive macro `NonExistent`
-  --> $DIR/issue-55457.rs:5:10
-   |
-LL | #[derive(NonExistent)]
-   |          ^^^^^^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: cannot determine resolution for the attribute macro `non_existent`
-  --> $DIR/issue-55457.rs:4:3
-   |
-LL | #[non_existent]
-   |   ^^^^^^^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: cannot determine resolution for the derive macro `NonExistent`
-  --> $DIR/issue-55457.rs:5:10
-   |
-LL | #[derive(NonExistent)]
-   |          ^^^^^^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: cannot determine resolution for the derive macro `NonExistent`
-  --> $DIR/issue-55457.rs:5:10
-   |
-LL | #[derive(NonExistent)]
-   |          ^^^^^^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/imports/issue-59764.rs b/tests/ui/imports/issue-59764.rs
index 09dee8c2732..91b3ddcd84d 100644
--- a/tests/ui/imports/issue-59764.rs
+++ b/tests/ui/imports/issue-59764.rs
@@ -128,7 +128,6 @@ use issue_59764::foo::makro;
 //~^ ERROR unresolved import `issue_59764::foo::makro` [E0432]
 
 makro!(bar);
-//~^ ERROR cannot determine resolution for the macro `makro`
 
 fn main() {
     bar();
diff --git a/tests/ui/imports/issue-59764.stderr b/tests/ui/imports/issue-59764.stderr
index b969515e2f0..fe58eb97b8d 100644
--- a/tests/ui/imports/issue-59764.stderr
+++ b/tests/ui/imports/issue-59764.stderr
@@ -226,21 +226,13 @@ help: a macro with this name exists at the root of the crate
 LL | use issue_59764::makro;
    |     ~~~~~~~~~~~~~~~~~~
 
-error: cannot determine resolution for the macro `makro`
-  --> $DIR/issue-59764.rs:130:1
-   |
-LL | makro!(bar);
-   | ^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error[E0425]: cannot find function `bar` in this scope
-  --> $DIR/issue-59764.rs:134:5
+  --> $DIR/issue-59764.rs:133:5
    |
 LL |     bar();
    |     ^^^ not found in this scope
 
-error: aborting due to 18 previous errors
+error: aborting due to 17 previous errors
 
 Some errors have detailed explanations: E0425, E0432.
 For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/inference/erase-type-params-in-label.stderr b/tests/ui/inference/erase-type-params-in-label.stderr
index 9be18286480..546e679f2d0 100644
--- a/tests/ui/inference/erase-type-params-in-label.stderr
+++ b/tests/ui/inference/erase-type-params-in-label.stderr
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>`
   --> $DIR/erase-type-params-in-label.rs:2:9
    |
 LL |     let foo = foo(1, "");
-   |         ^^^   --- type must be known at this point
+   |         ^^^   ---------- type must be known at this point
    |
    = note: cannot satisfy `_: Default`
 note: required by a bound in `foo`
@@ -19,7 +19,7 @@ error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
   --> $DIR/erase-type-params-in-label.rs:5:9
    |
 LL |     let bar = bar(1, "");
-   |         ^^^   --- type must be known at this point
+   |         ^^^   ---------- type must be known at this point
    |
    = note: cannot satisfy `_: Default`
 note: required by a bound in `bar`
diff --git a/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr b/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr
index aeebf68e675..5576e175468 100644
--- a/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr
+++ b/tests/ui/inference/need_type_info/infer-var-for-self-param.stderr
@@ -2,7 +2,7 @@ error[E0790]: cannot call associated function on trait without specifying the co
   --> $DIR/infer-var-for-self-param.rs:5:14
    |
 LL |     let _ = (Default::default(),);
-   |              ^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |              ^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use a fully-qualified path to a specific available implementation
    |
diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr
index a33f49baf54..cc7053bf385 100644
--- a/tests/ui/inference/need_type_info/type-alias.stderr
+++ b/tests/ui/inference/need_type_info/type-alias.stderr
@@ -2,13 +2,13 @@ error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:12:5
    |
 LL |     DirectAlias::new()
-   |     ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+   |     ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
 
 error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:32:5
    |
 LL |     DirectButWithDefaultAlias::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.rs b/tests/ui/inline-const/const-match-pat-lifetime-err.rs
index 366ad26bb27..ce91e5233bc 100644
--- a/tests/ui/inline-const/const-match-pat-lifetime-err.rs
+++ b/tests/ui/inline-const/const-match-pat-lifetime-err.rs
@@ -1,5 +1,3 @@
-// ignore-test (This is currently broken)
-
 #![allow(incomplete_features)]
 #![feature(const_mut_refs)]
 #![feature(inline_const_pat)]
@@ -9,6 +7,9 @@ use std::marker::PhantomData;
 #[derive(PartialEq, Eq)]
 pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
 
+#[derive(PartialEq, Eq)]
+pub struct CovariantRef<'a, T: ?Sized>(&'a T);
+
 impl<'a, T: ?Sized> InvariantRef<'a, T> {
     pub const fn new(r: &'a T) -> Self {
         InvariantRef(r, PhantomData)
@@ -19,16 +20,30 @@ impl<'a> InvariantRef<'a, ()> {
     pub const NEW: Self = InvariantRef::new(&());
 }
 
+impl<'a> CovariantRef<'a, ()> {
+    pub const NEW: Self = CovariantRef(&());
+}
+
 fn match_invariant_ref<'a>() {
     let y = ();
     match InvariantRef::new(&y) {
-    //~^ ERROR `y` does not live long enough [E0597]
-        // FIXME(nbdd0121): This should give the same error as `InvariantRef::<'a>::NEW` (without
-        // const block)
+        //~^ ERROR `y` does not live long enough [E0597]
         const { InvariantRef::<'a>::NEW } => (),
     }
 }
 
+fn match_covariant_ref<'a>() {
+    // Unclear if we should error here (should we be able to subtype the type of
+    // `y.0`), but using the associated const directly in the pattern also
+    // errors.
+    let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
+    //~^ ERROR lifetime may not live long enough
+    match y.0 {
+        const { CovariantRef::<'a>::NEW } => (),
+    }
+}
+
 fn main() {
     match_invariant_ref();
+    match_covariant_ref();
 }
diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.stderr b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr
new file mode 100644
index 00000000000..c5760f1027e
--- /dev/null
+++ b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr
@@ -0,0 +1,28 @@
+error[E0597]: `y` does not live long enough
+  --> $DIR/const-match-pat-lifetime-err.rs:29:29
+   |
+LL | fn match_invariant_ref<'a>() {
+   |                        -- lifetime `'a` defined here
+LL |     let y = ();
+   |         - binding `y` declared here
+LL |     match InvariantRef::new(&y) {
+   |                             ^^ borrowed value does not live long enough
+LL |
+LL |         const { InvariantRef::<'a>::NEW } => (),
+   |         --------------------------------- type annotation requires that `y` is borrowed for `'a`
+LL |     }
+LL | }
+   | - `y` dropped here while still borrowed
+
+error: lifetime may not live long enough
+  --> $DIR/const-match-pat-lifetime-err.rs:39:12
+   |
+LL | fn match_covariant_ref<'a>() {
+   |                        -- lifetime `'a` defined here
+...
+LL |     let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/inline-const/pat-unsafe-err.rs b/tests/ui/inline-const/pat-unsafe-err.rs
index 0db18dd3260..7680c82efb5 100644
--- a/tests/ui/inline-const/pat-unsafe-err.rs
+++ b/tests/ui/inline-const/pat-unsafe-err.rs
@@ -1,5 +1,3 @@
-// ignore-test This is currently broken
-
 #![allow(incomplete_features)]
 #![feature(inline_const_pat)]
 
diff --git a/tests/ui/inline-const/pat-unsafe-err.stderr b/tests/ui/inline-const/pat-unsafe-err.stderr
new file mode 100644
index 00000000000..9b995d6ccf2
--- /dev/null
+++ b/tests/ui/inline-const/pat-unsafe-err.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
+  --> $DIR/pat-unsafe-err.rs:11:13
+   |
+LL |             require_unsafe();
+   |             ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
+  --> $DIR/pat-unsafe-err.rs:18:13
+   |
+LL |             require_unsafe()
+   |             ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/inline-const/pat-unsafe.rs b/tests/ui/inline-const/pat-unsafe.rs
index cfef9ad6a56..f7073ef40eb 100644
--- a/tests/ui/inline-const/pat-unsafe.rs
+++ b/tests/ui/inline-const/pat-unsafe.rs
@@ -1,5 +1,4 @@
 // check-pass
-// ignore-test This is currently broken
 
 #![allow(incomplete_features)]
 #![warn(unused_unsafe)]
diff --git a/tests/ui/inline-const/pat-unsafe.stderr b/tests/ui/inline-const/pat-unsafe.stderr
new file mode 100644
index 00000000000..84dc10c4902
--- /dev/null
+++ b/tests/ui/inline-const/pat-unsafe.stderr
@@ -0,0 +1,20 @@
+warning: unnecessary `unsafe` block
+  --> $DIR/pat-unsafe.rs:16:17
+   |
+LL |                 unsafe {}
+   |                 ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/pat-unsafe.rs:4:9
+   |
+LL | #![warn(unused_unsafe)]
+   |         ^^^^^^^^^^^^^
+
+warning: unnecessary `unsafe` block
+  --> $DIR/pat-unsafe.rs:23:17
+   |
+LL |                 unsafe {}
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/internal/internal-unstable.rs b/tests/ui/internal/internal-unstable.rs
index 1eb27fbdc3a..a4445fefef5 100644
--- a/tests/ui/internal/internal-unstable.rs
+++ b/tests/ui/internal/internal-unstable.rs
@@ -28,6 +28,14 @@ macro_rules! bar {
     }}
 }
 
+#[allow_internal_unstable(stmt_expr_attributes)]
+macro_rules! internal_attr {
+    ($e: expr) => {
+        #[allow(overflowing_literals)]
+        $e
+    }
+}
+
 fn main() {
     // ok, the instability is contained.
     call_unstable_allow!();
@@ -51,4 +59,6 @@ fn main() {
         #[allow_internal_unstable]
         _ => {}
     }
+
+    assert_eq!(internal_attr!(1e100_f32), f32::INFINITY);
 }
diff --git a/tests/ui/internal/internal-unstable.stderr b/tests/ui/internal/internal-unstable.stderr
index af5ac21e696..78b9109d1c2 100644
--- a/tests/ui/internal/internal-unstable.stderr
+++ b/tests/ui/internal/internal-unstable.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:40:25
+  --> $DIR/internal-unstable.rs:48:25
    |
 LL |     pass_through_allow!(internal_unstable::unstable());
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     pass_through_allow!(internal_unstable::unstable());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:42:27
+  --> $DIR/internal-unstable.rs:50:27
    |
 LL |     pass_through_noallow!(internal_unstable::unstable());
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     pass_through_noallow!(internal_unstable::unstable());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:46:22
+  --> $DIR/internal-unstable.rs:54:22
    |
 LL |     println!("{:?}", internal_unstable::unstable());
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     println!("{:?}", internal_unstable::unstable());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:48:10
+  --> $DIR/internal-unstable.rs:56:10
    |
 LL |     bar!(internal_unstable::unstable());
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/issues/auxiliary/issue-1920.rs b/tests/ui/issues/issue-1920-absolute-paths/auxiliary/issue-1920.rs
index 1548cb99563..1548cb99563 100644
--- a/tests/ui/issues/auxiliary/issue-1920.rs
+++ b/tests/ui/issues/issue-1920-absolute-paths/auxiliary/issue-1920.rs
diff --git a/tests/ui/issues/issue-1920-1.rs b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-1.rs
index 26553f56b84..26553f56b84 100644
--- a/tests/ui/issues/issue-1920-1.rs
+++ b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-1.rs
diff --git a/tests/ui/issues/issue-1920-1.stderr b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-1.stderr
index b7c7da00672..b7c7da00672 100644
--- a/tests/ui/issues/issue-1920-1.stderr
+++ b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-1.stderr
diff --git a/tests/ui/issues/issue-1920-2.rs b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-2.rs
index 8d4a5f66310..8d4a5f66310 100644
--- a/tests/ui/issues/issue-1920-2.rs
+++ b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-2.rs
diff --git a/tests/ui/issues/issue-1920-2.stderr b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-2.stderr
index 844cb0ff199..844cb0ff199 100644
--- a/tests/ui/issues/issue-1920-2.stderr
+++ b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-2.stderr
diff --git a/tests/ui/issues/issue-1920-3.rs b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-3.rs
index 520db50f94a..520db50f94a 100644
--- a/tests/ui/issues/issue-1920-3.rs
+++ b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-3.rs
diff --git a/tests/ui/issues/issue-1920-3.stderr b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-3.stderr
index 525ca4685bb..525ca4685bb 100644
--- a/tests/ui/issues/issue-1920-3.stderr
+++ b/tests/ui/issues/issue-1920-absolute-paths/issue-1920-3.stderr
diff --git a/tests/ui/issues/issue-23302-1.rs b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.rs
index 24e79dc5811..24e79dc5811 100644
--- a/tests/ui/issues/issue-23302-1.rs
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.rs
diff --git a/tests/ui/issues/issue-23302-1.stderr b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr
index 53131f9130d..53131f9130d 100644
--- a/tests/ui/issues/issue-23302-1.stderr
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr
diff --git a/tests/ui/issues/issue-23302-2.rs b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.rs
index e89c7eab503..e89c7eab503 100644
--- a/tests/ui/issues/issue-23302-2.rs
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.rs
diff --git a/tests/ui/issues/issue-23302-2.stderr b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr
index d55d88762be..d55d88762be 100644
--- a/tests/ui/issues/issue-23302-2.stderr
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr
diff --git a/tests/ui/issues/issue-23302-3.rs b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-3.rs
index da75f330798..da75f330798 100644
--- a/tests/ui/issues/issue-23302-3.rs
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-3.rs
diff --git a/tests/ui/issues/issue-23302-3.stderr b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-3.stderr
index e23957c6de7..e23957c6de7 100644
--- a/tests/ui/issues/issue-23302-3.stderr
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-3.stderr
diff --git a/tests/ui/issues/issue-32122-1.fixed b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.fixed
index 4fc5f64ff9a..4fc5f64ff9a 100644
--- a/tests/ui/issues/issue-32122-1.fixed
+++ b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.fixed
diff --git a/tests/ui/issues/issue-32122-1.rs b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs
index 3c4859f07a2..3c4859f07a2 100644
--- a/tests/ui/issues/issue-32122-1.rs
+++ b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs
diff --git a/tests/ui/issues/issue-32122-1.stderr b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.stderr
index ae5dffe1fad..ae5dffe1fad 100644
--- a/tests/ui/issues/issue-32122-1.stderr
+++ b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.stderr
diff --git a/tests/ui/issues/issue-32122-2.fixed b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.fixed
index cee0e592976..cee0e592976 100644
--- a/tests/ui/issues/issue-32122-2.fixed
+++ b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.fixed
diff --git a/tests/ui/issues/issue-32122-2.rs b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs
index 39e9df4224e..39e9df4224e 100644
--- a/tests/ui/issues/issue-32122-2.rs
+++ b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs
diff --git a/tests/ui/issues/issue-32122-2.stderr b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.stderr
index eb4327bef62..eb4327bef62 100644
--- a/tests/ui/issues/issue-32122-2.stderr
+++ b/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.stderr
diff --git a/tests/ui/issues/issue-3668-2.fixed b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.fixed
index a95781c6edc..a95781c6edc 100644
--- a/tests/ui/issues/issue-3668-2.fixed
+++ b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.fixed
diff --git a/tests/ui/issues/issue-3668-2.rs b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs
index 8aa0897ecb4..8aa0897ecb4 100644
--- a/tests/ui/issues/issue-3668-2.rs
+++ b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.rs
diff --git a/tests/ui/issues/issue-3668-2.stderr b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.stderr
index 3676f388891..3676f388891 100644
--- a/tests/ui/issues/issue-3668-2.stderr
+++ b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668-2.stderr
diff --git a/tests/ui/issues/issue-3668.rs b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs
index 0e1f19a75ba..0e1f19a75ba 100644
--- a/tests/ui/issues/issue-3668.rs
+++ b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.rs
diff --git a/tests/ui/issues/issue-3668.stderr b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.stderr
index d761b2d87db..d761b2d87db 100644
--- a/tests/ui/issues/issue-3668.stderr
+++ b/tests/ui/issues/issue-3668-non-constant-value-in-constant/issue-3668.stderr
diff --git a/tests/ui/issues/issue-40510-1.migrate.stderr b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr
index 2090530571b..2090530571b 100644
--- a/tests/ui/issues/issue-40510-1.migrate.stderr
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr
diff --git a/tests/ui/issues/issue-40510-1.rs b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.rs
index ca53dcd9b41..ca53dcd9b41 100644
--- a/tests/ui/issues/issue-40510-1.rs
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.rs
diff --git a/tests/ui/issues/issue-40510-1.stderr b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.stderr
index 81fed1305cb..81fed1305cb 100644
--- a/tests/ui/issues/issue-40510-1.stderr
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.stderr
diff --git a/tests/ui/issues/issue-40510-2.rs b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-2.rs
index 3ae84be0578..3ae84be0578 100644
--- a/tests/ui/issues/issue-40510-2.rs
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-2.rs
diff --git a/tests/ui/issues/issue-40510-3.migrate.stderr b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr
index 59aba4a8ef8..59aba4a8ef8 100644
--- a/tests/ui/issues/issue-40510-3.migrate.stderr
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr
diff --git a/tests/ui/issues/issue-40510-3.rs b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.rs
index 181263adcbf..181263adcbf 100644
--- a/tests/ui/issues/issue-40510-3.rs
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.rs
diff --git a/tests/ui/issues/issue-40510-3.stderr b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.stderr
index 43e8a73b819..43e8a73b819 100644
--- a/tests/ui/issues/issue-40510-3.stderr
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.stderr
diff --git a/tests/ui/issues/issue-40510-4.rs b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-4.rs
index 48bb8d36f55..48bb8d36f55 100644
--- a/tests/ui/issues/issue-40510-4.rs
+++ b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-4.rs
diff --git a/tests/ui/issues/issue-56199.stderr b/tests/ui/issues/issue-56199.stderr
index 7aaf8e4ac2f..eb6d7005979 100644
--- a/tests/ui/issues/issue-56199.stderr
+++ b/tests/ui/issues/issue-56199.stderr
@@ -10,7 +10,7 @@ error: the `Self` constructor can only be used with tuple or unit structs
   --> $DIR/issue-56199.rs:8:17
    |
 LL |         let _ = Self();
-   |                 ^^^^
+   |                 ^^^^^^
    |
    = help: did you mean to use one of the enum's variants?
 
@@ -24,7 +24,7 @@ error: the `Self` constructor can only be used with tuple or unit structs
   --> $DIR/issue-56199.rs:17:17
    |
 LL |         let _ = Self();
-   |                 ^^^^ help: use curly brackets: `Self { /* fields */ }`
+   |                 ^^^^^^ help: use curly brackets: `Self { /* fields */ }`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/issues/issue-57741-1.rs b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs
index d0aae23b2fc..d0aae23b2fc 100644
--- a/tests/ui/issues/issue-57741-1.rs
+++ b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs
diff --git a/tests/ui/issues/issue-57741-1.stderr b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr
index 76f03bab6d1..76f03bab6d1 100644
--- a/tests/ui/issues/issue-57741-1.stderr
+++ b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr
diff --git a/tests/ui/issues/issue-57741.fixed b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed
index 4cae080033c..4cae080033c 100644
--- a/tests/ui/issues/issue-57741.fixed
+++ b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed
diff --git a/tests/ui/issues/issue-57741.rs b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs
index e2658295af7..e2658295af7 100644
--- a/tests/ui/issues/issue-57741.rs
+++ b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs
diff --git a/tests/ui/issues/issue-57741.stderr b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr
index 38014ecce75..38014ecce75 100644
--- a/tests/ui/issues/issue-57741.stderr
+++ b/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr
diff --git a/tests/ui/issues/issue-5997-enum.rs b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.rs
index 0b1857ae3df..0b1857ae3df 100644
--- a/tests/ui/issues/issue-5997-enum.rs
+++ b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.rs
diff --git a/tests/ui/issues/issue-5997-enum.stderr b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.stderr
index c0b3cd6de66..c0b3cd6de66 100644
--- a/tests/ui/issues/issue-5997-enum.stderr
+++ b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.stderr
diff --git a/tests/ui/issues/issue-5997-struct.rs b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.rs
index 19d994b0dfb..19d994b0dfb 100644
--- a/tests/ui/issues/issue-5997-struct.rs
+++ b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.rs
diff --git a/tests/ui/issues/issue-5997-struct.stderr b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.stderr
index 670a54894b5..670a54894b5 100644
--- a/tests/ui/issues/issue-5997-struct.stderr
+++ b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.stderr
diff --git a/tests/ui/issues/issue-5997.rs b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs
index 145e3a7928d..145e3a7928d 100644
--- a/tests/ui/issues/issue-5997.rs
+++ b/tests/ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs
diff --git a/tests/ui/issues/issue-71676-1.fixed b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.fixed
index cbc0e8c061b..cbc0e8c061b 100644
--- a/tests/ui/issues/issue-71676-1.fixed
+++ b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.fixed
diff --git a/tests/ui/issues/issue-71676-1.rs b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.rs
index 6e87c7174c6..6e87c7174c6 100644
--- a/tests/ui/issues/issue-71676-1.rs
+++ b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.rs
diff --git a/tests/ui/issues/issue-71676-1.stderr b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.stderr
index 164641ff775..164641ff775 100644
--- a/tests/ui/issues/issue-71676-1.stderr
+++ b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.stderr
diff --git a/tests/ui/issues/issue-71676-2.rs b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.rs
index f3183899dc5..f3183899dc5 100644
--- a/tests/ui/issues/issue-71676-2.rs
+++ b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.rs
diff --git a/tests/ui/issues/issue-71676-2.stderr b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.stderr
index 6ed318c8768..6ed318c8768 100644
--- a/tests/ui/issues/issue-71676-2.stderr
+++ b/tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.stderr
diff --git a/tests/ui/issues/issue-76077-1.fixed b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.fixed
index 8103a7ca47d..8103a7ca47d 100644
--- a/tests/ui/issues/issue-76077-1.fixed
+++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.fixed
diff --git a/tests/ui/issues/issue-76077-1.rs b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs
index 730332853c1..730332853c1 100644
--- a/tests/ui/issues/issue-76077-1.rs
+++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs
diff --git a/tests/ui/issues/issue-76077-1.stderr b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr
index 8e77662b4ba..8e77662b4ba 100644
--- a/tests/ui/issues/issue-76077-1.stderr
+++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr
diff --git a/tests/ui/issues/issue-76077.rs b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs
index 2d29093b01b..2d29093b01b 100644
--- a/tests/ui/issues/issue-76077.rs
+++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs
diff --git a/tests/ui/issues/issue-76077.stderr b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.stderr
index 3fef5ffce30..3fef5ffce30 100644
--- a/tests/ui/issues/issue-76077.stderr
+++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077.stderr
diff --git a/tests/ui/iterators/issue-28098.rs b/tests/ui/iterators/issue-28098.rs
index 80c77edae9e..62a90d90d12 100644
--- a/tests/ui/iterators/issue-28098.rs
+++ b/tests/ui/iterators/issue-28098.rs
@@ -2,14 +2,12 @@ fn main() {
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
     //~| ERROR `()` is not an iterator
-    //~| ERROR `()` is not an iterator
 
     for _ in false {}
     //~^ ERROR `bool` is not an iterator
 
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
-    //~| ERROR `()` is not an iterator
 
     other()
 }
@@ -20,11 +18,9 @@ pub fn other() {
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
     //~| ERROR `()` is not an iterator
-    //~| ERROR `()` is not an iterator
 
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
-    //~| ERROR `()` is not an iterator
 
     for _ in false {}
     //~^ ERROR `bool` is not an iterator
diff --git a/tests/ui/iterators/issue-28098.stderr b/tests/ui/iterators/issue-28098.stderr
index 3256e57d436..a724f03ad4a 100644
--- a/tests/ui/iterators/issue-28098.stderr
+++ b/tests/ui/iterators/issue-28098.stderr
@@ -8,16 +8,8 @@ LL |     let _ = Iterator::next(&mut ());
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:2:13
-   |
-LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
 error[E0277]: `bool` is not an iterator
-  --> $DIR/issue-28098.rs:7:14
+  --> $DIR/issue-28098.rs:6:14
    |
 LL |     for _ in false {}
    |              ^^^^^ `bool` is not an iterator
@@ -26,7 +18,7 @@ LL |     for _ in false {}
    = note: required for `bool` to implement `IntoIterator`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:10:28
+  --> $DIR/issue-28098.rs:9:28
    |
 LL |     let _ = Iterator::next(&mut ());
    |             -------------- ^^^^^^^ `()` is not an iterator
@@ -36,23 +28,15 @@ LL |     let _ = Iterator::next(&mut ());
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:10:13
-   |
-LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
-error[E0277]: `()` is not an iterator
   --> $DIR/issue-28098.rs:2:13
    |
 LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:20:28
+  --> $DIR/issue-28098.rs:18:28
    |
 LL |     let _ = Iterator::next(&mut ());
    |             -------------- ^^^^^^^ `()` is not an iterator
@@ -62,15 +46,7 @@ LL |     let _ = Iterator::next(&mut ());
    = help: the trait `Iterator` is not implemented for `()`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:20:13
-   |
-LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:25:28
+  --> $DIR/issue-28098.rs:22:28
    |
 LL |     let _ = Iterator::next(&mut ());
    |             -------------- ^^^^^^^ `()` is not an iterator
@@ -79,16 +55,8 @@ LL |     let _ = Iterator::next(&mut ());
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:25:13
-   |
-LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
 error[E0277]: `bool` is not an iterator
-  --> $DIR/issue-28098.rs:29:14
+  --> $DIR/issue-28098.rs:25:14
    |
 LL |     for _ in false {}
    |              ^^^^^ `bool` is not an iterator
@@ -97,13 +65,13 @@ LL |     for _ in false {}
    = note: required for `bool` to implement `IntoIterator`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:20:13
+  --> $DIR/issue-28098.rs:18:13
    |
 LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error: aborting due to 12 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/vec-on-unimplemented.stderr b/tests/ui/iterators/vec-on-unimplemented.stderr
index e2a80dbffde..29b19d5e3b4 100644
--- a/tests/ui/iterators/vec-on-unimplemented.stderr
+++ b/tests/ui/iterators/vec-on-unimplemented.stderr
@@ -3,9 +3,6 @@ error[E0599]: `Vec<bool>` is not an iterator
    |
 LL |     vec![true, false].map(|v| !v).collect::<Vec<_>>();
    |                       ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-   |
-   = note: doesn't satisfy `Vec<bool>: Iterator`
    |
    = note: the following trait bounds were not satisfied:
            `Vec<bool>: Iterator`
diff --git a/tests/ui/lang-items/bad-add-impl.rs b/tests/ui/lang-items/bad-add-impl.rs
deleted file mode 100644
index 0c44edbe51a..00000000000
--- a/tests/ui/lang-items/bad-add-impl.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#![feature(no_core)]
-#![feature(lang_items)]
-#![no_core]
-
-#[lang = "sized"]
-trait Sized {}
-
-#[lang = "add"]
-trait Add<T> {
-    const add: u32 = 1u32;
-}
-
-impl Add<u32> for u32 {}
-
-fn main() {
-    1u32 + 1u32;
-    //~^ ERROR cannot add `u32` to `u32`
-}
diff --git a/tests/ui/lang-items/bad-add-impl.stderr b/tests/ui/lang-items/bad-add-impl.stderr
deleted file mode 100644
index c5ad9ff2a08..00000000000
--- a/tests/ui/lang-items/bad-add-impl.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0369]: cannot add `u32` to `u32`
-  --> $DIR/bad-add-impl.rs:16:10
-   |
-LL |     1u32 + 1u32;
-   |     ---- ^ ---- u32
-   |     |
-   |     u32
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr
deleted file mode 100644
index ff603111e94..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr
deleted file mode 100644
index ff603111e94..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:39:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:43:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr
deleted file mode 100644
index 02e33c597fe..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr
deleted file mode 100644
index 02e33c597fe..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr
deleted file mode 100644
index 02e33c597fe..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr
deleted file mode 100644
index 02e33c597fe..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr
deleted file mode 100644
index 02e33c597fe..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr
deleted file mode 100644
index 02e33c597fe..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5
-   |
-LL |     a();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5
-   |
-LL |     b();
-   |     ^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs
deleted file mode 100644
index 757c6538d05..00000000000
--- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// revisions: fn_once_bad_item fn_once_bad_sig fn_mut_bad_item fn_mut_bad_sig fn_bad_item fn_bad_sig
-
-#![feature(lang_items)]
-#![feature(no_core)]
-#![no_core]
-
-#[lang = "sized"]
-trait Sized {}
-
-#[cfg(any(fn_bad_item, fn_bad_sig))]
-#[lang = "fn"]
-trait MyFn<T> {
-    #[cfg(fn_bad_sig)]
-    fn call(i: i32) -> i32 { 0 }
-
-    #[cfg(fn_bad_item)]
-    const call: i32 = 42;
-}
-
-#[cfg(any(fn_mut_bad_item, fn_mut_bad_sig))]
-#[lang = "fn_mut"]
-trait MyFnMut<T> {
-    #[cfg(fn_mut_bad_sig)]
-    fn call_mut(i: i32) -> i32 { 0 }
-
-    #[cfg(fn_mut_bad_item)]
-    const call_mut: i32 = 42;
-}
-
-#[cfg(any(fn_once_bad_item, fn_once_bad_sig))]
-#[lang = "fn_once"]
-trait MyFnOnce<T> {
-    #[cfg(fn_once_bad_sig)]
-    fn call_once(i: i32) -> i32 { 0 }
-
-    #[cfg(fn_once_bad_item)]
-    const call_once: i32 = 42;
-}
-
-fn main() {
-    let a = || 42;
-    a();
-    //~^ ERROR failed to find an overloaded call trait for closure call
-
-    let mut i = 0;
-    let mut b = || { };
-    b();
-    //~^ ERROR failed to find an overloaded call trait for closure call
-}
diff --git a/tests/ui/lang-items/issue-31076.rs b/tests/ui/lang-items/issue-31076.rs
deleted file mode 100644
index cdb196d4ff2..00000000000
--- a/tests/ui/lang-items/issue-31076.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#![feature(no_core, lang_items)]
-#![no_core]
-
-#[lang="sized"]
-trait Sized {}
-
-#[lang="add"]
-trait Add<T> {}
-
-impl Add<i32> for i32 {}
-
-fn main() {
-    let x = 5 + 6;
-    //~^ ERROR cannot add `i32` to `{integer}`
-    let y = 5i32 + 6i32;
-    //~^ ERROR cannot add `i32` to `i32`
-}
diff --git a/tests/ui/lang-items/issue-31076.stderr b/tests/ui/lang-items/issue-31076.stderr
deleted file mode 100644
index ac0d9dc7528..00000000000
--- a/tests/ui/lang-items/issue-31076.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0369]: cannot add `i32` to `{integer}`
-  --> $DIR/issue-31076.rs:13:15
-   |
-LL |     let x = 5 + 6;
-   |             - ^ - i32
-   |             |
-   |             {integer}
-
-error[E0369]: cannot add `i32` to `i32`
-  --> $DIR/issue-31076.rs:15:18
-   |
-LL |     let y = 5i32 + 6i32;
-   |             ---- ^ ---- i32
-   |             |
-   |             i32
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/lang-items/issue-86238.rs b/tests/ui/lang-items/issue-86238.rs
deleted file mode 100644
index 509f94f3834..00000000000
--- a/tests/ui/lang-items/issue-86238.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Regression test for the ICE described in issue #86238.
-
-#![feature(lang_items)]
-#![feature(no_core)]
-
-#![no_core]
-fn main() {
-    let one = || {};
-    one()
-    //~^ ERROR: failed to find an overloaded call trait for closure call
-    //~| HELP: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined
-}
-#[lang = "sized"]
-trait Sized {}
-#[lang = "copy"]
-trait Copy {}
diff --git a/tests/ui/lang-items/issue-86238.stderr b/tests/ui/lang-items/issue-86238.stderr
deleted file mode 100644
index b492904bcc7..00000000000
--- a/tests/ui/lang-items/issue-86238.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: failed to find an overloaded call trait for closure call
-  --> $DIR/issue-86238.rs:9:5
-   |
-LL |     one()
-   |     ^^^^^
-   |
-   = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index 8161f97dde0..0ed743818c5 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -232,7 +232,7 @@ error: layout_of(MultipleAlignments) = Layout {
 LL | enum MultipleAlignments {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: layout_of(Result<[u32; 0], Packed<NonZeroU16>>) = Layout {
+error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
            size: Size(4 bytes),
            align: AbiAndPrefAlign {
                abi: Align(4 bytes),
diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs
index 09fda33dbec..9740742fbbb 100644
--- a/tests/ui/lint/clashing-extern-fn.rs
+++ b/tests/ui/lint/clashing-extern-fn.rs
@@ -436,7 +436,7 @@ mod hidden_niche {
 
             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
             //~^ WARN redeclared with a different signature
-            //~| WARN block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
+            //~| WARN block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
         }
     }
 }
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
index 0d269e599dd..5b9244b6993 100644
--- a/tests/ui/lint/clashing-extern-fn.stderr
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -8,7 +8,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
    = 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
+warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
   --> $DIR/clashing-extern-fn.rs:437:46
    |
 LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
@@ -163,7 +163,7 @@ LL |             fn non_zero_usize() -> core::num::NonZeroUsize;
 LL |             fn non_zero_usize() -> usize;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
-   = note: expected `unsafe extern "C" fn() -> NonZeroUsize`
+   = note: expected `unsafe extern "C" fn() -> NonZero<usize>`
               found `unsafe extern "C" fn() -> usize`
 
 warning: `non_null_ptr` redeclared with a different signature
@@ -224,7 +224,7 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
    = note: expected `unsafe extern "C" fn() -> usize`
-              found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
+              found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
 
 warning: 19 warnings emitted
 
diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr
index 57531b0968f..bdf47343114 100644
--- a/tests/ui/lint/invalid_value.stderr
+++ b/tests/ui/lint/invalid_value.stderr
@@ -316,7 +316,7 @@ LL |         let _val: NonNull<i32> = mem::uninitialized();
    = note: `std::ptr::NonNull<i32>` must be non-null
    = note: raw pointers must be initialized
 
-error: the type `(NonZeroU32, i32)` does not permit zero-initialization
+error: the type `(NonZero<u32>, i32)` does not permit zero-initialization
   --> $DIR/invalid_value.rs:95:39
    |
 LL |         let _val: (NonZeroU32, i32) = mem::zeroed();
@@ -325,9 +325,9 @@ 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
+   = note: `std::num::NonZero<u32>` must be non-null
 
-error: the type `(NonZeroU32, i32)` does not permit being left uninitialized
+error: the type `(NonZero<u32>, i32)` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:96:39
    |
 LL |         let _val: (NonZeroU32, i32) = mem::uninitialized();
@@ -336,7 +336,7 @@ 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
+   = note: `std::num::NonZero<u32>` must be non-null
    = note: integers must be initialized
 
 error: the type `*const dyn Send` does not permit zero-initialization
@@ -417,7 +417,7 @@ LL |         let _val: OneFruitNonZero = mem::zeroed();
    |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: `OneFruitNonZero` must be non-null
-note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
   --> $DIR/invalid_value.rs:39:12
    |
 LL |     Banana(NonZeroU32),
@@ -433,7 +433,7 @@ LL |         let _val: OneFruitNonZero = mem::uninitialized();
    |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: `OneFruitNonZero` must be non-null
-note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
   --> $DIR/invalid_value.rs:39:12
    |
 LL |     Banana(NonZeroU32),
@@ -603,7 +603,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
+error: the type `NonZero<u32>` does not permit zero-initialization
   --> $DIR/invalid_value.rs:154:32
    |
 LL |         let _val: NonZeroU32 = mem::transmute(0);
@@ -612,7 +612,7 @@ LL |         let _val: NonZeroU32 = mem::transmute(0);
    |                                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
+   = note: `std::num::NonZero<u32>` must be non-null
 
 error: the type `NonNull<i32>` does not permit zero-initialization
   --> $DIR/invalid_value.rs:157:34
diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr
index 8554e261778..64beefbb757 100644
--- a/tests/ui/lint/lint-ctypes-enum.stderr
+++ b/tests/ui/lint/lint-ctypes-enum.stderr
@@ -61,7 +61,7 @@ LL |    fn nonzero_i128(x: Option<num::NonZeroI128>);
    |
    = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `Option<TransparentUnion<NonZeroU8>>`, which is not FFI-safe
+error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:86:28
    |
 LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
@@ -70,7 +70,7 @@ LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-error: `extern` block uses type `Option<Rust<NonZeroU8>>`, which is not FFI-safe
+error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:88:20
    |
 LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
@@ -79,7 +79,7 @@ LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-error: `extern` block uses type `Result<(), NonZeroI32>`, which is not FFI-safe
+error: `extern` block uses type `Result<(), NonZero<i32>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:89:20
    |
 LL |    fn no_result(x: Result<(), num::NonZeroI32>);
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs
index 192e6e0cc98..8cef833f48d 100644
--- a/tests/ui/macros/stringify.rs
+++ b/tests/ui/macros/stringify.rs
@@ -107,9 +107,9 @@ fn test_expr() {
     c1!(expr, [ true || false ], "true || false");
     c1!(expr, [ true || false && false ], "true || false && false");
     c1!(expr, [ a < 1 && 2 < b && c > 3 && 4 > d ], "a < 1 && 2 < b && c > 3 && 4 > d");
-    c2!(expr, [ a & b & !c ], "a & b & !c", "a & b &!c"); // FIXME
+    c1!(expr, [ a & b & !c ], "a & b & !c");
     c1!(expr, [ a + b * c - d + -1 * -2 - -3], "a + b * c - d + -1 * -2 - -3");
-    c2!(expr, [ x = !y ], "x = !y", "x =!y"); // FIXME
+    c1!(expr, [ x = !y ], "x = !y");
 
     // ExprKind::Unary
     c1!(expr, [ *expr ], "*expr");
@@ -141,15 +141,14 @@ fn test_expr() {
         "if let _ = (true && false) {}",
         "if let _ = true && false {}",
     );
-    c2!(expr,
+    c1!(expr,
         [ match () { _ if let _ = Struct {} => {} } ],
-        "match () { _ if let _ = Struct {} => {} }",
-        "match() { _ if let _ = Struct {} => {} }",
+        "match () { _ if let _ = Struct {} => {} }"
     );
 
     // ExprKind::If
     c1!(expr, [ if true {} ], "if true {}");
-    c2!(expr, [ if !true {} ], "if !true {}", "if!true {}"); // FIXME
+    c1!(expr, [ if !true {} ], "if !true {}");
     c1!(expr, [ if ::std::blah() { } else { } ], "if ::std::blah() {} else {}");
     c1!(expr, [ if let true = true {} else {} ], "if let true = true {} else {}");
     c1!(expr,
@@ -212,7 +211,7 @@ fn test_expr() {
     c2_match_arm!(
         [ { 1 } - 1 ],
         "match () { _ => ({ 1 }) - 1, }",
-        "match() { _ => { 1 } - 1 }",
+        "match () { _ => { 1 } - 1 }",
     );
 
     // ExprKind::Closure
@@ -655,11 +654,11 @@ fn test_stmt() {
     c2!(stmt, [ let _ ], "let _;", "let _");
     c2!(stmt, [ let x = true ], "let x = true;", "let x = true");
     c2!(stmt, [ let x: bool = true ], "let x: bool = true;", "let x: bool = true");
-    c2!(stmt, [ let (a, b) = (1, 2) ], "let (a, b) = (1, 2);", "let(a, b) = (1, 2)"); // FIXME
+    c2!(stmt, [ let (a, b) = (1, 2) ], "let (a, b) = (1, 2);", "let (a, b) = (1, 2)");
     c2!(stmt,
         [ let (a, b): (u32, u32) = (1, 2) ],
         "let (a, b): (u32, u32) = (1, 2);",
-        "let(a, b): (u32, u32) = (1, 2)" // FIXME
+        "let (a, b): (u32, u32) = (1, 2)"
     );
     macro_rules! c2_let_expr_minus_one {
         ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => {
@@ -776,8 +775,8 @@ fn test_ty() {
     c1!(ty, [ Ref<'a> ], "Ref<'a>");
     c1!(ty, [ PhantomData<T> ], "PhantomData<T>");
     c2!(ty, [ PhantomData::<T> ], "PhantomData<T>", "PhantomData::<T>");
-    c2!(ty, [ Fn() -> ! ], "Fn() -> !", "Fn() ->!");
-    c2!(ty, [ Fn(u8) -> ! ], "Fn(u8) -> !", "Fn(u8) ->!"); // FIXME
+    c1!(ty, [ Fn() -> ! ], "Fn() -> !");
+    c1!(ty, [ Fn(u8) -> ! ], "Fn(u8) -> !");
     c1!(ty, [ <Struct as Trait>::Type ], "<Struct as Trait>::Type");
 
     // TyKind::TraitObject
@@ -857,16 +856,16 @@ fn test_punct() {
     // Otherwise, any old proc macro that parses pretty-printed code might glue
     // together tokens that shouldn't be glued.
     p!([ = = < < <= <= == == != != >= >= > > ], "= = < < <= <= == == != != >= >= > >");
-    p!([ && && & & || || | | ! ! ], "&& && & & || || | |!!"); // FIXME
+    p!([ && && & & || || | | ! ! ], "&& && & & || || | | ! !");
     p!([ ~ ~ @ @ # # ], "~ ~ @ @ # #");
-    p!([ . . .. .. ... ... ..= ..=], ".... .. ... ... ..= ..="); // FIXME
-    p!([ , , ; ; : : :: :: ], ",, ; ; : : :: ::"); // FIXME
+    p!([ . . .. .. ... ... ..= ..=], ". . .. .. ... ... ..= ..=");
+    p!([ , , ; ; : : :: :: ], ", , ; ; : : :: ::");
     p!([ -> -> <- <- => =>], "-> -> <- <- => =>");
-    p!([ $ $ ? ? ' ' ], "$$? ? ' '"); // FIXME
+    p!([ $ $ ? ? ' ' ], "$ $ ? ? ' '");
     p!([ + + += += - - -= -= * * *= *= / / /= /= ], "+ + += += - - -= -= * * *= *= / / /= /=");
     p!([ % % %= %= ^ ^ ^= ^= << << <<= <<= >> >> >>= >>= ],
         "% % %= %= ^ ^ ^= ^= << << <<= <<= >> >> >>= >>=");
-    p!([ +! ?= |> >>@ --> <-- $$ =====> ], "+! ?= |> >>@ --> <-- $$=====>");
-    p!([ ,; ;, ** @@ $+$ >< <> ?? +== ], ",; ;, ** @@ $+$>< <> ?? +=="); // FIXME: `$ >` -> `$>`
+    p!([ +! ?= |> >>@ --> <-- $$ =====> ], "+! ?= |> >>@ --> <-- $$ =====>");
+    p!([ ,; ;, ** @@ $+$ >< <> ?? +== ], ",; ;, ** @@ $+$ >< <> ?? +==");
     p!([ :#!@|$=&*,+;*~? ], ":#!@|$=&*,+;*~?");
 }
diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr
index 81047c7a21a..69607600b55 100644
--- a/tests/ui/macros/trace_faulty_macros.stderr
+++ b/tests/ui/macros/trace_faulty_macros.stderr
@@ -111,7 +111,7 @@ LL |     test!(let x = 1+1);
    = note: expanding `test! { let x = 1+1 }`
    = note: to `test! ((x, 1 + 1))`
    = note: expanding `test! { (x, 1 + 1) }`
-   = note: to `let x = 1 + 1 ;`
+   = note: to `let x = 1 + 1;`
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr
index bd51378cf1a..f4310857454 100644
--- a/tests/ui/methods/method-call-err-msg.stderr
+++ b/tests/ui/methods/method-call-err-msg.stderr
@@ -49,10 +49,7 @@ error[E0599]: `Foo` is not an iterator
   --> $DIR/method-call-err-msg.rs:19:7
    |
 LL |   pub struct Foo;
-   |   --------------
-   |   |
-   |   method `take` not found for this struct
-   |   doesn't satisfy `Foo: Iterator`
+   |   -------------- method `take` not found for this struct because it doesn't satisfy `Foo: Iterator`
 ...
 LL | /     y.zero()
 LL | |      .take()
diff --git a/tests/ui/mismatched_types/E0631.stderr b/tests/ui/mismatched_types/E0631.stderr
index 9ba8f5035c5..dcd66c28e3c 100644
--- a/tests/ui/mismatched_types/E0631.stderr
+++ b/tests/ui/mismatched_types/E0631.stderr
@@ -2,8 +2,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:7:5
    |
 LL |     foo(|_: isize| {});
-   |     ^^^ ---------- found signature defined here
-   |     |
+   |     ^^^^----------^^^^
+   |     |   |
+   |     |   found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `fn(usize) -> _`
@@ -18,8 +19,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:8:5
    |
 LL |     bar(|_: isize| {});
-   |     ^^^ ---------- found signature defined here
-   |     |
+   |     ^^^^----------^^^^
+   |     |   |
+   |     |   found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `fn(usize) -> _`
diff --git a/tests/ui/mismatched_types/closure-arg-count.stderr b/tests/ui/mismatched_types/closure-arg-count.stderr
index 2ecab9f024a..0e2ca8feec5 100644
--- a/tests/ui/mismatched_types/closure-arg-count.stderr
+++ b/tests/ui/mismatched_types/closure-arg-count.stderr
@@ -49,8 +49,9 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
   --> $DIR/closure-arg-count.rs:13:5
    |
 LL |     f(|| panic!());
-   |     ^ -- takes 0 arguments
-   |     |
+   |     ^^--^^^^^^^^^^
+   |     | |
+   |     | takes 0 arguments
    |     expected closure that takes 1 argument
    |
 note: required by a bound in `f`
@@ -67,8 +68,9 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
   --> $DIR/closure-arg-count.rs:15:5
    |
 LL |     f(  move    || panic!());
-   |     ^   ---------- takes 0 arguments
-   |     |
+   |     ^^^^----------^^^^^^^^^^
+   |     |   |
+   |     |   takes 0 arguments
    |     expected closure that takes 1 argument
    |
 note: required by a bound in `f`
diff --git a/tests/ui/mismatched_types/issue-36053-2.stderr b/tests/ui/mismatched_types/issue-36053-2.stderr
index 292525daa3d..6d23319ca7e 100644
--- a/tests/ui/mismatched_types/issue-36053-2.stderr
+++ b/tests/ui/mismatched_types/issue-36053-2.stderr
@@ -21,11 +21,7 @@ error[E0599]: the method `count` exists for struct `Filter<Fuse<Once<&str>>, {cl
 LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
    |                                       ---------       ^^^^^ method cannot be called due to unsatisfied trait bounds
    |                                       |
-   |                                       doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
-   |                                       doesn't satisfy `_: FnMut<(&&str,)>`
-  --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL
-   |
-   = note: doesn't satisfy `_: Iterator`
+   |                                       doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool` or `_: FnMut<(&&str,)>`
    |
    = note: the following trait bounds were not satisfied:
            `<{closure@$DIR/issue-36053-2.rs:7:39: 7:48} as FnOnce<(&&str,)>>::Output = bool`
diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.stderr b/tests/ui/mismatched_types/non_zero_assigned_something.stderr
index 57db71f889c..f8e86905ab9 100644
--- a/tests/ui/mismatched_types/non_zero_assigned_something.stderr
+++ b/tests/ui/mismatched_types/non_zero_assigned_something.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/non_zero_assigned_something.rs:2:35
    |
 LL |     let _: std::num::NonZeroU64 = 1;
-   |            --------------------   ^ expected `NonZeroU64`, found integer
+   |            --------------------   ^ expected `NonZero<u64>`, found integer
    |            |
    |            expected due to this
    |
+   = note: expected struct `NonZero<u64>`
+                found type `{integer}`
 help: consider calling `NonZeroU64::new`
    |
 LL |     let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap();
@@ -15,11 +17,11 @@ error[E0308]: mismatched types
   --> $DIR/non_zero_assigned_something.rs:6:43
    |
 LL |     let _: Option<std::num::NonZeroU64> = 1;
-   |            ----------------------------   ^ expected `Option<NonZeroU64>`, found integer
+   |            ----------------------------   ^ expected `Option<NonZero<u64>>`, found integer
    |            |
    |            expected due to this
    |
-   = note: expected enum `Option<NonZeroU64>`
+   = note: expected enum `Option<NonZero<u64>>`
               found type `{integer}`
 help: consider calling `NonZeroU64::new`
    |
diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
index e1825eb5b54..be0fc0f98e2 100644
--- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
+++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
@@ -124,7 +124,7 @@ LL |     x / 100.0
    = help: the trait `Div<{float}>` is not implemented for `u8`
    = help: the following other types implement trait `Div<Rhs>`:
              <u8 as Div>
-             <u8 as Div<NonZeroU8>>
+             <u8 as Div<NonZero<u8>>>
              <u8 as Div<&u8>>
              <&'a u8 as Div<u8>>
              <&u8 as Div<&u8>>
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
new file mode 100644
index 00000000000..7aec3a73fe9
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr
@@ -0,0 +1,12 @@
+error[E0038]: the trait `Copy` cannot be made into an object
+  --> $DIR/avoid-ice-on-warning-2.rs:4:13
+   |
+LL | fn id<F>(f: Copy) -> usize {
+   |             ^^^^ `Copy` cannot be made into an object
+   |
+   = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = 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>
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
index 2755eee6f35..41c09b7df62 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-2.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
@@ -1,43 +1,33 @@
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-2.rs:1:13
+  --> $DIR/avoid-ice-on-warning-2.rs:4:13
    |
 LL | fn id<F>(f: Copy) -> usize {
    |             ^^^^
    |
    = 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: `Copy` it is not object safe, so it can't be `dyn`
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use a new generic type parameter, constrained by `Copy`
+help: use `dyn`
    |
-LL | fn id<F, T: Copy>(f: T) -> usize {
-   |        +++++++++     ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
-   |
-LL | fn id<F>(f: impl Copy) -> usize {
-   |             ++++
+LL | fn id<F>(f: dyn Copy) -> usize {
+   |             +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-2.rs:1:13
+  --> $DIR/avoid-ice-on-warning-2.rs:4:13
    |
 LL | fn id<F>(f: Copy) -> usize {
    |             ^^^^
    |
    = 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: `Copy` it is not object safe, so it can't be `dyn`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use a new generic type parameter, constrained by `Copy`
-   |
-LL | fn id<F, T: Copy>(f: T) -> usize {
-   |        +++++++++     ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+help: use `dyn`
    |
-LL | fn id<F>(f: impl Copy) -> usize {
-   |             ++++
+LL | fn id<F>(f: dyn Copy) -> usize {
+   |             +++
 
 error[E0038]: the trait `Copy` cannot be made into an object
-  --> $DIR/avoid-ice-on-warning-2.rs:1:13
+  --> $DIR/avoid-ice-on-warning-2.rs:4:13
    |
 LL | fn id<F>(f: Copy) -> usize {
    |             ^^^^ `Copy` cannot be made into an object
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.rs b/tests/ui/object-safety/avoid-ice-on-warning-2.rs
index cd34362d3dd..9a6a4378fa3 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-2.rs
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.rs
@@ -1,9 +1,12 @@
+// revisions: old new
+//[old] edition:2015
+//[new] edition:2021
 fn id<F>(f: Copy) -> usize {
-//~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-//~| ERROR the trait `Copy` cannot be made into an object
+//~^ ERROR the trait `Copy` cannot be made into an object
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     f()
 }
 fn main() {}
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr
new file mode 100644
index 00000000000..fd92d43ef9a
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.new.stderr
@@ -0,0 +1,47 @@
+error[E0038]: the trait `A` cannot be made into an object
+  --> $DIR/avoid-ice-on-warning-3.rs:4:19
+   |
+LL | trait B { fn f(a: A) -> A; }
+   |                   ^ `A` cannot be made into an object
+   |
+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>
+  --> $DIR/avoid-ice-on-warning-3.rs:12:14
+   |
+LL | trait A { fn g(b: B) -> B; }
+   |       -      ^ ...because associated function `g` has no `self` parameter
+   |       |
+   |       this trait cannot be made into an object...
+help: consider turning `g` into a method by giving it a `&self` argument
+   |
+LL | trait A { fn g(&self, b: B) -> B; }
+   |                ++++++
+help: alternatively, consider constraining `g` so it does not apply to trait objects
+   |
+LL | trait A { fn g(b: B) -> B where Self: Sized; }
+   |                           +++++++++++++++++
+
+error[E0038]: the trait `B` cannot be made into an object
+  --> $DIR/avoid-ice-on-warning-3.rs:12:19
+   |
+LL | trait A { fn g(b: B) -> B; }
+   |                   ^ `B` cannot be made into an object
+   |
+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>
+  --> $DIR/avoid-ice-on-warning-3.rs:4:14
+   |
+LL | trait B { fn f(a: A) -> A; }
+   |       -      ^ ...because associated function `f` has no `self` parameter
+   |       |
+   |       this trait cannot be made into an object...
+help: consider turning `f` into a method by giving it a `&self` argument
+   |
+LL | trait B { fn f(&self, a: A) -> A; }
+   |                ++++++
+help: alternatively, consider constraining `f` so it does not apply to trait objects
+   |
+LL | trait B { fn f(a: A) -> A where Self: Sized; }
+   |                           +++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
index 0fc67770b96..a36e2519c80 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-3.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
@@ -1,93 +1,78 @@
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:9:19
+  --> $DIR/avoid-ice-on-warning-3.rs:4:19
    |
-LL | trait A { fn g(b: B) -> B; }
+LL | trait B { fn f(a: A) -> A; }
    |                   ^
    |
    = 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: `B` it is not object safe, so it can't be `dyn`
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use a new generic type parameter, constrained by `B`
-   |
-LL | trait A { fn g<T: B>(b: T) -> B; }
-   |               ++++++    ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+help: use `dyn`
    |
-LL | trait A { fn g(b: impl B) -> B; }
-   |                   ++++
+LL | trait B { fn f(a: dyn A) -> A; }
+   |                   +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:9:25
+  --> $DIR/avoid-ice-on-warning-3.rs:4:25
    |
-LL | trait A { fn g(b: B) -> B; }
+LL | trait B { fn f(a: A) -> A; }
    |                         ^
    |
    = 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: `B` is not object safe, use `impl B` to return an opaque type, as long as you return a single underlying type
+help: use `dyn`
    |
-LL | trait A { fn g(b: B) -> impl B; }
-   |                         ++++
+LL | trait B { fn f(a: A) -> dyn A; }
+   |                         +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:1:19
+  --> $DIR/avoid-ice-on-warning-3.rs:12:19
    |
-LL | trait B { fn f(a: A) -> A; }
+LL | trait A { fn g(b: B) -> B; }
    |                   ^
    |
    = 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: `A` it is not object safe, so it can't be `dyn`
-help: use a new generic type parameter, constrained by `A`
-   |
-LL | trait B { fn f<T: A>(a: T) -> A; }
-   |               ++++++    ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+help: use `dyn`
    |
-LL | trait B { fn f(a: impl A) -> A; }
-   |                   ++++
+LL | trait A { fn g(b: dyn B) -> B; }
+   |                   +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:1:25
+  --> $DIR/avoid-ice-on-warning-3.rs:12:25
    |
-LL | trait B { fn f(a: A) -> A; }
+LL | trait A { fn g(b: B) -> B; }
    |                         ^
    |
    = 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: `A` is not object safe, use `impl A` to return an opaque type, as long as you return a single underlying type
+help: use `dyn`
    |
-LL | trait B { fn f(a: A) -> impl A; }
-   |                         ++++
+LL | trait A { fn g(b: B) -> dyn B; }
+   |                         +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:1:19
+  --> $DIR/avoid-ice-on-warning-3.rs:4:19
    |
 LL | trait B { fn f(a: A) -> A; }
    |                   ^
    |
    = 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: `A` it is not object safe, so it can't be `dyn`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use a new generic type parameter, constrained by `A`
-   |
-LL | trait B { fn f<T: A>(a: T) -> A; }
-   |               ++++++    ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+help: use `dyn`
    |
-LL | trait B { fn f(a: impl A) -> A; }
-   |                   ++++
+LL | trait B { fn f(a: dyn A) -> A; }
+   |                   +++
 
 error[E0038]: the trait `A` cannot be made into an object
-  --> $DIR/avoid-ice-on-warning-3.rs:1:19
+  --> $DIR/avoid-ice-on-warning-3.rs:4:19
    |
 LL | trait B { fn f(a: A) -> A; }
    |                   ^ `A` cannot be made into an object
    |
 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>
-  --> $DIR/avoid-ice-on-warning-3.rs:9:14
+  --> $DIR/avoid-ice-on-warning-3.rs:12:14
    |
 LL | trait A { fn g(b: B) -> B; }
    |       -      ^ ...because associated function `g` has no `self` parameter
@@ -103,32 +88,27 @@ LL | trait A { fn g(b: B) -> B where Self: Sized; }
    |                           +++++++++++++++++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning-3.rs:9:19
+  --> $DIR/avoid-ice-on-warning-3.rs:12:19
    |
 LL | trait A { fn g(b: B) -> B; }
    |                   ^
    |
    = 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: `B` it is not object safe, so it can't be `dyn`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use a new generic type parameter, constrained by `B`
-   |
-LL | trait A { fn g<T: B>(b: T) -> B; }
-   |               ++++++    ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
+help: use `dyn`
    |
-LL | trait A { fn g(b: impl B) -> B; }
-   |                   ++++
+LL | trait A { fn g(b: dyn B) -> B; }
+   |                   +++
 
 error[E0038]: the trait `B` cannot be made into an object
-  --> $DIR/avoid-ice-on-warning-3.rs:9:19
+  --> $DIR/avoid-ice-on-warning-3.rs:12:19
    |
 LL | trait A { fn g(b: B) -> B; }
    |                   ^ `B` cannot be made into an object
    |
 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>
-  --> $DIR/avoid-ice-on-warning-3.rs:1:14
+  --> $DIR/avoid-ice-on-warning-3.rs:4:14
    |
 LL | trait B { fn f(a: A) -> A; }
    |       -      ^ ...because associated function `f` has no `self` parameter
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.rs b/tests/ui/object-safety/avoid-ice-on-warning-3.rs
index caaf4d0fd99..40563e233de 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-3.rs
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.rs
@@ -1,17 +1,20 @@
+// revisions: old new
+//[old] edition:2015
+//[new] edition:2021
 trait B { fn f(a: A) -> A; }
-//~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN this is accepted in the current edition
-//~| WARN this is accepted in the current edition
-//~| ERROR the trait `A` cannot be made into an object
+//~^ ERROR the trait `A` cannot be made into an object
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN this is accepted in the current edition
+//[old]~| WARN this is accepted in the current edition
+//[old]~| WARN this is accepted in the current edition
 trait A { fn g(b: B) -> B; }
-//~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN this is accepted in the current edition
-//~| WARN this is accepted in the current edition
-//~| ERROR the trait `B` cannot be made into an object
+//~^ ERROR the trait `B` cannot be made into an object
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN this is accepted in the current edition
+//[old]~| WARN this is accepted in the current edition
+//[old]~| WARN this is accepted in the current edition
 fn main() {}
diff --git a/tests/ui/object-safety/avoid-ice-on-warning.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr
new file mode 100644
index 00000000000..517f910080d
--- /dev/null
+++ b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr
@@ -0,0 +1,15 @@
+error: return types are denoted using `->`
+  --> $DIR/avoid-ice-on-warning.rs:4:23
+   |
+LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
+   |                       ^ help: use `->` instead
+
+error[E0405]: cannot find trait `call_that` in this scope
+  --> $DIR/avoid-ice-on-warning.rs:4:36
+   |
+LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
+   |                                    ^^^^^^^^^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/object-safety/avoid-ice-on-warning.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
index 1046f177e82..7c7af968280 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
@@ -1,17 +1,17 @@
 error: return types are denoted using `->`
-  --> $DIR/avoid-ice-on-warning.rs:1:23
+  --> $DIR/avoid-ice-on-warning.rs:4:23
    |
 LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    |                       ^ help: use `->` instead
 
 error[E0405]: cannot find trait `call_that` in this scope
-  --> $DIR/avoid-ice-on-warning.rs:1:36
+  --> $DIR/avoid-ice-on-warning.rs:4:36
    |
 LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    |                                    ^^^^^^^^^ not found in this scope
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/avoid-ice-on-warning.rs:1:25
+  --> $DIR/avoid-ice-on-warning.rs:4:25
    |
 LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    |                         ^^^^^^^^^^^^^^^^^^^^
@@ -19,10 +19,10 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    = 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: `Fn(&str) + call_that` is not object safe, use `impl Fn(&str) + call_that` to return an opaque type, as long as you return a single underlying type
+help: use `dyn`
    |
-LL | fn call_this<F>(f: F) : impl Fn(&str) + call_that {}
-   |                         ++++
+LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
+   |                         +++
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/object-safety/avoid-ice-on-warning.rs b/tests/ui/object-safety/avoid-ice-on-warning.rs
index d2a1eeb5286..5192da94216 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning.rs
+++ b/tests/ui/object-safety/avoid-ice-on-warning.rs
@@ -1,6 +1,9 @@
+// revisions: old new
+//[old] edition:2015
+//[new] edition:2021
 fn call_this<F>(f: F) : Fn(&str) + call_that {}
 //~^ ERROR return types are denoted using `->`
 //~| ERROR cannot find trait `call_that` in this scope
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+//[old]~| WARN trait objects without an explicit `dyn` are deprecated
+//[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 fn main() {}
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed
deleted file mode 100644
index e95b982966d..00000000000
--- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.fixed
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-rustfix
-#![deny(bare_trait_objects)]
-fn ord_prefer_dot(s: String) -> impl Ord {
-    //~^ ERROR the trait `Ord` cannot be made into an object
-    (s.starts_with("."), s)
-}
-fn main() {
-    let _ = ord_prefer_dot(String::new());
-}
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed
new file mode 100644
index 00000000000..301c36c6191
--- /dev/null
+++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.fixed
@@ -0,0 +1,16 @@
+// revisions: old new
+//[old] edition:2015
+//[new] edition:2021
+//[new] run-rustfix
+// FIXME: the test suite tries to create a crate called `bare_trait_dont_suggest_dyn.new`
+#![crate_name="bare_trait_dont_suggest_dyn"]
+#![deny(bare_trait_objects)]
+fn ord_prefer_dot(s: String) -> impl Ord {
+    //~^ ERROR the trait `Ord` cannot be made into an object
+    //[old]~| ERROR trait objects without an explicit `dyn` are deprecated
+    //[old]~| WARNING this is accepted in the current edition (Rust 2015)
+    (s.starts_with("."), s)
+}
+fn main() {
+    let _ = ord_prefer_dot(String::new());
+}
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.stderr
index 2c499d240ab..52db31d620c 100644
--- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.stderr
+++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.new.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Ord` cannot be made into an object
-  --> $DIR/bare-trait-dont-suggest-dyn.rs:3:33
+  --> $DIR/bare-trait-dont-suggest-dyn.rs:8:33
    |
 LL | fn ord_prefer_dot(s: String) -> Ord {
    |                                 ^^^ `Ord` cannot be made into an object
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
new file mode 100644
index 00000000000..274d5a639a4
--- /dev/null
+++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
@@ -0,0 +1,39 @@
+error: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/bare-trait-dont-suggest-dyn.rs:8:33
+   |
+LL | fn ord_prefer_dot(s: String) -> Ord {
+   |                                 ^^^
+   |
+   = 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/bare-trait-dont-suggest-dyn.rs:7:9
+   |
+LL | #![deny(bare_trait_objects)]
+   |         ^^^^^^^^^^^^^^^^^^
+help: use `dyn`
+   |
+LL | fn ord_prefer_dot(s: String) -> dyn Ord {
+   |                                 +++
+
+error[E0038]: the trait `Ord` cannot be made into an object
+  --> $DIR/bare-trait-dont-suggest-dyn.rs:8:33
+   |
+LL | fn ord_prefer_dot(s: String) -> Ord {
+   |                                 ^^^ `Ord` cannot be made into an object
+   |
+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>
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+   = note: the trait cannot be made into an object because it uses `Self` as a type parameter
+  ::: $SRC_DIR/core/src/cmp.rs:LL:COL
+   |
+   = note: the trait cannot be made into an object because it uses `Self` as a type parameter
+help: consider using an opaque type instead
+   |
+LL | fn ord_prefer_dot(s: String) -> impl Ord {
+   |                                 ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs
index fdf7e0a77aa..64586b77b8c 100644
--- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs
+++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.rs
@@ -1,7 +1,14 @@
-// run-rustfix
+// revisions: old new
+//[old] edition:2015
+//[new] edition:2021
+//[new] run-rustfix
+// FIXME: the test suite tries to create a crate called `bare_trait_dont_suggest_dyn.new`
+#![crate_name="bare_trait_dont_suggest_dyn"]
 #![deny(bare_trait_objects)]
 fn ord_prefer_dot(s: String) -> Ord {
     //~^ ERROR the trait `Ord` cannot be made into an object
+    //[old]~| ERROR trait objects without an explicit `dyn` are deprecated
+    //[old]~| WARNING this is accepted in the current edition (Rust 2015)
     (s.starts_with("."), s)
 }
 fn main() {
diff --git a/tests/ui/on-unimplemented/multiple-impls.rs b/tests/ui/on-unimplemented/multiple-impls.rs
index a32fd456623..b74957ebcd4 100644
--- a/tests/ui/on-unimplemented/multiple-impls.rs
+++ b/tests/ui/on-unimplemented/multiple-impls.rs
@@ -33,13 +33,10 @@ fn main() {
     Index::index(&[] as &[i32], 2u32);
     //~^ ERROR E0277
     //~| ERROR E0277
-    //~| ERROR E0277
     Index::index(&[] as &[i32], Foo(2u32));
     //~^ ERROR E0277
     //~| ERROR E0277
-    //~| ERROR E0277
     Index::index(&[] as &[i32], Bar(2u32));
     //~^ ERROR E0277
     //~| ERROR E0277
-    //~| ERROR E0277
 }
diff --git a/tests/ui/on-unimplemented/multiple-impls.stderr b/tests/ui/on-unimplemented/multiple-impls.stderr
index 3d0e36db752..f59c93a7c37 100644
--- a/tests/ui/on-unimplemented/multiple-impls.stderr
+++ b/tests/ui/on-unimplemented/multiple-impls.stderr
@@ -11,19 +11,8 @@ LL |     Index::index(&[] as &[i32], 2u32);
              <[i32] as Index<Foo<usize>>>
              <[i32] as Index<Bar<usize>>>
 
-error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/multiple-impls.rs:33:5
-   |
-LL |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message
-   |
-   = help: the trait `Index<u32>` is not implemented for `[i32]`
-   = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Foo<usize>>>
-             <[i32] as Index<Bar<usize>>>
-
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:37:33
+  --> $DIR/multiple-impls.rs:36:33
    |
 LL |     Index::index(&[] as &[i32], Foo(2u32));
    |     ------------                ^^^^^^^^^ on impl for Foo
@@ -35,19 +24,8 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
              <[i32] as Index<Foo<usize>>>
              <[i32] as Index<Bar<usize>>>
 
-error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:37:5
-   |
-LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
-   |
-   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
-   = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Foo<usize>>>
-             <[i32] as Index<Bar<usize>>>
-
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:41:33
+  --> $DIR/multiple-impls.rs:39:33
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
    |     ------------                ^^^^^^^^^ on impl for Bar
@@ -59,22 +37,11 @@ LL |     Index::index(&[] as &[i32], Bar(2u32));
              <[i32] as Index<Foo<usize>>>
              <[i32] as Index<Bar<usize>>>
 
-error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:41:5
-   |
-LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
-   |
-   = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
-   = help: the following other types implement trait `Index<Idx>`:
-             <[i32] as Index<Foo<usize>>>
-             <[i32] as Index<Bar<usize>>>
-
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:5
    |
 LL |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^ trait message
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
@@ -82,10 +49,10 @@ LL |     Index::index(&[] as &[i32], 2u32);
              <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:37:5
+  --> $DIR/multiple-impls.rs:36:5
    |
 LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ^^^^^^^^^^^^ on impl for Foo
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
@@ -93,16 +60,16 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
              <[i32] as Index<Bar<usize>>>
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:41:5
+  --> $DIR/multiple-impls.rs:39:5
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ^^^^^^^^^^^^ on impl for Bar
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
    = help: the following other types implement trait `Index<Idx>`:
              <[i32] as Index<Foo<usize>>>
              <[i32] as Index<Bar<usize>>>
 
-error: aborting due to 9 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/on-unimplemented/on-impl.rs b/tests/ui/on-unimplemented/on-impl.rs
index d0537810ce1..ab3e67d01fe 100644
--- a/tests/ui/on-unimplemented/on-impl.rs
+++ b/tests/ui/on-unimplemented/on-impl.rs
@@ -22,5 +22,4 @@ fn main() {
     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
     //~^ ERROR E0277
     //~| ERROR E0277
-    //~| ERROR E0277
 }
diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr
index 3a0b8353fa5..c7d2a78af6c 100644
--- a/tests/ui/on-unimplemented/on-impl.stderr
+++ b/tests/ui/on-unimplemented/on-impl.stderr
@@ -20,16 +20,6 @@ LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    = help: the trait `Index<usize>` is implemented for `[i32]`
    = help: for that trait implementation, expected `usize`, found `u32`
 
-error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/on-impl.rs:22:5
-   |
-LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
-   |
-   = help: the trait `Index<u32>` is not implemented for `[i32]`
-   = help: the trait `Index<usize>` is implemented for `[i32]`
-   = help: for that trait implementation, expected `usize`, found `u32`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/on-unimplemented/on-trait.stderr b/tests/ui/on-unimplemented/on-trait.stderr
index 4847a1a5a61..4097ee1350d 100644
--- a/tests/ui/on-unimplemented/on-trait.stderr
+++ b/tests/ui/on-unimplemented/on-trait.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `Option<Vec<u8>>: MyFromIterator<&u8>` is not sati
   --> $DIR/on-trait.rs:28:30
    |
 LL |     let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect()
-   |                              ^^^^^^^ a collection of type `Option<Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
+   |                              ^^^^^^^^^^^^^^^^^ a collection of type `Option<Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
    |
    = help: the trait `MyFromIterator<&u8>` is not implemented for `Option<Vec<u8>>`
 help: this trait has no implementations, consider adding one
@@ -20,7 +20,7 @@ error[E0277]: the trait bound `String: Foo<u8, _, u32>` is not satisfied
   --> $DIR/on-trait.rs:31:21
    |
 LL |     let x: String = foobar();
-   |                     ^^^^^^ test error `String` with `u8` `_` `u32` in `Foo`
+   |                     ^^^^^^^^ test error `String` with `u8` `_` `u32` in `Foo`
    |
    = help: the trait `Foo<u8, _, u32>` is not implemented for `String`
 help: this trait has no implementations, consider adding one
diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs
index f13c12fc52e..b59023b50e1 100644
--- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs
+++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs
@@ -1,5 +1,4 @@
 // compile-flags:-C panic=abort
-// error-pattern: language item required, but not found: `panic_info`
 
 #![feature(lang_items)]
 #![feature(no_core)]
@@ -8,6 +7,7 @@
 
 #[panic_handler]
 fn panic() -> ! {
+    //~^ ERROR requires `panic_info` lang_item
     loop {}
 }
 
diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr b/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr
index 06ff8e3098a..873f61a5163 100644
--- a/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr
+++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr
@@ -1,4 +1,8 @@
-error: language item required, but not found: `panic_info`
+error: requires `panic_info` lang_item
+  --> $DIR/panic-handler-requires-panic-info.rs:9:1
+   |
+LL | fn panic() -> ! {
+   | ^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs
new file mode 100644
index 00000000000..a7412f51782
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs
@@ -0,0 +1,9 @@
+// Issue #118164: recovery path leaving unemitted error behind
+fn bar() -> String {
+    #[cfg(feature = )]
+    [1, 2, 3].iter().map().collect::<String>() //~ ERROR expected `;`, found `#`
+    #[attr] //~ ERROR expected statement after outer attribute
+}
+fn main() {
+    let _ = bar();
+}
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
new file mode 100644
index 00000000000..dd0081cc2df
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
@@ -0,0 +1,27 @@
+error: expected `;`, found `#`
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:4:47
+   |
+LL |     #[cfg(feature = )]
+   |     ------------------ only `;` terminated statements or tail expressions are allowed after this attribute
+LL |     [1, 2, 3].iter().map().collect::<String>()
+   |                                               ^ expected `;` here
+LL |     #[attr]
+   |     - unexpected token
+   |
+help: add `;` here
+   |
+LL |     [1, 2, 3].iter().map().collect::<String>();
+   |                                               +
+help: alternatively, consider surrounding the expression with a block
+   |
+LL |     { [1, 2, 3].iter().map().collect::<String>() }
+   |     +                                            +
+
+error: expected statement after outer attribute
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
+   |
+LL |     #[attr]
+   |     ^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/parser/issues/issue-24197.rs b/tests/ui/parser/issues/issue-24197.rs
index aaf5137461f..9bba16e5596 100644
--- a/tests/ui/parser/issues/issue-24197.rs
+++ b/tests/ui/parser/issues/issue-24197.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let buf[0] = 0; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    let buf[0] = 0; //~ error: expected a pattern, found an expression
 }
diff --git a/tests/ui/parser/issues/issue-24197.stderr b/tests/ui/parser/issues/issue-24197.stderr
index 3ef707f3953..7ebbf4ac370 100644
--- a/tests/ui/parser/issues/issue-24197.stderr
+++ b/tests/ui/parser/issues/issue-24197.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
-  --> $DIR/issue-24197.rs:2:12
+error: expected a pattern, found an expression
+  --> $DIR/issue-24197.rs:2:9
    |
 LL |     let buf[0] = 0;
-   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-24375.rs b/tests/ui/parser/issues/issue-24375.rs
index 1d128d33e4f..a5e256b7f15 100644
--- a/tests/ui/parser/issues/issue-24375.rs
+++ b/tests/ui/parser/issues/issue-24375.rs
@@ -3,7 +3,7 @@ static tmp : [&'static str; 2]  = ["hello", "he"];
 fn main() {
     let z = "hello";
     match z {
-        tmp[0] => {} //~ ERROR expected one of `=>`, `@`, `if`, or `|`, found `[`
+        tmp[0] => {} //~ error: expected a pattern, found an expression
         _ => {}
     }
 }
diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr
index bb1e19e9e6d..e6ef07d13fd 100644
--- a/tests/ui/parser/issues/issue-24375.stderr
+++ b/tests/ui/parser/issues/issue-24375.stderr
@@ -1,8 +1,8 @@
-error: expected one of `=>`, `@`, `if`, or `|`, found `[`
-  --> $DIR/issue-24375.rs:6:12
+error: expected a pattern, found an expression
+  --> $DIR/issue-24375.rs:6:9
    |
 LL |         tmp[0] => {}
-   |            ^ expected one of `=>`, `@`, `if`, or `|`
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/label-is-actually-char.rs b/tests/ui/parser/label-is-actually-char.rs
index 183da603da4..74df898d191 100644
--- a/tests/ui/parser/label-is-actually-char.rs
+++ b/tests/ui/parser/label-is-actually-char.rs
@@ -1,16 +1,43 @@
+// Note: it's ok to interpret 'a as 'a', but but not ok to interpret 'abc as
+// 'abc' because 'abc' is not a valid char literal.
+
 fn main() {
     let c = 'a;
     //~^ ERROR expected `while`, `for`, `loop` or `{` after a label
     //~| HELP add `'` to close the char literal
-    match c {
+
+    let c = 'abc;
+    //~^ ERROR expected `while`, `for`, `loop` or `{` after a label
+    //~| ERROR expected expression, found `;`
+}
+
+fn f() {
+    match 'a' {
         'a'..='b => {}
         //~^ ERROR unexpected token: `'b`
         //~| HELP add `'` to close the char literal
-        _ => {}
+        'c'..='def => {}
+        //~^ ERROR unexpected token: `'def`
     }
-    let x = ['a, 'b];
-    //~^ ERROR expected `while`, `for`, `loop` or `{` after a label
-    //~| ERROR expected `while`, `for`, `loop` or `{` after a label
-    //~| HELP add `'` to close the char literal
-    //~| HELP add `'` to close the char literal
+}
+
+fn g() {
+   match 'g' {
+       'g => {}
+       //~^ ERROR expected pattern, found `=>`
+       //~| HELP add `'` to close the char literal
+       'hij => {}
+       //~^ ERROR expected pattern, found `'hij`
+       _ => {}
+   }
+}
+
+fn h() {
+   let x = ['a, 'b, 'cde];
+   //~^ ERROR expected `while`, `for`, `loop` or `{` after a label
+   //~| HELP add `'` to close the char literal
+   //~| ERROR expected `while`, `for`, `loop` or `{` after a label
+   //~| HELP add `'` to close the char literal
+   //~| ERROR expected `while`, `for`, `loop` or `{` after a label
+   //~| ERROR expected expression, found `]`
 }
diff --git a/tests/ui/parser/label-is-actually-char.stderr b/tests/ui/parser/label-is-actually-char.stderr
index 28c8d2ada3a..10a7e1803b5 100644
--- a/tests/ui/parser/label-is-actually-char.stderr
+++ b/tests/ui/parser/label-is-actually-char.stderr
@@ -1,5 +1,5 @@
 error: expected `while`, `for`, `loop` or `{` after a label
-  --> $DIR/label-is-actually-char.rs:2:15
+  --> $DIR/label-is-actually-char.rs:5:15
    |
 LL |     let c = 'a;
    |               ^ expected `while`, `for`, `loop` or `{` after a label
@@ -9,8 +9,20 @@ help: add `'` to close the char literal
 LL |     let c = 'a';
    |               +
 
+error: expected `while`, `for`, `loop` or `{` after a label
+  --> $DIR/label-is-actually-char.rs:9:17
+   |
+LL |     let c = 'abc;
+   |                 ^ expected `while`, `for`, `loop` or `{` after a label
+
+error: expected expression, found `;`
+  --> $DIR/label-is-actually-char.rs:9:17
+   |
+LL |     let c = 'abc;
+   |                 ^ expected expression
+
 error: unexpected token: `'b`
-  --> $DIR/label-is-actually-char.rs:6:15
+  --> $DIR/label-is-actually-char.rs:16:15
    |
 LL |         'a'..='b => {}
    |               ^^
@@ -20,27 +32,62 @@ help: add `'` to close the char literal
 LL |         'a'..='b' => {}
    |                 +
 
+error: unexpected token: `'def`
+  --> $DIR/label-is-actually-char.rs:19:15
+   |
+LL |         'c'..='def => {}
+   |               ^^^^
+
+error: expected pattern, found `=>`
+  --> $DIR/label-is-actually-char.rs:26:11
+   |
+LL |        'g => {}
+   |           ^^ expected pattern
+   |
+help: add `'` to close the char literal
+   |
+LL |        'g' => {}
+   |          +
+
+error: expected pattern, found `'hij`
+  --> $DIR/label-is-actually-char.rs:29:8
+   |
+LL |        'hij => {}
+   |        ^^^^ expected pattern
+
 error: expected `while`, `for`, `loop` or `{` after a label
-  --> $DIR/label-is-actually-char.rs:11:16
+  --> $DIR/label-is-actually-char.rs:36:15
    |
-LL |     let x = ['a, 'b];
-   |                ^ expected `while`, `for`, `loop` or `{` after a label
+LL |    let x = ['a, 'b, 'cde];
+   |               ^ expected `while`, `for`, `loop` or `{` after a label
    |
 help: add `'` to close the char literal
    |
-LL |     let x = ['a', 'b];
-   |                +
+LL |    let x = ['a', 'b, 'cde];
+   |               +
 
 error: expected `while`, `for`, `loop` or `{` after a label
-  --> $DIR/label-is-actually-char.rs:11:20
+  --> $DIR/label-is-actually-char.rs:36:19
    |
-LL |     let x = ['a, 'b];
-   |                    ^ expected `while`, `for`, `loop` or `{` after a label
+LL |    let x = ['a, 'b, 'cde];
+   |                   ^ expected `while`, `for`, `loop` or `{` after a label
    |
 help: add `'` to close the char literal
    |
-LL |     let x = ['a, 'b'];
-   |                    +
+LL |    let x = ['a, 'b', 'cde];
+   |                   +
+
+error: expected `while`, `for`, `loop` or `{` after a label
+  --> $DIR/label-is-actually-char.rs:36:25
+   |
+LL |    let x = ['a, 'b, 'cde];
+   |                         ^ expected `while`, `for`, `loop` or `{` after a label
+
+error: expected expression, found `]`
+  --> $DIR/label-is-actually-char.rs:36:25
+   |
+LL |    let x = ['a, 'b, 'cde];
+   |                         ^ expected expression
 
-error: aborting due to 4 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/tests/ui/parser/pat-lt-bracket-5.rs b/tests/ui/parser/pat-lt-bracket-5.rs
index aaece1f6bd9..6d784494d56 100644
--- a/tests/ui/parser/pat-lt-bracket-5.rs
+++ b/tests/ui/parser/pat-lt-bracket-5.rs
@@ -1,3 +1,5 @@
 fn main() {
-    let v[0] = v[1]; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    let v[0] = v[1];
+    //~^ error: expected a pattern, found an expression
+    //~| error: cannot find value `v` in this scope
 }
diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr
index e556e6c0206..18cf2df0282 100644
--- a/tests/ui/parser/pat-lt-bracket-5.stderr
+++ b/tests/ui/parser/pat-lt-bracket-5.stderr
@@ -1,8 +1,15 @@
-error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
-  --> $DIR/pat-lt-bracket-5.rs:2:10
+error: expected a pattern, found an expression
+  --> $DIR/pat-lt-bracket-5.rs:2:9
    |
 LL |     let v[0] = v[1];
-   |          ^ expected one of `:`, `;`, `=`, `@`, or `|`
+   |         ^^^^ arbitrary expressions are not allowed in patterns
 
-error: aborting due to 1 previous error
+error[E0425]: cannot find value `v` in this scope
+  --> $DIR/pat-lt-bracket-5.rs:2:16
+   |
+LL |     let v[0] = v[1];
+   |                ^ not found in this scope
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/parser/pat-lt-bracket-6.rs b/tests/ui/parser/pat-lt-bracket-6.rs
index 7becffa9fe2..496525ed537 100644
--- a/tests/ui/parser/pat-lt-bracket-6.rs
+++ b/tests/ui/parser/pat-lt-bracket-6.rs
@@ -3,7 +3,8 @@ fn main() {
     let x = Test(&0, []);
 
     let Test(&desc[..]) = x;
-    //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
+    //~^ error: expected a pattern, found an expression
+    //~| error: this pattern has 1 field, but the corresponding tuple struct has 2 fields
 }
 
 const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/tests/ui/parser/pat-lt-bracket-6.stderr b/tests/ui/parser/pat-lt-bracket-6.stderr
index 035d0dbfe06..10c638a63e4 100644
--- a/tests/ui/parser/pat-lt-bracket-6.stderr
+++ b/tests/ui/parser/pat-lt-bracket-6.stderr
@@ -1,18 +1,30 @@
-error: expected one of `)`, `,`, `@`, or `|`, found `[`
-  --> $DIR/pat-lt-bracket-6.rs:5:19
+error: expected a pattern, found an expression
+  --> $DIR/pat-lt-bracket-6.rs:5:15
    |
 LL |     let Test(&desc[..]) = x;
-   |                   ^
-   |                   |
-   |                   expected one of `)`, `,`, `@`, or `|`
-   |                   help: missing `,`
+   |               ^^^^^^^^ arbitrary expressions are not allowed in patterns
 
 error[E0308]: mismatched types
-  --> $DIR/pat-lt-bracket-6.rs:9:30
+  --> $DIR/pat-lt-bracket-6.rs:10:30
    |
 LL | const RECOVERY_WITNESS: () = 0;
    |                              ^ expected `()`, found integer
 
-error: aborting due to 2 previous errors
+error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
+  --> $DIR/pat-lt-bracket-6.rs:5:14
+   |
+LL |     struct Test(&'static u8, [u8; 0]);
+   |                 -----------  ------- tuple struct has 2 fields
+...
+LL |     let Test(&desc[..]) = x;
+   |              ^^^^^^^^^ expected 2 fields, found 1
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |     let Test(&desc[..], _) = x;
+   |                       +++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0023, E0308.
+For more information about an error, try `rustc --explain E0023`.
diff --git a/tests/ui/parser/pat-ranges-3.rs b/tests/ui/parser/pat-ranges-3.rs
index 8976dcf0d90..419768a2a20 100644
--- a/tests/ui/parser/pat-ranges-3.rs
+++ b/tests/ui/parser/pat-ranges-3.rs
@@ -1,5 +1,9 @@
 // Parsing of range patterns
 
 fn main() {
-    let 10 ..= 10 + 3 = 12; //~ expected one of `:`, `;`, `=`, or `|`, found `+`
+    let 10 ..= 10 + 3 = 12;
+    //~^ error: expected a pattern range bound, found an expression
+
+    let 10 - 3 ..= 10 = 8;
+    //~^ error: expected a pattern range bound, found an expression
 }
diff --git a/tests/ui/parser/pat-ranges-3.stderr b/tests/ui/parser/pat-ranges-3.stderr
index 611b35a6502..5e1f35d1b6f 100644
--- a/tests/ui/parser/pat-ranges-3.stderr
+++ b/tests/ui/parser/pat-ranges-3.stderr
@@ -1,8 +1,14 @@
-error: expected one of `:`, `;`, `=`, or `|`, found `+`
-  --> $DIR/pat-ranges-3.rs:4:19
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-ranges-3.rs:4:16
    |
 LL |     let 10 ..= 10 + 3 = 12;
-   |                   ^ expected one of `:`, `;`, `=`, or `|`
+   |                ^^^^^^ arbitrary expressions are not allowed in patterns
 
-error: aborting due to 1 previous error
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-ranges-3.rs:7:9
+   |
+LL |     let 10 - 3 ..= 10 = 8;
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/pat-ranges-4.rs b/tests/ui/parser/pat-ranges-4.rs
deleted file mode 100644
index 61188976b02..00000000000
--- a/tests/ui/parser/pat-ranges-4.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// Parsing of range patterns
-
-fn main() {
-    let 10 - 3 ..= 10 = 8;
-    //~^ error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
-}
diff --git a/tests/ui/parser/pat-ranges-4.stderr b/tests/ui/parser/pat-ranges-4.stderr
deleted file mode 100644
index c30160291d6..00000000000
--- a/tests/ui/parser/pat-ranges-4.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
-  --> $DIR/pat-ranges-4.rs:4:12
-   |
-LL |     let 10 - 3 ..= 10 = 8;
-   |            ^ expected one of 7 possible tokens
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/parser/pat-recover-exprs.rs b/tests/ui/parser/pat-recover-exprs.rs
new file mode 100644
index 00000000000..ecd471467e3
--- /dev/null
+++ b/tests/ui/parser/pat-recover-exprs.rs
@@ -0,0 +1,28 @@
+fn main() {
+    match u8::MAX {
+        u8::MAX.abs() => (),
+        //~^ error: expected a pattern, found a method call
+        x.sqrt() @ .. => (),
+        //~^ error: expected a pattern, found a method call
+        //~| error: left-hand side of `@` must be a binding
+        z @ w @ v.u() => (),
+        //~^ error: expected a pattern, found a method call
+        y.ilog(3) => (),
+        //~^ error: expected a pattern, found a method call
+        n + 1 => (),
+        //~^ error: expected a pattern, found an expression
+        ("".f() + 14 * 8) => (),
+        //~^ error: expected a pattern, found an expression
+        0 | ((1) | 2) | 3 => (),
+        f?() => (),
+        //~^ error: expected a pattern, found an expression
+        (_ + 1) => (),
+        //~^ error: expected one of `)`, `,`, or `|`, found `+`
+    }
+
+    let 1 + 1 = 2;
+    //~^ error: expected a pattern, found an expression
+
+    let b = matches!(x, (x * x | x.f()) | x[0]);
+    //~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
+}
diff --git a/tests/ui/parser/pat-recover-exprs.stderr b/tests/ui/parser/pat-recover-exprs.stderr
new file mode 100644
index 00000000000..787fd03b0c3
--- /dev/null
+++ b/tests/ui/parser/pat-recover-exprs.stderr
@@ -0,0 +1,76 @@
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:3:9
+   |
+LL |         u8::MAX.abs() => (),
+   |         ^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:5:9
+   |
+LL |         x.sqrt() @ .. => (),
+   |         ^^^^^^^^ method calls are not allowed in patterns
+
+error: left-hand side of `@` must be a binding
+  --> $DIR/pat-recover-exprs.rs:5:9
+   |
+LL |         x.sqrt() @ .. => (),
+   |         --------^^^--
+   |         |          |
+   |         |          also a pattern
+   |         interpreted as a pattern, not a binding
+   |
+   = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:8:17
+   |
+LL |         z @ w @ v.u() => (),
+   |                 ^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:10:9
+   |
+LL |         y.ilog(3) => (),
+   |         ^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:12:9
+   |
+LL |         n + 1 => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:14:10
+   |
+LL |         ("".f() + 14 * 8) => (),
+   |          ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:17:9
+   |
+LL |         f?() => (),
+   |         ^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected one of `)`, `,`, or `|`, found `+`
+  --> $DIR/pat-recover-exprs.rs:19:12
+   |
+LL |         (_ + 1) => (),
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:23:9
+   |
+LL |     let 1 + 1 = 2;
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected one of `)`, `,`, `@`, or `|`, found `*`
+  --> $DIR/pat-recover-exprs.rs:26:28
+   |
+LL |     let b = matches!(x, (x * x | x.f()) | x[0]);
+   |                            ^ expected one of `)`, `,`, `@`, or `|`
+  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
+   |
+   = note: while parsing argument for this `pat` macro fragment
+
+error: aborting due to 11 previous errors
+
diff --git a/tests/ui/parser/pat-recover-methodcalls.rs b/tests/ui/parser/pat-recover-methodcalls.rs
new file mode 100644
index 00000000000..54104e9a535
--- /dev/null
+++ b/tests/ui/parser/pat-recover-methodcalls.rs
@@ -0,0 +1,37 @@
+struct Foo(String);
+struct Bar { baz: String }
+
+fn foo(foo: Foo) -> bool {
+    match foo {
+        Foo("hi".to_owned()) => true,
+        //~^ error: expected a pattern, found a method call
+        _ => false
+    }
+}
+
+fn bar(bar: Bar) -> bool {
+    match bar {
+        Bar { baz: "hi".to_owned() } => true,
+        //~^ error: expected a pattern, found a method call
+        _ => false
+    }
+}
+
+fn baz() { // issue #90121
+    let foo = vec!["foo".to_string()];
+
+    match foo.as_slice() {
+        &["foo".to_string()] => {}
+        //~^ error: expected a pattern, found a method call
+        _ => {}
+    };
+}
+
+fn main() {
+    if let (-1.some(4)) = (0, Some(4)) {}
+    //~^ error: expected a pattern, found a method call
+
+    if let (-1.Some(4)) = (0, Some(4)) {}
+    //~^ error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
+    //~| help: missing `,`
+}
diff --git a/tests/ui/parser/pat-recover-methodcalls.stderr b/tests/ui/parser/pat-recover-methodcalls.stderr
new file mode 100644
index 00000000000..1f9ae81dc0c
--- /dev/null
+++ b/tests/ui/parser/pat-recover-methodcalls.stderr
@@ -0,0 +1,35 @@
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:6:13
+   |
+LL |         Foo("hi".to_owned()) => true,
+   |             ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:14:20
+   |
+LL |         Bar { baz: "hi".to_owned() } => true,
+   |                    ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:24:11
+   |
+LL |         &["foo".to_string()] => {}
+   |           ^^^^^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:31:13
+   |
+LL |     if let (-1.some(4)) = (0, Some(4)) {}
+   |             ^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
+  --> $DIR/pat-recover-methodcalls.rs:34:15
+   |
+LL |     if let (-1.Some(4)) = (0, Some(4)) {}
+   |               ^
+   |               |
+   |               expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
+   |               help: missing `,`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/parser/pat-recover-ranges.rs b/tests/ui/parser/pat-recover-ranges.rs
index 65a6fc6fe21..7d77e950d90 100644
--- a/tests/ui/parser/pat-recover-ranges.rs
+++ b/tests/ui/parser/pat-recover-ranges.rs
@@ -8,6 +8,22 @@ fn main() {
         (0)..=(-4) => (),
         //~^ error: range pattern bounds cannot have parentheses
         //~| error: range pattern bounds cannot have parentheses
+        ..=1 + 2 => (),
+        //~^ error: expected a pattern range bound, found an expression
+        (4).. => (),
+        //~^ error: range pattern bounds cannot have parentheses
+        (-4 + 0).. => (),
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: range pattern bounds cannot have parentheses
+        (1 + 4)...1 * 2 => (),
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: expected a pattern range bound, found an expression
+        //~| error: range pattern bounds cannot have parentheses
+        //~| warning: `...` range patterns are deprecated
+        //~| warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+        0.x()..="y".z() => (),
+        //~^ error: expected a pattern range bound, found a method call
+        //~| error: expected a pattern range bound, found a method call
     };
 }
 
diff --git a/tests/ui/parser/pat-recover-ranges.stderr b/tests/ui/parser/pat-recover-ranges.stderr
index 0d722b5aa95..a7d62bd7f8a 100644
--- a/tests/ui/parser/pat-recover-ranges.stderr
+++ b/tests/ui/parser/pat-recover-ranges.stderr
@@ -46,5 +46,87 @@ LL -         (0)..=(-4) => (),
 LL +         (0)..=-4 => (),
    |
 
-error: aborting due to 4 previous errors
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:11:12
+   |
+LL |         ..=1 + 2 => (),
+   |            ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-ranges.rs:13:9
+   |
+LL |         (4).. => (),
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (4).. => (),
+LL +         4.. => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:15:10
+   |
+LL |         (-4 + 0).. => (),
+   |          ^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-ranges.rs:15:9
+   |
+LL |         (-4 + 0).. => (),
+   |         ^      ^
+   |
+help: remove these parentheses
+   |
+LL -         (-4 + 0).. => (),
+LL +         -4 + 0.. => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:18:10
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |          ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-ranges.rs:18:9
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |         ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         (1 + 4)...1 * 2 => (),
+LL +         1 + 4...1 * 2 => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:18:19
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |                   ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern range bound, found a method call
+  --> $DIR/pat-recover-ranges.rs:24:9
+   |
+LL |         0.x()..="y".z() => (),
+   |         ^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern range bound, found a method call
+  --> $DIR/pat-recover-ranges.rs:24:17
+   |
+LL |         0.x()..="y".z() => (),
+   |                 ^^^^^^^ method calls are not allowed in patterns
+
+warning: `...` range patterns are deprecated
+  --> $DIR/pat-recover-ranges.rs:18:16
+   |
+LL |         (1 + 4)...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: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
+
+error: aborting due to 13 previous errors; 1 warning emitted
 
diff --git a/tests/ui/parser/pat-recover-wildcards.rs b/tests/ui/parser/pat-recover-wildcards.rs
new file mode 100644
index 00000000000..f506e2223d6
--- /dev/null
+++ b/tests/ui/parser/pat-recover-wildcards.rs
@@ -0,0 +1,61 @@
+// check that we can't do funny things with wildcards.
+
+fn a() {
+    match 1 {
+        _ + 1 => () //~ error: expected one of `=>`, `if`, or `|`, found `+`
+    }
+}
+
+fn b() {
+    match 2 {
+        (_ % 4) => () //~ error: expected one of `)`, `,`, or `|`, found `%`
+    }
+}
+
+fn c() {
+    match 3 {
+        _.x() => () //~ error: expected one of `=>`, `if`, or `|`, found `.`
+    }
+}
+
+fn d() {
+    match 4 {
+        _..=4 => () //~ error: expected one of `=>`, `if`, or `|`, found `..=`
+    }
+}
+
+fn e() {
+    match 5 {
+        .._ => () //~ error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+    }
+}
+
+fn f() {
+    match 6 {
+        0..._ => ()
+        //~^ error: inclusive range with no end
+        //~| error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+    }
+}
+
+fn g() {
+    match 7 {
+        (_ * 0)..5 => () //~ error: expected one of `)`, `,`, or `|`, found `*`
+    }
+}
+
+fn h() {
+    match 8 {
+        ..(_) => () //~ error: expected one of `=>`, `if`, or `|`, found `(`
+    }
+}
+
+fn i() {
+    match 9 {
+        4..=(2 + _) => ()
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: range pattern bounds cannot have parentheses
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/parser/pat-recover-wildcards.stderr b/tests/ui/parser/pat-recover-wildcards.stderr
new file mode 100644
index 00000000000..2b0c9bbc5be
--- /dev/null
+++ b/tests/ui/parser/pat-recover-wildcards.stderr
@@ -0,0 +1,77 @@
+error: expected one of `=>`, `if`, or `|`, found `+`
+  --> $DIR/pat-recover-wildcards.rs:5:11
+   |
+LL |         _ + 1 => ()
+   |           ^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `)`, `,`, or `|`, found `%`
+  --> $DIR/pat-recover-wildcards.rs:11:12
+   |
+LL |         (_ % 4) => ()
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found `.`
+  --> $DIR/pat-recover-wildcards.rs:17:10
+   |
+LL |         _.x() => ()
+   |          ^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found `..=`
+  --> $DIR/pat-recover-wildcards.rs:23:10
+   |
+LL |         _..=4 => ()
+   |          ^^^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+  --> $DIR/pat-recover-wildcards.rs:29:11
+   |
+LL |         .._ => ()
+   |           ^ expected one of `=>`, `if`, or `|`
+
+error[E0586]: inclusive range with no end
+  --> $DIR/pat-recover-wildcards.rs:35:10
+   |
+LL |         0..._ => ()
+   |          ^^^ help: use `..` instead
+   |
+   = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+  --> $DIR/pat-recover-wildcards.rs:35:13
+   |
+LL |         0..._ => ()
+   |             ^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `)`, `,`, or `|`, found `*`
+  --> $DIR/pat-recover-wildcards.rs:43:12
+   |
+LL |         (_ * 0)..5 => ()
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found `(`
+  --> $DIR/pat-recover-wildcards.rs:49:11
+   |
+LL |         ..(_) => ()
+   |           ^ expected one of `=>`, `if`, or `|`
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-wildcards.rs:55:14
+   |
+LL |         4..=(2 + _) => ()
+   |              ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-wildcards.rs:55:13
+   |
+LL |         4..=(2 + _) => ()
+   |             ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         4..=(2 + _) => ()
+LL +         4..=2 + _ => ()
+   |
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/tests/ui/parser/range-exclusive-dotdotlt.rs b/tests/ui/parser/range-exclusive-dotdotlt.rs
new file mode 100644
index 00000000000..5752566026f
--- /dev/null
+++ b/tests/ui/parser/range-exclusive-dotdotlt.rs
@@ -0,0 +1,43 @@
+fn foo() {
+    let _ = 0..<10;
+    //~^ ERROR: expected type, found `10`
+    //~| HELP: remove the `<` to write an exclusive range
+}
+
+fn bar() {
+    let _ = 0..<foo;
+    //~^ ERROR: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `;`
+    //~| HELP: remove the `<` to write an exclusive range
+}
+
+fn baz() {
+    let _ = <foo>;
+    //~^ ERROR: expected `::`, found `;`
+}
+
+fn qux() {
+    let _ = [1, 2, 3][..<1];
+    //~^ ERROR: expected type, found `1`
+    //~| HELP: remove the `<` to write an exclusive range
+}
+
+fn quux() {
+    let _ = [1, 2, 3][..<foo];
+    //~^ ERROR: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `]`
+    //~| HELP: remove the `<` to write an exclusive range
+}
+
+fn foobar() {
+    let _ = [1, 2, 3][..<foo>];
+    //~^ ERROR: expected `::`, found `]`
+}
+
+fn ok1() {
+    let _ = [1, 2, 3][..<usize>::default()];
+}
+
+fn ok2() {
+    let _ = 0..<i32>::default();
+}
+
+fn main() {}
diff --git a/tests/ui/parser/range-exclusive-dotdotlt.stderr b/tests/ui/parser/range-exclusive-dotdotlt.stderr
new file mode 100644
index 00000000000..af25e1df343
--- /dev/null
+++ b/tests/ui/parser/range-exclusive-dotdotlt.stderr
@@ -0,0 +1,46 @@
+error: expected type, found `10`
+  --> $DIR/range-exclusive-dotdotlt.rs:2:17
+   |
+LL |     let _ = 0..<10;
+   |                -^^ expected type
+   |                |
+   |                help: remove the `<` to write an exclusive range
+
+error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `;`
+  --> $DIR/range-exclusive-dotdotlt.rs:8:20
+   |
+LL |     let _ = 0..<foo;
+   |                -   ^ expected one of 7 possible tokens
+   |                |
+   |                help: remove the `<` to write an exclusive range
+
+error: expected `::`, found `;`
+  --> $DIR/range-exclusive-dotdotlt.rs:14:18
+   |
+LL |     let _ = <foo>;
+   |                  ^ expected `::`
+
+error: expected type, found `1`
+  --> $DIR/range-exclusive-dotdotlt.rs:19:26
+   |
+LL |     let _ = [1, 2, 3][..<1];
+   |                         -^ expected type
+   |                         |
+   |                         help: remove the `<` to write an exclusive range
+
+error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `]`
+  --> $DIR/range-exclusive-dotdotlt.rs:25:29
+   |
+LL |     let _ = [1, 2, 3][..<foo];
+   |                         -   ^ expected one of 7 possible tokens
+   |                         |
+   |                         help: remove the `<` to write an exclusive range
+
+error: expected `::`, found `]`
+  --> $DIR/range-exclusive-dotdotlt.rs:31:30
+   |
+LL |     let _ = [1, 2, 3][..<foo>];
+   |                              ^ expected `::`
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
index 3681a796c53..17138a6f079 100644
--- a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
+++ b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
@@ -30,8 +30,9 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/recover-fn-trait-from-fn-kw.rs:10:5
    |
 LL |     foo2(|_: ()| {});
-   |     ^^^^ ------- found signature defined here
-   |     |
+   |     ^^^^^-------^^^^
+   |     |    |
+   |     |    found signature defined here
    |     expected due to this
    |
    = note: expected closure signature `fn(i32) -> _`
diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
index 367aba3bdd6..0c55164a780 100644
--- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
@@ -1,23 +1,23 @@
 error: unreachable pattern
-  --> $DIR/empty-types.rs:47:9
+  --> $DIR/empty-types.rs:50:9
    |
 LL |         _ => {}
    |         ^
    |
 note: the lint level is defined here
-  --> $DIR/empty-types.rs:13:9
+  --> $DIR/empty-types.rs:16:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:50:9
+  --> $DIR/empty-types.rs:53:9
    |
 LL |         _x => {}
    |         ^^
 
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
-  --> $DIR/empty-types.rs:54:11
+  --> $DIR/empty-types.rs:57:11
    |
 LL |     match ref_never {}
    |           ^^^^^^^^^
@@ -32,31 +32,31 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:69:9
+  --> $DIR/empty-types.rs:72:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:76:9
+  --> $DIR/empty-types.rs:79:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:79:9
+  --> $DIR/empty-types.rs:82:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:83:9
+  --> $DIR/empty-types.rs:86:9
    |
 LL |         _ => {}
    |         ^
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
-  --> $DIR/empty-types.rs:87:11
+  --> $DIR/empty-types.rs:90:11
    |
 LL |     match res_u32_never {}
    |           ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@@ -75,19 +75,19 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:95:9
+  --> $DIR/empty-types.rs:98:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:100:9
+  --> $DIR/empty-types.rs:103:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
 
 error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
-  --> $DIR/empty-types.rs:97:11
+  --> $DIR/empty-types.rs:100:11
    |
 LL |     match res_u32_never {
    |           ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
@@ -105,7 +105,7 @@ LL ~         Ok(1_u32..=u32::MAX) => todo!()
    |
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/empty-types.rs:104:9
+  --> $DIR/empty-types.rs:107:9
    |
 LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
@@ -119,121 +119,121 @@ LL |     let Ok(_x) = res_u32_never.as_ref() else { todo!() };
    |                                         ++++++++++++++++
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:115:9
+  --> $DIR/empty-types.rs:118:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:119:9
+  --> $DIR/empty-types.rs:122:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:122:9
+  --> $DIR/empty-types.rs:125:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:123:9
+  --> $DIR/empty-types.rs:126:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:126:9
+  --> $DIR/empty-types.rs:129:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:127:9
+  --> $DIR/empty-types.rs:130:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:136:13
+  --> $DIR/empty-types.rs:139:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:139:13
+  --> $DIR/empty-types.rs:142:13
    |
 LL |             _ if false => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:148:13
+  --> $DIR/empty-types.rs:151:13
    |
 LL |             Some(_) => {}
    |             ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:152:13
+  --> $DIR/empty-types.rs:155:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:204:13
+  --> $DIR/empty-types.rs:207:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:209:13
+  --> $DIR/empty-types.rs:212:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:214:13
+  --> $DIR/empty-types.rs:217:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:219:13
+  --> $DIR/empty-types.rs:222:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:225:13
+  --> $DIR/empty-types.rs:228:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:284:9
+  --> $DIR/empty-types.rs:287:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:287:9
+  --> $DIR/empty-types.rs:290:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:290:9
+  --> $DIR/empty-types.rs:293:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:291:9
+  --> $DIR/empty-types.rs:294:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
 
 error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
-  --> $DIR/empty-types.rs:323:11
+  --> $DIR/empty-types.rs:326:11
    |
 LL |     match slice_never {}
    |           ^^^^^^^^^^^
@@ -247,7 +247,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` not covered
-  --> $DIR/empty-types.rs:334:11
+  --> $DIR/empty-types.rs:337:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[]` not covered
@@ -260,7 +260,7 @@ LL +         &[] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` not covered
-  --> $DIR/empty-types.rs:347:11
+  --> $DIR/empty-types.rs:350:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[]` not covered
@@ -274,7 +274,7 @@ LL +         &[] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
-  --> $DIR/empty-types.rs:353:11
+  --> $DIR/empty-types.rs:356:11
    |
 LL |     match *slice_never {}
    |           ^^^^^^^^^^^^
@@ -288,25 +288,25 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:363:9
+  --> $DIR/empty-types.rs:366:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:366:9
+  --> $DIR/empty-types.rs:369:9
    |
 LL |         [_, _, _] => {}
    |         ^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:369:9
+  --> $DIR/empty-types.rs:372:9
    |
 LL |         [_, ..] => {}
    |         ^^^^^^^
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
-  --> $DIR/empty-types.rs:383:11
+  --> $DIR/empty-types.rs:386:11
    |
 LL |     match array_0_never {}
    |           ^^^^^^^^^^^^^
@@ -320,13 +320,13 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:390:9
+  --> $DIR/empty-types.rs:393:9
    |
 LL |         _ => {}
    |         ^
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/empty-types.rs:392:11
+  --> $DIR/empty-types.rs:395:11
    |
 LL |     match array_0_never {
    |           ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -340,49 +340,49 @@ LL +         [] => todo!()
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:411:9
+  --> $DIR/empty-types.rs:414:9
    |
 LL |         Some(_) => {}
    |         ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:416:9
+  --> $DIR/empty-types.rs:419:9
    |
 LL |         Some(_a) => {}
    |         ^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:421:9
+  --> $DIR/empty-types.rs:424:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:426:9
+  --> $DIR/empty-types.rs:429:9
    |
 LL |         _a => {}
    |         ^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:598:9
+  --> $DIR/empty-types.rs:601:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:601:9
+  --> $DIR/empty-types.rs:604:9
    |
 LL |         _x => {}
    |         ^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:604:9
+  --> $DIR/empty-types.rs:607:9
    |
 LL |         _ if false => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:607:9
+  --> $DIR/empty-types.rs:610:9
    |
 LL |         _x if false => {}
    |         ^^
diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
new file mode 100644
index 00000000000..ed5d125e684
--- /dev/null
+++ b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
@@ -0,0 +1,630 @@
+warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/empty-types.rs:13:35
+   |
+LL | #![cfg_attr(min_exh_pats, feature(min_exhaustive_patterns))]
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #119612 <https://github.com/rust-lang/rust/issues/119612> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:50:9
+   |
+LL |         _ => {}
+   |         ^
+   |
+note: the lint level is defined here
+  --> $DIR/empty-types.rs:16:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:53:9
+   |
+LL |         _x => {}
+   |         ^^
+
+error[E0004]: non-exhaustive patterns: type `&!` is non-empty
+  --> $DIR/empty-types.rs:57:11
+   |
+LL |     match ref_never {}
+   |           ^^^^^^^^^
+   |
+   = note: the matched value is of type `&!`
+   = note: references are always considered inhabited
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match ref_never {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:72:9
+   |
+LL |         (_, _) => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:79:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:82:9
+   |
+LL |         (_, _) => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:86:9
+   |
+LL |         _ => {}
+   |         ^
+
+error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
+  --> $DIR/empty-types.rs:90:11
+   |
+LL |     match res_u32_never {}
+   |           ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
+   |
+note: `Result<u32, !>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+  ::: $SRC_DIR/core/src/result.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Result<u32, !>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~     match res_u32_never {
+LL +         Ok(_) => todo!(),
+LL +     }
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:98:9
+   |
+LL |         Err(_) => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:103:9
+   |
+LL |         Err(_) => {}
+   |         ^^^^^^
+
+error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
+  --> $DIR/empty-types.rs:100:11
+   |
+LL |     match res_u32_never {
+   |           ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
+   |
+note: `Result<u32, !>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+  ::: $SRC_DIR/core/src/result.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Result<u32, !>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Err(_) => {},
+LL ~         Ok(1_u32..=u32::MAX) => todo!()
+   |
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/empty-types.rs:107:9
+   |
+LL |     let Ok(_x) = res_u32_never.as_ref();
+   |         ^^^^^^ pattern `Err(_)` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `Result<&u32, &!>`
+help: you might want to use `let else` to handle the variant that isn't matched
+   |
+LL |     let Ok(_x) = res_u32_never.as_ref() else { todo!() };
+   |                                         ++++++++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/empty-types.rs:111:9
+   |
+LL |     let Ok(_x) = &res_u32_never;
+   |         ^^^^^^ pattern `&Err(_)` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `&Result<u32, !>`
+help: you might want to use `let else` to handle the variant that isn't matched
+   |
+LL |     let Ok(_x) = &res_u32_never else { todo!() };
+   |                                 ++++++++++++++++
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:118:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:122:9
+   |
+LL |         Ok(_) => {}
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:125:9
+   |
+LL |         Ok(_) => {}
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:126:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:129:9
+   |
+LL |         Ok(_) => {}
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:130:9
+   |
+LL |         Err(_) => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:139:13
+   |
+LL |             _ => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:142:13
+   |
+LL |             _ if false => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:151:13
+   |
+LL |             Some(_) => {}
+   |             ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:155:13
+   |
+LL |             _ => {}
+   |             ^
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/empty-types.rs:164:15
+   |
+LL |         match *ref_opt_void {
+   |               ^^^^^^^^^^^^^ pattern `Some(_)` not covered
+   |
+note: `Option<Void>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<Void>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~             None => {},
+LL +             Some(_) => todo!()
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:207:13
+   |
+LL |             _ => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:212:13
+   |
+LL |             _ => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:217:13
+   |
+LL |             _ => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:222:13
+   |
+LL |             _ => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:228:13
+   |
+LL |             _ => {}
+   |             ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:287:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:290:9
+   |
+LL |         (_, _) => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:293:9
+   |
+LL |         Ok(_) => {}
+   |         ^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:294:9
+   |
+LL |         Err(_) => {}
+   |         ^^^^^^
+
+error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
+  --> $DIR/empty-types.rs:315:11
+   |
+LL |     match *x {}
+   |           ^^
+   |
+   = note: the matched value is of type `(u32, !)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match *x {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
+  --> $DIR/empty-types.rs:317:11
+   |
+LL |     match *x {}
+   |           ^^
+   |
+   = note: the matched value is of type `(!, !)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match *x {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
+  --> $DIR/empty-types.rs:319:11
+   |
+LL |     match *x {}
+   |           ^^ patterns `Ok(_)` and `Err(_)` not covered
+   |
+note: `Result<!, !>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+  ::: $SRC_DIR/core/src/result.rs:LL:COL
+   |
+   = note: not covered
+  ::: $SRC_DIR/core/src/result.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Result<!, !>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~     match *x {
+LL +         Ok(_) | Err(_) => todo!(),
+LL ~     }
+   |
+
+error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
+  --> $DIR/empty-types.rs:321:11
+   |
+LL |     match *x {}
+   |           ^^
+   |
+   = note: the matched value is of type `[!; 3]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match *x {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
+  --> $DIR/empty-types.rs:326:11
+   |
+LL |     match slice_never {}
+   |           ^^^^^^^^^^^
+   |
+   = note: the matched value is of type `&[!]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match slice_never {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
+  --> $DIR/empty-types.rs:328:11
+   |
+LL |     match slice_never {
+   |           ^^^^^^^^^^^ pattern `&[_, ..]` not covered
+   |
+   = note: the matched value is of type `&[!]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [] => {},
+LL +         &[_, ..] => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
+  --> $DIR/empty-types.rs:337:11
+   |
+LL |     match slice_never {
+   |           ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
+   |
+   = note: the matched value is of type `&[!]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         [_, _, _, ..] => {},
+LL +         &[] | &[_] | &[_, _] => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
+  --> $DIR/empty-types.rs:350:11
+   |
+LL |     match slice_never {
+   |           ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
+   |
+   = note: the matched value is of type `&[!]`
+   = note: match arms with guards don't count towards exhaustivity
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~         &[..] if false => {},
+LL +         &[] | &[_, ..] => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
+  --> $DIR/empty-types.rs:356:11
+   |
+LL |     match *slice_never {}
+   |           ^^^^^^^^^^^^
+   |
+   = note: the matched value is of type `[!]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match *slice_never {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:366:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:369:9
+   |
+LL |         [_, _, _] => {}
+   |         ^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:372:9
+   |
+LL |         [_, ..] => {}
+   |         ^^^^^^^
+
+error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
+  --> $DIR/empty-types.rs:386:11
+   |
+LL |     match array_0_never {}
+   |           ^^^^^^^^^^^^^
+   |
+   = note: the matched value is of type `[!; 0]`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match array_0_never {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:393:9
+   |
+LL |         _ => {}
+   |         ^
+
+error[E0004]: non-exhaustive patterns: `[]` not covered
+  --> $DIR/empty-types.rs:395:11
+   |
+LL |     match array_0_never {
+   |           ^^^^^^^^^^^^^ pattern `[]` not covered
+   |
+   = note: the matched value is of type `[!; 0]`
+   = note: match arms with guards don't count towards exhaustivity
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         [..] if false => {},
+LL +         [] => todo!()
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:414:9
+   |
+LL |         Some(_) => {}
+   |         ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:419:9
+   |
+LL |         Some(_a) => {}
+   |         ^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:424:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:429:9
+   |
+LL |         _a => {}
+   |         ^^
+
+error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
+  --> $DIR/empty-types.rs:449:11
+   |
+LL |     match ref_opt_never {
+   |           ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
+   |
+note: `Option<!>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `&Option<!>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         &None => {},
+LL +         &Some(_) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/empty-types.rs:490:11
+   |
+LL |     match *ref_opt_never {
+   |           ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
+   |
+note: `Option<!>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<!>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None => {},
+LL +         Some(_) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `Err(_)` not covered
+  --> $DIR/empty-types.rs:538:11
+   |
+LL |     match *ref_res_never {
+   |           ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
+   |
+note: `Result<!, !>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+  ::: $SRC_DIR/core/src/result.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Result<!, !>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Ok(_) => {},
+LL +         Err(_) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `Err(_)` not covered
+  --> $DIR/empty-types.rs:549:11
+   |
+LL |     match *ref_res_never {
+   |           ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
+   |
+note: `Result<!, !>` defined here
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+  ::: $SRC_DIR/core/src/result.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Result<!, !>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         Ok(_a) => {},
+LL +         Err(_) => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
+  --> $DIR/empty-types.rs:568:11
+   |
+LL |     match *ref_tuple_half_never {}
+   |           ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the matched value is of type `(u32, !)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match *ref_tuple_half_never {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:601:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:604:9
+   |
+LL |         _x => {}
+   |         ^^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:607:9
+   |
+LL |         _ if false => {}
+   |         ^
+
+error: unreachable pattern
+  --> $DIR/empty-types.rs:610:9
+   |
+LL |         _x if false => {}
+   |         ^^
+
+error[E0004]: non-exhaustive patterns: `&_` not covered
+  --> $DIR/empty-types.rs:635:11
+   |
+LL |     match ref_never {
+   |           ^^^^^^^^^ pattern `&_` not covered
+   |
+   = note: the matched value is of type `&!`
+   = note: references are always considered inhabited
+   = note: match arms with guards don't count towards exhaustivity
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         &_a if false => {},
+LL +         &_ => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/empty-types.rs:663:11
+   |
+LL |     match *x {
+   |           ^^ pattern `Some(_)` not covered
+   |
+note: `Option<Result<!, !>>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<Result<!, !>>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None => {},
+LL +         Some(_) => todo!()
+   |
+
+error: aborting due to 63 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0004, E0005.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr
index 133a95a821b..2fdb51677da 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -1,23 +1,23 @@
 error: unreachable pattern
-  --> $DIR/empty-types.rs:47:9
+  --> $DIR/empty-types.rs:50:9
    |
 LL |         _ => {}
    |         ^
    |
 note: the lint level is defined here
-  --> $DIR/empty-types.rs:13:9
+  --> $DIR/empty-types.rs:16:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:50:9
+  --> $DIR/empty-types.rs:53:9
    |
 LL |         _x => {}
    |         ^^
 
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
-  --> $DIR/empty-types.rs:54:11
+  --> $DIR/empty-types.rs:57:11
    |
 LL |     match ref_never {}
    |           ^^^^^^^^^
@@ -32,7 +32,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:66:11
+  --> $DIR/empty-types.rs:69:11
    |
 LL |     match tuple_half_never {}
    |           ^^^^^^^^^^^^^^^^
@@ -46,7 +46,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
-  --> $DIR/empty-types.rs:73:11
+  --> $DIR/empty-types.rs:76:11
    |
 LL |     match tuple_never {}
    |           ^^^^^^^^^^^
@@ -60,13 +60,13 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:83:9
+  --> $DIR/empty-types.rs:86:9
    |
 LL |         _ => {}
    |         ^
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
-  --> $DIR/empty-types.rs:87:11
+  --> $DIR/empty-types.rs:90:11
    |
 LL |     match res_u32_never {}
    |           ^^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
@@ -88,7 +88,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/empty-types.rs:89:11
+  --> $DIR/empty-types.rs:92:11
    |
 LL |     match res_u32_never {
    |           ^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -106,7 +106,7 @@ LL +         Err(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
-  --> $DIR/empty-types.rs:97:11
+  --> $DIR/empty-types.rs:100:11
    |
 LL |     match res_u32_never {
    |           ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
@@ -124,7 +124,7 @@ LL ~         Ok(1_u32..=u32::MAX) => todo!()
    |
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/empty-types.rs:102:9
+  --> $DIR/empty-types.rs:105:9
    |
 LL |     let Ok(_x) = res_u32_never;
    |         ^^^^^^ pattern `Err(_)` not covered
@@ -138,7 +138,7 @@ LL |     let Ok(_x) = res_u32_never else { todo!() };
    |                                ++++++++++++++++
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/empty-types.rs:104:9
+  --> $DIR/empty-types.rs:107:9
    |
 LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
@@ -152,7 +152,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref() else { todo!() };
    |                                         ++++++++++++++++
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/empty-types.rs:108:9
+  --> $DIR/empty-types.rs:111:9
    |
 LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(_)` not covered
@@ -166,7 +166,7 @@ LL |     let Ok(_x) = &res_u32_never else { todo!() };
    |                                 ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
-  --> $DIR/empty-types.rs:112:11
+  --> $DIR/empty-types.rs:115:11
    |
 LL |     match result_never {}
    |           ^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
@@ -188,7 +188,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/empty-types.rs:117:11
+  --> $DIR/empty-types.rs:120:11
    |
 LL |     match result_never {
    |           ^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -205,19 +205,19 @@ LL |         Ok(_) => {}, Err(_) => todo!()
    |                    +++++++++++++++++++
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:136:13
+  --> $DIR/empty-types.rs:139:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:139:13
+  --> $DIR/empty-types.rs:142:13
    |
 LL |             _ if false => {}
    |             ^
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/empty-types.rs:142:15
+  --> $DIR/empty-types.rs:145:15
    |
 LL |         match opt_void {
    |               ^^^^^^^^ pattern `Some(_)` not covered
@@ -235,7 +235,7 @@ LL +             Some(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/empty-types.rs:161:15
+  --> $DIR/empty-types.rs:164:15
    |
 LL |         match *ref_opt_void {
    |               ^^^^^^^^^^^^^ pattern `Some(_)` not covered
@@ -253,43 +253,43 @@ LL +             Some(_) => todo!()
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:204:13
+  --> $DIR/empty-types.rs:207:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:209:13
+  --> $DIR/empty-types.rs:212:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:214:13
+  --> $DIR/empty-types.rs:217:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:219:13
+  --> $DIR/empty-types.rs:222:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:225:13
+  --> $DIR/empty-types.rs:228:13
    |
 LL |             _ => {}
    |             ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:284:9
+  --> $DIR/empty-types.rs:287:9
    |
 LL |         _ => {}
    |         ^
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:312:11
+  --> $DIR/empty-types.rs:315:11
    |
 LL |     match *x {}
    |           ^^
@@ -303,7 +303,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
-  --> $DIR/empty-types.rs:314:11
+  --> $DIR/empty-types.rs:317:11
    |
 LL |     match *x {}
    |           ^^
@@ -317,7 +317,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
-  --> $DIR/empty-types.rs:316:11
+  --> $DIR/empty-types.rs:319:11
    |
 LL |     match *x {}
    |           ^^ patterns `Ok(_)` and `Err(_)` not covered
@@ -339,7 +339,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
-  --> $DIR/empty-types.rs:318:11
+  --> $DIR/empty-types.rs:321:11
    |
 LL |     match *x {}
    |           ^^
@@ -353,7 +353,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
-  --> $DIR/empty-types.rs:323:11
+  --> $DIR/empty-types.rs:326:11
    |
 LL |     match slice_never {}
    |           ^^^^^^^^^^^
@@ -367,7 +367,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
-  --> $DIR/empty-types.rs:325:11
+  --> $DIR/empty-types.rs:328:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[_, ..]` not covered
@@ -380,7 +380,7 @@ LL +         &[_, ..] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
-  --> $DIR/empty-types.rs:334:11
+  --> $DIR/empty-types.rs:337:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
@@ -393,7 +393,7 @@ LL +         &[] | &[_] | &[_, _] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
-  --> $DIR/empty-types.rs:347:11
+  --> $DIR/empty-types.rs:350:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
@@ -407,7 +407,7 @@ LL +         &[] | &[_, ..] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
-  --> $DIR/empty-types.rs:353:11
+  --> $DIR/empty-types.rs:356:11
    |
 LL |     match *slice_never {}
    |           ^^^^^^^^^^^^
@@ -421,7 +421,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
-  --> $DIR/empty-types.rs:360:11
+  --> $DIR/empty-types.rs:363:11
    |
 LL |     match array_3_never {}
    |           ^^^^^^^^^^^^^
@@ -435,7 +435,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
-  --> $DIR/empty-types.rs:383:11
+  --> $DIR/empty-types.rs:386:11
    |
 LL |     match array_0_never {}
    |           ^^^^^^^^^^^^^
@@ -449,13 +449,13 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:390:9
+  --> $DIR/empty-types.rs:393:9
    |
 LL |         _ => {}
    |         ^
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/empty-types.rs:392:11
+  --> $DIR/empty-types.rs:395:11
    |
 LL |     match array_0_never {
    |           ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -469,7 +469,7 @@ LL +         [] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
-  --> $DIR/empty-types.rs:446:11
+  --> $DIR/empty-types.rs:449:11
    |
 LL |     match ref_opt_never {
    |           ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
@@ -487,7 +487,7 @@ LL +         &Some(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/empty-types.rs:487:11
+  --> $DIR/empty-types.rs:490:11
    |
 LL |     match *ref_opt_never {
    |           ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
@@ -505,7 +505,7 @@ LL +         Some(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/empty-types.rs:535:11
+  --> $DIR/empty-types.rs:538:11
    |
 LL |     match *ref_res_never {
    |           ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -523,7 +523,7 @@ LL +         Err(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/empty-types.rs:546:11
+  --> $DIR/empty-types.rs:549:11
    |
 LL |     match *ref_res_never {
    |           ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -541,7 +541,7 @@ LL +         Err(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:565:11
+  --> $DIR/empty-types.rs:568:11
    |
 LL |     match *ref_tuple_half_never {}
    |           ^^^^^^^^^^^^^^^^^^^^^
@@ -555,31 +555,31 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:598:9
+  --> $DIR/empty-types.rs:601:9
    |
 LL |         _ => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:601:9
+  --> $DIR/empty-types.rs:604:9
    |
 LL |         _x => {}
    |         ^^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:604:9
+  --> $DIR/empty-types.rs:607:9
    |
 LL |         _ if false => {}
    |         ^
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:607:9
+  --> $DIR/empty-types.rs:610:9
    |
 LL |         _x if false => {}
    |         ^^
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
-  --> $DIR/empty-types.rs:631:11
+  --> $DIR/empty-types.rs:635:11
    |
 LL |     match ref_never {
    |           ^^^^^^^^^ pattern `&_` not covered
@@ -594,7 +594,7 @@ LL +         &_ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/empty-types.rs:659:11
+  --> $DIR/empty-types.rs:663:11
    |
 LL |     match *x {
    |           ^^ pattern `Some(_)` not covered
diff --git a/tests/ui/pattern/usefulness/empty-types.rs b/tests/ui/pattern/usefulness/empty-types.rs
index 1e1d23e446d..c66fd1edc19 100644
--- a/tests/ui/pattern/usefulness/empty-types.rs
+++ b/tests/ui/pattern/usefulness/empty-types.rs
@@ -1,4 +1,5 @@
-// revisions: normal exhaustive_patterns
+// revisions: normal min_exh_pats exhaustive_patterns
+// gate-test-min_exhaustive_patterns
 //
 // This tests correct handling of empty types in exhaustiveness checking.
 //
@@ -9,6 +10,8 @@
 // This feature is useful to avoid `!` falling back to `()` all the time.
 #![feature(never_type_fallback)]
 #![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
+#![cfg_attr(min_exh_pats, feature(min_exhaustive_patterns))]
+//[min_exh_pats]~^ WARN the feature `min_exhaustive_patterns` is incomplete
 #![allow(dead_code, unreachable_code)]
 #![deny(unreachable_patterns)]
 
@@ -66,17 +69,17 @@ fn basic(x: NeverBundle) {
     match tuple_half_never {}
     //[normal]~^ ERROR non-empty
     match tuple_half_never {
-        (_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        (_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
 
     let tuple_never: (!, !) = x.tuple_never;
     match tuple_never {}
     //[normal]~^ ERROR non-empty
     match tuple_never {
-        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match tuple_never {
-        (_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        (_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match tuple_never.0 {}
     match tuple_never.0 {
@@ -92,12 +95,12 @@ fn basic(x: NeverBundle) {
     }
     match res_u32_never {
         Ok(_) => {}
-        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match res_u32_never {
         //~^ ERROR non-exhaustive
         Ok(0) => {}
-        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     let Ok(_x) = res_u32_never;
     //[normal]~^ ERROR refutable
@@ -106,25 +109,25 @@ fn basic(x: NeverBundle) {
     // Non-obvious difference: here there's an implicit dereference in the patterns, which makes the
     // inner place !known_valid. `exhaustive_patterns` ignores this.
     let Ok(_x) = &res_u32_never;
-    //[normal]~^ ERROR refutable
+    //[normal,min_exh_pats]~^ ERROR refutable
 
     let result_never: Result<!, !> = x.result_never;
     match result_never {}
     //[normal]~^ ERROR non-exhaustive
     match result_never {
-        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match result_never {
         //[normal]~^ ERROR non-exhaustive
-        Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
-        _ => {}     //[exhaustive_patterns]~ ERROR unreachable pattern
+        Ok(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
+        _ => {}     //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {}  //[exhaustive_patterns]~ ERROR unreachable pattern
-        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Ok(_) => {}  //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
 }
 
@@ -145,11 +148,11 @@ fn void_same_as_never(x: NeverBundle) {
         }
         match opt_void {
             None => {}
-            Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+            Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
         }
         match opt_void {
             None => {}
-            _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+            _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
         }
 
         let ref_void: &Void = &x.void;
@@ -159,7 +162,7 @@ fn void_same_as_never(x: NeverBundle) {
         }
         let ref_opt_void: &Option<Void> = &None;
         match *ref_opt_void {
-            //[normal]~^ ERROR non-exhaustive
+            //[normal,min_exh_pats]~^ ERROR non-exhaustive
             None => {}
         }
         match *ref_opt_void {
@@ -284,11 +287,11 @@ fn nested_validity_tracking(bundle: NeverBundle) {
         _ => {} //~ ERROR unreachable pattern
     }
     match tuple_never {
-        (_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        (_, _) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match result_never {
-        Ok(_) => {}  //[exhaustive_patterns]~ ERROR unreachable pattern
-        Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Ok(_) => {}  //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
+        Err(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
 
     // These should be considered !known_valid and not warn unreachable.
@@ -309,13 +312,13 @@ fn invalid_empty_match(bundle: NeverBundle) {
     match *x {}
 
     let x: &(u32, !) = &bundle.tuple_half_never;
-    match *x {} //[normal]~ ERROR non-exhaustive
+    match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
     let x: &(!, !) = &bundle.tuple_never;
-    match *x {} //[normal]~ ERROR non-exhaustive
+    match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
     let x: &Result<!, !> = &bundle.result_never;
-    match *x {} //[normal]~ ERROR non-exhaustive
+    match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
     let x: &[!; 3] = &bundle.array_3_never;
-    match *x {} //[normal]~ ERROR non-exhaustive
+    match *x {} //[normal,min_exh_pats]~ ERROR non-exhaustive
 }
 
 fn arrays_and_slices(x: NeverBundle) {
@@ -323,7 +326,7 @@ fn arrays_and_slices(x: NeverBundle) {
     match slice_never {}
     //~^ ERROR non-empty
     match slice_never {
-        //[normal]~^ ERROR not covered
+        //[normal,min_exh_pats]~^ ERROR not covered
         [] => {}
     }
     match slice_never {
@@ -332,7 +335,7 @@ fn arrays_and_slices(x: NeverBundle) {
         [_, _, ..] => {}
     }
     match slice_never {
-        //[normal]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
+        //[normal,min_exh_pats]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
         //[exhaustive_patterns]~^^ ERROR `&[]` not covered
         [_, _, _, ..] => {}
     }
@@ -345,7 +348,7 @@ fn arrays_and_slices(x: NeverBundle) {
         _x => {}
     }
     match slice_never {
-        //[normal]~^ ERROR `&[]` and `&[_, ..]` not covered
+        //[normal,min_exh_pats]~^ ERROR `&[]` and `&[_, ..]` not covered
         //[exhaustive_patterns]~^^ ERROR `&[]` not covered
         &[..] if false => {}
     }
@@ -360,13 +363,13 @@ fn arrays_and_slices(x: NeverBundle) {
     match array_3_never {}
     //[normal]~^ ERROR non-empty
     match array_3_never {
-        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match array_3_never {
-        [_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        [_, _, _] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match array_3_never {
-        [_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        [_, ..] => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
 
     let ref_array_3_never: &[!; 3] = &array_3_never;
@@ -408,22 +411,22 @@ fn bindings(x: NeverBundle) {
     match opt_never {
         None => {}
         // !useful, !reachable
-        Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Some(_) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match opt_never {
         None => {}
         // !useful, !reachable
-        Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        Some(_a) => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match opt_never {
         None => {}
         // !useful, !reachable
-        _ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        _ => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
     match opt_never {
         None => {}
         // !useful, !reachable
-        _a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
+        _a => {} //[exhaustive_patterns,min_exh_pats]~ ERROR unreachable pattern
     }
 
     // The scrutinee is known_valid, but under the `&` isn't anymore.
@@ -444,7 +447,7 @@ fn bindings(x: NeverBundle) {
         &_a => {}
     }
     match ref_opt_never {
-        //[normal]~^ ERROR non-exhaustive
+        //[normal,min_exh_pats]~^ ERROR non-exhaustive
         &None => {}
     }
     match ref_opt_never {
@@ -485,7 +488,7 @@ fn bindings(x: NeverBundle) {
         ref _a => {}
     }
     match *ref_opt_never {
-        //[normal]~^ ERROR non-exhaustive
+        //[normal,min_exh_pats]~^ ERROR non-exhaustive
         None => {}
     }
     match *ref_opt_never {
@@ -533,7 +536,7 @@ fn bindings(x: NeverBundle) {
 
     let ref_res_never: &Result<!, !> = &x.result_never;
     match *ref_res_never {
-        //[normal]~^ ERROR non-exhaustive
+        //[normal,min_exh_pats]~^ ERROR non-exhaustive
         // useful, reachable
         Ok(_) => {}
     }
@@ -544,7 +547,7 @@ fn bindings(x: NeverBundle) {
         _ => {}
     }
     match *ref_res_never {
-        //[normal]~^ ERROR non-exhaustive
+        //[normal,min_exh_pats]~^ ERROR non-exhaustive
         // useful, !reachable
         Ok(_a) => {}
     }
@@ -563,7 +566,7 @@ fn bindings(x: NeverBundle) {
 
     let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never;
     match *ref_tuple_half_never {}
-    //[normal]~^ ERROR non-empty
+    //[normal,min_exh_pats]~^ ERROR non-empty
     match *ref_tuple_half_never {
         // useful, reachable
         (_, _) => {}
@@ -614,6 +617,7 @@ fn guards_and_validity(x: NeverBundle) {
         // useful, reachable
         _ => {}
     }
+
     // Now the madness commences. The guard caused a load of the value thus asserting validity. So
     // there's no invalid value for `_` to catch. So the second pattern is unreachable despite the
     // guard not being taken.
@@ -629,7 +633,7 @@ fn guards_and_validity(x: NeverBundle) {
         _a if false => {}
     }
     match ref_never {
-        //[normal]~^ ERROR non-exhaustive
+        //[normal,min_exh_pats]~^ ERROR non-exhaustive
         // useful, !reachable
         &_a if false => {}
     }
@@ -657,7 +661,7 @@ fn diagnostics_subtlety(x: NeverBundle) {
     // Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`.
     let x: &Option<Result<!, !>> = &None;
     match *x {
-        //[normal]~^ ERROR `Some(_)` not covered
+        //[normal,min_exh_pats]~^ ERROR `Some(_)` not covered
         None => {}
     }
 }
diff --git a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs
index 4203dd94d43..51ff641509d 100644
--- a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs
+++ b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs
@@ -1,6 +1,6 @@
 fn main() {
     let f = |3: isize| println!("hello");
-    //~^ ERROR refutable pattern in function argument
+    //~^ ERROR refutable pattern in closure argument
     //~| `..=2_isize` and `4_isize..` not covered
     f(4);
 }
diff --git a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr
index bd6c5002e63..be119d27ab2 100644
--- a/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr
+++ b/tests/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr
@@ -1,4 +1,4 @@
-error[E0005]: refutable pattern in function argument
+error[E0005]: refutable pattern in closure argument
   --> $DIR/refutable-pattern-in-fn-arg.rs:2:14
    |
 LL |     let f = |3: isize| println!("hello");
diff --git a/tests/ui/pin-macro/cant_access_internals.rs b/tests/ui/pin-macro/cant_access_internals.rs
index 5826a18b571..4aeb6a643d9 100644
--- a/tests/ui/pin-macro/cant_access_internals.rs
+++ b/tests/ui/pin-macro/cant_access_internals.rs
@@ -8,5 +8,5 @@ use core::{
 
 fn main() {
     let mut phantom_pinned = pin!(PhantomPinned);
-    mem::take(phantom_pinned.pointer); //~ ERROR use of unstable library feature 'unsafe_pin_internals'
+    mem::take(phantom_pinned.__pointer); //~ ERROR use of unstable library feature 'unsafe_pin_internals'
 }
diff --git a/tests/ui/pin-macro/cant_access_internals.stderr b/tests/ui/pin-macro/cant_access_internals.stderr
index 2737b84f599..444314a9d8b 100644
--- a/tests/ui/pin-macro/cant_access_internals.stderr
+++ b/tests/ui/pin-macro/cant_access_internals.stderr
@@ -1,8 +1,8 @@
 error[E0658]: use of unstable library feature 'unsafe_pin_internals'
   --> $DIR/cant_access_internals.rs:11:15
    |
-LL |     mem::take(phantom_pinned.pointer);
-   |               ^^^^^^^^^^^^^^^^^^^^^^
+LL |     mem::take(phantom_pinned.__pointer);
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(unsafe_pin_internals)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
diff --git a/tests/ui/print_type_sizes/niche-filling.stdout b/tests/ui/print_type_sizes/niche-filling.stdout
index d1753c26ca8..b53b8936603 100644
--- a/tests/ui/print_type_sizes/niche-filling.stdout
+++ b/tests/ui/print_type_sizes/niche-filling.stdout
@@ -14,17 +14,17 @@ print-type-size         field `.pre`: 1 bytes
 print-type-size         field `.post`: 2 bytes
 print-type-size         field `.val`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<Union1<std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<Union1<std::num::NonZero<u32>>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<Union2<std::num::NonZeroU32, std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<Union2<std::num::NonZero<u32>, std::num::NonZero<u32>>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<Union2<std::num::NonZeroU32, u32>>`: 8 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<Union2<std::num::NonZero<u32>, u32>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
@@ -53,22 +53,22 @@ print-type-size type: `MyOption<char>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `Union1<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `Union1<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Union1`: 4 bytes
 print-type-size         field `.a`: 4 bytes
-print-type-size type: `Union2<std::num::NonZeroU32, std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `Union2<std::num::NonZero<u32>, std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Union2`: 4 bytes
 print-type-size         field `.a`: 4 bytes
 print-type-size         field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
-print-type-size type: `Union2<std::num::NonZeroU32, u32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `Union2<std::num::NonZero<u32>, u32>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Union2`: 4 bytes
 print-type-size         field `.a`: 4 bytes
 print-type-size         field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
-print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes
+print-type-size type: `std::num::NonZero<u32>`: 4 bytes, alignment: 4 bytes
 print-type-size     field `.0`: 4 bytes
 print-type-size type: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes
 print-type-size     variant `Four`: 2 bytes
diff --git a/tests/ui/proc-macro/allowed-attr-stmt-expr.stdout b/tests/ui/proc-macro/allowed-attr-stmt-expr.stdout
index 8459f4e6305..947d411e849 100644
--- a/tests/ui/proc-macro/allowed-attr-stmt-expr.stdout
+++ b/tests/ui/proc-macro/allowed-attr-stmt-expr.stdout
@@ -1,5 +1,4 @@
 PRINT-ATTR INPUT (DISPLAY): struct ItemWithSemi;
-PRINT-ATTR RE-COLLECTED (DISPLAY): struct ItemWithSemi ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -47,7 +46,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!";
-PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_let] let string = "Hello, world!" ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -90,7 +88,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro!("{}", string);
-PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string) ;
+PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string);
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -144,7 +142,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): second_make_stmt!(#[allow(dead_code)] struct Bar {});
-PRINT-ATTR RE-COLLECTED (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar {}) ;
+PRINT-ATTR RE-COLLECTED (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar {});
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "second_make_stmt",
@@ -293,7 +291,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] struct NonBracedStruct;
-PRINT-ATTR RE-COLLECTED (DISPLAY): #[rustc_dummy] struct NonBracedStruct ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
diff --git a/tests/ui/proc-macro/attr-stmt-expr.stdout b/tests/ui/proc-macro/attr-stmt-expr.stdout
index 5e09198bbd4..e9fcbe304a0 100644
--- a/tests/ui/proc-macro/attr-stmt-expr.stdout
+++ b/tests/ui/proc-macro/attr-stmt-expr.stdout
@@ -30,7 +30,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): #[expect_let] let string = "Hello, world!";
-PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_let] let string = "Hello, world!" ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -73,7 +72,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro!("{}", string);
-PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string) ;
+PRINT-ATTR RE-COLLECTED (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string);
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -127,7 +126,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): second_make_stmt!(#[allow(dead_code)] struct Bar {});
-PRINT-ATTR RE-COLLECTED (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar {}) ;
+PRINT-ATTR RE-COLLECTED (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar {});
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "second_make_stmt",
diff --git a/tests/ui/proc-macro/attribute-spans-preserved.stdout b/tests/ui/proc-macro/attribute-spans-preserved.stdout
index 190098d0211..28f4daecc0e 100644
--- a/tests/ui/proc-macro/attribute-spans-preserved.stdout
+++ b/tests/ui/proc-macro/attribute-spans-preserved.stdout
@@ -1 +1 @@
-fn main() { let y : u32 = "z" ; { let x: u32 = "y"; } }
+fn main() { let y : u32 = "z"; { let x: u32 = "y"; } }
diff --git a/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs
index 7a29894bbcf..0af62888449 100644
--- a/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs
+++ b/tests/ui/proc-macro/auxiliary/attr-stmt-expr.rs
@@ -10,14 +10,14 @@ use proc_macro::TokenStream;
 #[proc_macro_attribute]
 pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "let string = \"Hello, world!\" ;");
+    assert_eq!(item.to_string(), "let string = \"Hello, world!\";");
     item
 }
 
 #[proc_macro_attribute]
 pub fn expect_my_macro_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "my_macro! (\"{}\", string) ;");
+    assert_eq!(item.to_string(), "my_macro! (\"{}\", string);");
     item
 }
 
diff --git a/tests/ui/proc-macro/cfg-eval-inner.stdout b/tests/ui/proc-macro/cfg-eval-inner.stdout
index 43ae47c201f..9fa8f437d0e 100644
--- a/tests/ui/proc-macro/cfg-eval-inner.stdout
+++ b/tests/ui/proc-macro/cfg-eval-inner.stdout
@@ -11,10 +11,10 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): impl Foo <
     { field: [u8; { #![rustc_dummy(another_cursed_inner)] 1 }] } 0
 }] > { #![rustc_dummy(evaluated_attr)] fn bar() {} }
 PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl Foo <
-[u8 ;
+[u8;
 {
     #! [rustc_dummy(cursed_inner)] #! [allow(unused)] struct Inner
-    { field : [u8 ; { #! [rustc_dummy(another_cursed_inner)] 1 }] } 0
+    { field : [u8; { #! [rustc_dummy(another_cursed_inner)] 1 }] } 0
 }] > { #! [rustc_dummy(evaluated_attr)] fn bar() {} }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs
index 4a7e48eed46..b484b42e566 100644
--- a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs
+++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs
@@ -5,7 +5,7 @@
 #[macro_use]
 extern crate test_macros;
 
-#[derive(Empty)] //~ ERROR cannot determine resolution for the attribute macro `derive`
+#[derive(Empty)]
 #[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope
 struct Foo {}
 
diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr
index fd1ed8a3d0f..b34713b8ca6 100644
--- a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr
+++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr
@@ -4,19 +4,11 @@ error: cannot find attribute `dummy` in this scope
 LL | #![dummy]
    |    ^^^^^
 
-error: cannot determine resolution for the attribute macro `derive`
-  --> $DIR/derive-helper-legacy-spurious.rs:8:3
-   |
-LL | #[derive(Empty)]
-   |   ^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: cannot find attribute `empty_helper` in this scope
   --> $DIR/derive-helper-legacy-spurious.rs:9:3
    |
 LL | #[empty_helper]
    |   ^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/proc-macro/doc-comment-preserved.stdout b/tests/ui/proc-macro/doc-comment-preserved.stdout
index b0ea180d9bd..e9db3785d3d 100644
--- a/tests/ui/proc-macro/doc-comment-preserved.stdout
+++ b/tests/ui/proc-macro/doc-comment-preserved.stdout
@@ -6,7 +6,7 @@ PRINT-BANG INPUT (DISPLAY): /**
 *******
 */
  pub struct S;
-PRINT-BANG RE-COLLECTED (DISPLAY): #[doc = "\n*******\n* DOC *\n* DOC *\n* DOC *\n*******\n"] pub struct S ;
+PRINT-BANG RE-COLLECTED (DISPLAY): #[doc = "\n*******\n* DOC *\n* DOC *\n* DOC *\n*******\n"] pub struct S;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
diff --git a/tests/ui/proc-macro/dollar-crate-issue-57089.stdout b/tests/ui/proc-macro/dollar-crate-issue-57089.stdout
index 7f97ac9dbc2..79b39d36ffb 100644
--- a/tests/ui/proc-macro/dollar-crate-issue-57089.stdout
+++ b/tests/ui/proc-macro/dollar-crate-issue-57089.stdout
@@ -1,5 +1,4 @@
 PRINT-BANG INPUT (DISPLAY): struct M($crate :: S);
-PRINT-BANG RE-COLLECTED (DISPLAY): struct M($crate :: S) ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -40,7 +39,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S);
-PRINT-ATTR RE-COLLECTED (DISPLAY): struct A($crate :: S) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
diff --git a/tests/ui/proc-macro/dollar-crate-issue-62325.stdout b/tests/ui/proc-macro/dollar-crate-issue-62325.stdout
index 96161049e30..bfd013476f3 100644
--- a/tests/ui/proc-macro/dollar-crate-issue-62325.stdout
+++ b/tests/ui/proc-macro/dollar-crate-issue-62325.stdout
@@ -1,5 +1,4 @@
 PRINT-ATTR INPUT (DISPLAY): struct A(identity! ($crate :: S));
-PRINT-ATTR RE-COLLECTED (DISPLAY): struct A(identity! ($crate :: S)) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -55,7 +54,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct B(identity! ($crate :: S));
-PRINT-ATTR RE-COLLECTED (DISPLAY): struct B(identity! ($crate :: S)) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
diff --git a/tests/ui/proc-macro/dollar-crate.stdout b/tests/ui/proc-macro/dollar-crate.stdout
index a6bdab00441..0278ef1ad0f 100644
--- a/tests/ui/proc-macro/dollar-crate.stdout
+++ b/tests/ui/proc-macro/dollar-crate.stdout
@@ -1,5 +1,4 @@
 PRINT-BANG INPUT (DISPLAY): struct M($crate :: S);
-PRINT-BANG RE-COLLECTED (DISPLAY): struct M($crate :: S) ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -40,7 +39,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S);
-PRINT-ATTR RE-COLLECTED (DISPLAY): struct A($crate :: S) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -81,7 +79,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): struct D($crate :: S);
-PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D($crate :: S) ;
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -122,7 +119,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-BANG INPUT (DISPLAY): struct M($crate :: S);
-PRINT-BANG RE-COLLECTED (DISPLAY): struct M($crate :: S) ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -163,7 +159,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S);
-PRINT-ATTR RE-COLLECTED (DISPLAY): struct A($crate :: S) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -204,7 +199,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): struct D($crate :: S);
-PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D($crate :: S) ;
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
diff --git a/tests/ui/proc-macro/expand-to-derive.stdout b/tests/ui/proc-macro/expand-to-derive.stdout
index 9f03a469aeb..d59b7e5b88f 100644
--- a/tests/ui/proc-macro/expand-to-derive.stdout
+++ b/tests/ui/proc-macro/expand-to-derive.stdout
@@ -1,12 +1,12 @@
 PRINT-DERIVE INPUT (DISPLAY): struct Foo
 {
     field :
-    [bool ; { #[rustc_dummy] struct Inner { other_inner_field: u8, } 0 }]
+    [bool; { #[rustc_dummy] struct Inner { other_inner_field: u8, } 0 }]
 }
 PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct Foo
 {
     field :
-    [bool ; { #[rustc_dummy] struct Inner { other_inner_field : u8, } 0 }]
+    [bool; { #[rustc_dummy] struct Inner { other_inner_field : u8, } 0 }]
 }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
diff --git a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout
index eda2f433bce..ddd59b583a8 100644
--- a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout
+++ b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout
@@ -1,5 +1,5 @@
-PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] 0 ; 0 }, }
-PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = #[allow(warnings)] #[allow(warnings)] 0 ; 0 }, }
+PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] 0; 0 }, }
+PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = #[allow(warnings)] #[allow(warnings)] 0; 0 }, }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
@@ -123,7 +123,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0; }; 0 }, }
-PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { 0 } ; 0 }, }
+PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { 0 }; 0 }, }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
@@ -203,7 +203,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { {} }; 0 }, }
-PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { {} } ; 0 }, }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
@@ -282,7 +281,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH; }; 0 }, }
-PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { PATH } ; 0 }, }
+PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { PATH }; 0 }, }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
@@ -360,7 +359,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0 + 1; }; 0 }, }
-PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { 0 + 1 } ; 0 }, }
+PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { 0 + 1 }; 0 }, }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
@@ -451,7 +450,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH + 1; }; 0 }, }
-PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { PATH + 1 } ; 0 }, }
+PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { PATH + 1 }; 0 }, }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
diff --git a/tests/ui/proc-macro/inert-attribute-order.stdout b/tests/ui/proc-macro/inert-attribute-order.stdout
index 86b27217974..95b34ae84fd 100644
--- a/tests/ui/proc-macro/inert-attribute-order.stdout
+++ b/tests/ui/proc-macro/inert-attribute-order.stdout
@@ -2,10 +2,10 @@ PRINT-ATTR INPUT (DISPLAY): /// 1
 #[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5] /// 6
 #[print_attr(nodebug)] struct S;
 PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5]
-#[doc = " 6"] #[print_attr(nodebug)] struct S ;
+#[doc = " 6"] #[print_attr(nodebug)] struct S;
 PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
-#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S ;
+#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S;
 PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[rustfmt::attr2] #[doc = "3"] #[doc = "4"] #[rustfmt::attr5]
-#[doc = " 6"] struct S ;
+#[doc = " 6"] struct S;
 PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
-#[rustfmt :: attr5] #[doc = " 6"] struct S ;
+#[rustfmt :: attr5] #[doc = " 6"] struct S;
diff --git a/tests/ui/proc-macro/inner-attrs.stdout b/tests/ui/proc-macro/inner-attrs.stdout
index 39ec6834f06..c8d93babe3a 100644
--- a/tests/ui/proc-macro/inner-attrs.stdout
+++ b/tests/ui/proc-macro/inner-attrs.stdout
@@ -581,10 +581,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
 PRINT-DERIVE INPUT (DISPLAY): struct MyDerivePrint
 { field: [u8; { match true { _ => { #![rustc_dummy(third)] true } }; 0 }] }
 PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct MyDerivePrint
-{
-    field :
-    [u8 ; { match true { _ => { #! [rustc_dummy(third)] true } } ; 0 }]
-}
+{ field : [u8; { match true { _ => { #! [rustc_dummy(third)] true } }; 0 }] }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -718,8 +715,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 });
-PRINT-ATTR RE-COLLECTED (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
-PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
+PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 });
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Group {
         delimiter: Parenthesis,
@@ -834,8 +830,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 });
-PRINT-ATTR RE-COLLECTED (DISPLAY): (3, 4, { #![cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
-PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
+PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 });
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Group {
         delimiter: Parenthesis,
diff --git a/tests/ui/proc-macro/input-interpolated.stdout b/tests/ui/proc-macro/input-interpolated.stdout
index 6a8789b2c41..f2a0bc3b1aa 100644
--- a/tests/ui/proc-macro/input-interpolated.stdout
+++ b/tests/ui/proc-macro/input-interpolated.stdout
@@ -5,7 +5,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
         span: #0 bytes(503..504),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): const A : u8 = 0 ;
+PRINT-ATTR INPUT (DISPLAY): const A : u8 = 0;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "const",
diff --git a/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs b/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs
new file mode 100644
index 00000000000..baef0206128
--- /dev/null
+++ b/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs
@@ -0,0 +1,6 @@
+#![some_nonexistent_attribute]
+//~^ ERROR cannot find attribute `some_nonexistent_attribute` in this scope
+#[derive(Debug)]
+pub struct SomeUserCode;
+
+fn main() {}
diff --git a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr
new file mode 100644
index 00000000000..fa8af87a3d0
--- /dev/null
+++ b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr
@@ -0,0 +1,8 @@
+error: cannot find attribute `some_nonexistent_attribute` in this scope
+  --> $DIR/issue-118455-skip-err-builtin.rs:1:4
+   |
+LL | #![some_nonexistent_attribute]
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/proc-macro/issue-75734-pp-paren.stdout b/tests/ui/proc-macro/issue-75734-pp-paren.stdout
index ee135366fb6..9919ab5625f 100644
--- a/tests/ui/proc-macro/issue-75734-pp-paren.stdout
+++ b/tests/ui/proc-macro/issue-75734-pp-paren.stdout
@@ -1,5 +1,5 @@
 PRINT-ATTR INPUT (DISPLAY): fn main() { &|_: u8| {}; mul_2!(1 + 1); }
-PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): fn main() { &| _ : u8 | {} ; mul_2! (1 + 1) ; }
+PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): fn main() { &| _ : u8 | {}; mul_2! (1 + 1); }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "fn",
diff --git a/tests/ui/proc-macro/issue-75930-derive-cfg.stdout b/tests/ui/proc-macro/issue-75930-derive-cfg.stdout
index 093e37f8a8d..cc712abf2a5 100644
--- a/tests/ui/proc-macro/issue-75930-derive-cfg.stdout
+++ b/tests/ui/proc-macro/issue-75930-derive-cfg.stdout
@@ -51,22 +51,22 @@ struct Foo <#[cfg(FALSE)] A, B >
 {
     #[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second :
     bool, third :
-    [u8 ;
+    [u8;
     {
-        #[cfg(FALSE)] struct Bar ; #[cfg(not(FALSE))] struct Inner ;
-        #[cfg(FALSE)] let a = 25 ; match true
+        #[cfg(FALSE)] struct Bar; #[cfg(not(FALSE))] struct Inner;
+        #[cfg(FALSE)] let a = 25; match true
         {
             #[cfg(FALSE)] true => {}, #[cfg_attr(not(FALSE), allow(warnings))]
             false => {}, _ => {}
-        } ; #[print_helper(should_be_removed)] fn removed_fn()
+        }; #[print_helper(should_be_removed)] fn removed_fn()
         { #! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn()
-        { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
+        { #! [cfg(not(FALSE))] let my_val = true; } enum TupleEnum
         {
             Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32,
             #[cfg(FALSE)] String, u8)
         } struct
         TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32,
-        #[cfg(FALSE)] bool, u8) ; fn plain_removed_fn()
+        #[cfg(FALSE)] bool, u8); fn plain_removed_fn()
         { #! [cfg_attr(not(FALSE), cfg(FALSE))] } 0
     }], #[print_helper(d)] fourth : B
 }
@@ -1336,14 +1336,14 @@ PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_hel
 PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_helper(b)] struct Foo <B >
 {
     second : bool, third :
-    [u8 ;
+    [u8;
     {
-        #[cfg(not(FALSE))] struct Inner ; match true
-        { #[allow(warnings)] false => {}, _ => {} } ; #[print_helper(c)]
+        #[cfg(not(FALSE))] struct Inner; match true
+        { #[allow(warnings)] false => {}, _ => {} }; #[print_helper(c)]
         #[cfg(not(FALSE))] fn kept_fn()
-        { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
+        { #! [cfg(not(FALSE))] let my_val = true; } enum TupleEnum
         { Foo(#[cfg(not(FALSE))] i32, u8) } struct
-        TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0
+        TupleStruct(#[cfg(not(FALSE))] i32, u8); 0
     }], #[print_helper(d)] fourth : B
 }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
diff --git a/tests/ui/proc-macro/issue-76182-leading-vert-pat.stdout b/tests/ui/proc-macro/issue-76182-leading-vert-pat.stdout
index 09eb33f7e31..fdbf9118cd3 100644
--- a/tests/ui/proc-macro/issue-76182-leading-vert-pat.stdout
+++ b/tests/ui/proc-macro/issue-76182-leading-vert-pat.stdout
@@ -1,4 +1,4 @@
-PRINT-ATTR INPUT (DISPLAY): fn main() { match() { | () => () } }
+PRINT-ATTR INPUT (DISPLAY): fn main() { match () { | () => () } }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "fn",
diff --git a/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.fixed b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.fixed
new file mode 100644
index 00000000000..ae5f9f86726
--- /dev/null
+++ b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+
+#[derive(Debug)] //~ ERROR `derive` attribute cannot be used at crate level
+struct Test {}
+
+fn main() {}
diff --git a/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs
new file mode 100644
index 00000000000..639c64f8827
--- /dev/null
+++ b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs
@@ -0,0 +1,6 @@
+// run-rustfix
+
+#![derive(Debug)] //~ ERROR `derive` attribute cannot be used at crate level
+struct Test {}
+
+fn main() {}
diff --git a/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr
new file mode 100644
index 00000000000..f62cdd14b87
--- /dev/null
+++ b/tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr
@@ -0,0 +1,16 @@
+error: `derive` attribute cannot be used at crate level
+  --> $DIR/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs:3:1
+   |
+LL | #![derive(Debug)]
+   | ^^^^^^^^^^^^^^^^^
+LL | struct Test {}
+   |        ---- the inner attribute doesn't annotate this struct
+   |
+help: perhaps you meant to use an outer attribute
+   |
+LL - #![derive(Debug)]
+LL + #[derive(Debug)]
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/proc-macro/keep-expr-tokens.stdout b/tests/ui/proc-macro/keep-expr-tokens.stdout
index 8e4d4785e2e..fdd19126109 100644
--- a/tests/ui/proc-macro/keep-expr-tokens.stdout
+++ b/tests/ui/proc-macro/keep-expr-tokens.stdout
@@ -1,5 +1,5 @@
 PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] { 1 +1; }
-PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[rustc_dummy] { 1 + 1 ; }
+PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[rustc_dummy] { 1 + 1; }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
diff --git a/tests/ui/proc-macro/macro-rules-derive-cfg.stdout b/tests/ui/proc-macro/macro-rules-derive-cfg.stdout
index 89817a1efdc..257d59974b8 100644
--- a/tests/ui/proc-macro/macro-rules-derive-cfg.stdout
+++ b/tests/ui/proc-macro/macro-rules-derive-cfg.stdout
@@ -1,7 +1,7 @@
 PRINT-DERIVE INPUT (DISPLAY): struct Foo
 {
     val :
-    [bool ;
+    [bool;
     {
         let a = #[rustc_dummy(first)] #[rustc_dummy(second)]
         { #![allow(unused)] 30 }; 0
@@ -10,10 +10,10 @@ PRINT-DERIVE INPUT (DISPLAY): struct Foo
 PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct Foo
 {
     val :
-    [bool ;
+    [bool;
     {
         let a = #[rustc_dummy(first)] #[rustc_dummy(second)]
-        { #! [allow(unused)] 30 } ; 0
+        { #! [allow(unused)] 30 }; 0
     }]
 }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
diff --git a/tests/ui/proc-macro/nested-derive-cfg.stdout b/tests/ui/proc-macro/nested-derive-cfg.stdout
index c94808c3c0f..a3046e4ab85 100644
--- a/tests/ui/proc-macro/nested-derive-cfg.stdout
+++ b/tests/ui/proc-macro/nested-derive-cfg.stdout
@@ -1,7 +1,7 @@
 PRINT-DERIVE INPUT (DISPLAY): struct Foo
 { my_array: [bool; { struct Inner { non_removed_inner_field: usize } 0 }] }
 PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): struct Foo
-{ my_array : [bool ; { struct Inner { non_removed_inner_field : usize } 0 }] }
+{ my_array : [bool; { struct Inner { non_removed_inner_field : usize } 0 }] }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
index d3c2c46ac75..cf9addb8a94 100644
--- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
+++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
@@ -1,5 +1,4 @@
 PRINT-BANG INPUT (DISPLAY): struct S;
-PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): struct S ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Group {
         delimiter: None,
diff --git a/tests/ui/proc-macro/pretty-print-tts.stdout b/tests/ui/proc-macro/pretty-print-tts.stdout
index fbe8640a01a..ce404313507 100644
--- a/tests/ui/proc-macro/pretty-print-tts.stdout
+++ b/tests/ui/proc-macro/pretty-print-tts.stdout
@@ -1,5 +1,5 @@
 PRINT-BANG INPUT (DISPLAY): { #![rustc_dummy] let a = "hello".len(); matches!(a, 5); }
-PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): { #! [rustc_dummy] let a = "hello".len() ; matches! (a, 5) ; }
+PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): { #! [rustc_dummy] let a = "hello".len(); matches! (a, 5); }
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Group {
         delimiter: Brace,
diff --git a/tests/ui/reserved/reserved-attr-on-macro.rs b/tests/ui/reserved/reserved-attr-on-macro.rs
index 2630db0d097..5c4657e0ec2 100644
--- a/tests/ui/reserved/reserved-attr-on-macro.rs
+++ b/tests/ui/reserved/reserved-attr-on-macro.rs
@@ -7,5 +7,5 @@ macro_rules! foo {
 }
 
 fn main() {
-    foo!(); //~ ERROR cannot determine resolution for the macro `foo`
+    foo!();
 }
diff --git a/tests/ui/reserved/reserved-attr-on-macro.stderr b/tests/ui/reserved/reserved-attr-on-macro.stderr
index e55b58bef28..066f72367b1 100644
--- a/tests/ui/reserved/reserved-attr-on-macro.stderr
+++ b/tests/ui/reserved/reserved-attr-on-macro.stderr
@@ -4,19 +4,11 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp
 LL | #[rustc_attribute_should_be_reserved]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: cannot determine resolution for the macro `foo`
-  --> $DIR/reserved-attr-on-macro.rs:10:5
-   |
-LL |     foo!();
-   |     ^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: cannot find attribute `rustc_attribute_should_be_reserved` in this scope
   --> $DIR/reserved-attr-on-macro.rs:1:3
    |
 LL | #[rustc_attribute_should_be_reserved]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rust-2018/issue-54006.rs b/tests/ui/rust-2018/issue-54006.rs
index a7a4770fc02..6f929731c76 100644
--- a/tests/ui/rust-2018/issue-54006.rs
+++ b/tests/ui/rust-2018/issue-54006.rs
@@ -8,6 +8,5 @@ use alloc::vec;
 
 pub fn foo() {
     let mut xs = vec![];
-    //~^ ERROR cannot determine resolution for the macro `vec`
     xs.push(0);
 }
diff --git a/tests/ui/rust-2018/issue-54006.stderr b/tests/ui/rust-2018/issue-54006.stderr
index 1978138a688..35d4c17d2c7 100644
--- a/tests/ui/rust-2018/issue-54006.stderr
+++ b/tests/ui/rust-2018/issue-54006.stderr
@@ -4,14 +4,6 @@ error[E0432]: unresolved import `alloc`
 LL | use alloc::vec;
    |     ^^^^^ help: a similar path exists: `core::alloc`
 
-error: cannot determine resolution for the macro `vec`
-  --> $DIR/issue-54006.rs:10:18
-   |
-LL |     let mut xs = vec![];
-   |                  ^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/span/issue-43927-non-ADT-derive.rs b/tests/ui/span/issue-43927-non-ADT-derive.rs
index 935bfa001bf..e50ee36d7de 100644
--- a/tests/ui/span/issue-43927-non-ADT-derive.rs
+++ b/tests/ui/span/issue-43927-non-ADT-derive.rs
@@ -1,6 +1,5 @@
 #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
-//~^ ERROR cannot determine resolution for the attribute macro `derive`
-//~^^ ERROR `derive` attribute cannot be used at crate level
+//~^ ERROR `derive` attribute cannot be used at crate level
 struct DerivedOn;
 
 fn main() {}
diff --git a/tests/ui/span/issue-43927-non-ADT-derive.stderr b/tests/ui/span/issue-43927-non-ADT-derive.stderr
index a22a4d2b40a..27ed561f5be 100644
--- a/tests/ui/span/issue-43927-non-ADT-derive.stderr
+++ b/tests/ui/span/issue-43927-non-ADT-derive.stderr
@@ -1,17 +1,9 @@
-error: cannot determine resolution for the attribute macro `derive`
-  --> $DIR/issue-43927-non-ADT-derive.rs:1:4
-   |
-LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
-   |    ^^^^^^
-   |
-   = note: import resolution is stuck, try simplifying macro imports
-
 error: `derive` attribute cannot be used at crate level
   --> $DIR/issue-43927-non-ADT-derive.rs:1:1
    |
 LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
+LL |
 LL | struct DerivedOn;
    |        --------- the inner attribute doesn't annotate this struct
    |
@@ -21,5 +13,5 @@ LL - #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
 LL + #[derive(Debug, PartialEq, Eq)] // should be an outer attribute!
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
index 75c91e4806f..e9b0845ccf7 100644
--- a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
@@ -12,10 +12,7 @@ error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait b
   --> $DIR/specialization-trait-not-implemented.rs:22:29
    |
 LL | struct MyStruct;
-   | ---------------
-   | |
-   | method `foo_one` not found for this struct
-   | doesn't satisfy `MyStruct: Foo`
+   | --------------- method `foo_one` not found for this struct because it doesn't satisfy `MyStruct: Foo`
 ...
 LL |     println!("{}", MyStruct.foo_one());
    |                             ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
diff --git a/tests/ui/str/str-escape.rs b/tests/ui/str/str-escape.rs
index 10a72421f24..89a82171063 100644
--- a/tests/ui/str/str-escape.rs
+++ b/tests/ui/str/str-escape.rs
@@ -1,5 +1,6 @@
 // check-pass
 // ignore-tidy-tab
+// edition: 2021
 
 fn main() {
     let s = "\
@@ -8,11 +9,11 @@ fn main() {
     //~^^^ WARNING multiple lines skipped by escaped newline
     assert_eq!(s, "");
 
-    let s = "foo\
+    let s = c"foo\
              bar
              ";
     //~^^^ WARNING whitespace symbol '\u{a0}' is not skipped
-    assert_eq!(s, "foo           bar\n             ");
+    assert_eq!(s, c"foo           bar\n             ");
 
     let s = "a\
  b";
@@ -22,10 +23,10 @@ fn main() {
 	b";
     assert_eq!(s, "ab");
 
-    let s = "a\
+    let s = b"a\
     b";
     //~^^ WARNING whitespace symbol '\u{c}' is not skipped
     // '\x0c' is ASCII whitespace, but it may not need skipped
     // discussion: https://github.com/rust-lang/rust/pull/108403
-    assert_eq!(s, "a\x0cb");
+    assert_eq!(s, b"a\x0cb");
 }
diff --git a/tests/ui/str/str-escape.stderr b/tests/ui/str/str-escape.stderr
index 43b4f7e36f6..00fe5444e1a 100644
--- a/tests/ui/str/str-escape.stderr
+++ b/tests/ui/str/str-escape.stderr
@@ -1,5 +1,5 @@
 warning: multiple lines skipped by escaped newline
-  --> $DIR/str-escape.rs:5:14
+  --> $DIR/str-escape.rs:6:14
    |
 LL |       let s = "\
    |  ______________^
@@ -8,20 +8,20 @@ LL | |              ";
    | |_____________^ skipping everything up to and including this point
 
 warning: whitespace symbol '\u{a0}' is not skipped
-  --> $DIR/str-escape.rs:11:17
+  --> $DIR/str-escape.rs:12:18
    |
-LL |       let s = "foo\
-   |  _________________^
+LL |       let s = c"foo\
+   |  __________________^
 LL | |              bar
    | |   ^ whitespace symbol '\u{a0}' is not skipped
    | |___|
    | 
 
 warning: whitespace symbol '\u{c}' is not skipped
-  --> $DIR/str-escape.rs:25:15
+  --> $DIR/str-escape.rs:26:16
    |
-LL |       let s = "a\
-   |  _______________^
+LL |       let s = b"a\
+   |  ________________^
 LL | |     b";
    | |    ^- whitespace symbol '\u{c}' is not skipped
    | |____|
diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr
index e6835bb54fb..d41f5808752 100644
--- a/tests/ui/str/str-mut-idx.stderr
+++ b/tests/ui/str/str-mut-idx.stderr
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/str-mut-idx.rs:4:15
    |
 LL |     s[1..2] = bot();
-   |               ^^^ doesn't have a size known at compile-time
+   |               ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
 note: required by a bound in `bot`
diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr
index e2db0da74f0..9d6d29ec74e 100644
--- a/tests/ui/suggestions/derive-trait-for-method-call.stderr
+++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr
@@ -2,10 +2,7 @@ error[E0599]: the method `test` exists for struct `Foo<Enum, CloneEnum>`, but it
   --> $DIR/derive-trait-for-method-call.rs:28:15
    |
 LL | enum Enum {
-   | ---------
-   | |
-   | doesn't satisfy `Enum: Clone`
-   | doesn't satisfy `Enum: Default`
+   | --------- doesn't satisfy `Enum: Clone` or `Enum: Default`
 ...
 LL | enum CloneEnum {
    | -------------- doesn't satisfy `CloneEnum: Default`
@@ -40,10 +37,7 @@ error[E0599]: the method `test` exists for struct `Foo<Struct, CloneStruct>`, bu
   --> $DIR/derive-trait-for-method-call.rs:34:15
    |
 LL | struct Struct {
-   | -------------
-   | |
-   | doesn't satisfy `Struct: Clone`
-   | doesn't satisfy `Struct: Default`
+   | ------------- doesn't satisfy `Struct: Clone` or `Struct: Default`
 ...
 LL | struct CloneStruct {
    | ------------------ doesn't satisfy `CloneStruct: Default`
@@ -85,12 +79,6 @@ LL | struct Foo<X, Y> (X, Y);
 ...
 LL |     let y = x.test();
    |               ^^^^ method cannot be called on `Foo<Vec<Enum>, Instant>` due to unsatisfied trait bounds
-  --> $SRC_DIR/std/src/time.rs:LL:COL
-   |
-   = note: doesn't satisfy `Instant: Default`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-   |
-   = note: doesn't satisfy `Vec<Enum>: Clone`
    |
 note: the following trait bounds were not satisfied:
       `Instant: Default`
diff --git a/tests/ui/suggestions/issue-104327.stderr b/tests/ui/suggestions/issue-104327.stderr
index 325b6b6eb4b..1bad82d471e 100644
--- a/tests/ui/suggestions/issue-104327.stderr
+++ b/tests/ui/suggestions/issue-104327.stderr
@@ -5,7 +5,7 @@ LL |     fn f() {}
    |     --------- `Foo::f` defined here
 ...
 LL |     Foo::f();
-   |     ^^^^^^ cannot call associated function of trait
+   |     ^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
diff --git a/tests/ui/suggestions/issue-104328.stderr b/tests/ui/suggestions/issue-104328.stderr
index a5926218341..3c5e6f16289 100644
--- a/tests/ui/suggestions/issue-104328.stderr
+++ b/tests/ui/suggestions/issue-104328.stderr
@@ -5,7 +5,7 @@ LL |     fn f() {}
    |     --------- `Foo::f` defined here
 ...
 LL |     Foo::f();
-   |     ^^^^^^ cannot call associated function of trait
+   |     ^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
diff --git a/tests/ui/suggestions/issue-89333.stderr b/tests/ui/suggestions/issue-89333.stderr
index 761de7f2521..9df850ec9de 100644
--- a/tests/ui/suggestions/issue-89333.stderr
+++ b/tests/ui/suggestions/issue-89333.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `for<'a> &'a _: Trait` is not satisfied
   --> $DIR/issue-89333.rs:6:5
    |
 LL |     test(&|| 0);
-   |     ^^^^ the trait `for<'a> Trait` is not implemented for `&'a _`
+   |     ^^^^^^^^^^^ the trait `for<'a> Trait` is not implemented for `&'a _`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/issue-89333.rs:9:1
diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
index 94710f4503f..09a9b1d3b34 100644
--- a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
+++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
@@ -25,9 +25,6 @@ error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`,
    |
 LL |     writeln!(fp, "hello world").unwrap();
    |     ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
-  --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
-   |
-   = note: doesn't satisfy `BufWriter<&dyn std::io::Write>: std::io::Write`
    |
 note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
   --> $DIR/mut-borrow-needed-by-trait.rs:21:14
diff --git a/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr b/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
index 125a8b44f2f..485015a98f2 100644
--- a/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
+++ b/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `&mut usize: Default` is not satisfied
   --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9
    |
 LL |     foo(Default::default());
-   |         ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize`
+   |         ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize`
    |
 help: consider mutably borrowing here
    |
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `&usize: Default` is not satisfied
   --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9
    |
 LL |     bar(Default::default());
-   |         ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize`
+   |         ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize`
    |
 help: consider borrowing here
    |
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed
new file mode 100644
index 00000000000..86ac07a93a3
--- /dev/null
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.fixed
@@ -0,0 +1,29 @@
+// run-rustfix
+
+struct A {
+
+}
+
+trait M {
+    fn foo(_a: Self);
+    fn bar(_a: Self);
+    fn baz(_a: i32);
+}
+
+impl M for A {
+    fn foo(_a: Self) {}
+    fn bar(_a: A) {}
+    fn baz(_a: i32) {}
+}
+
+fn main() {
+    let _a = A {};
+    A::foo(_a);
+    //~^ ERROR no method named `foo` found
+    A::baz(0);
+    //~^ ERROR no method named `baz` found
+
+    let _b = A {};
+    A::bar(_b);
+    //~^ ERROR no method named `bar` found
+}
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs
new file mode 100644
index 00000000000..9a57ffb7740
--- /dev/null
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs
@@ -0,0 +1,29 @@
+// run-rustfix
+
+struct A {
+
+}
+
+trait M {
+    fn foo(_a: Self);
+    fn bar(_a: Self);
+    fn baz(_a: i32);
+}
+
+impl M for A {
+    fn foo(_a: Self) {}
+    fn bar(_a: A) {}
+    fn baz(_a: i32) {}
+}
+
+fn main() {
+    let _a = A {};
+    _a.foo();
+    //~^ ERROR no method named `foo` found
+    _a.baz(0);
+    //~^ ERROR no method named `baz` found
+
+    let _b = A {};
+    _b.bar();
+    //~^ ERROR no method named `bar` found
+}
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr
new file mode 100644
index 00000000000..0df2b08d3be
--- /dev/null
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr
@@ -0,0 +1,60 @@
+error[E0599]: no method named `foo` found for struct `A` in the current scope
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:21:8
+   |
+LL | struct A {
+   | -------- method `foo` not found for this struct
+...
+LL |     _a.foo();
+   |     ---^^^--
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `A::foo(_a)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `M`
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:8:5
+   |
+LL |     fn foo(_a: Self);
+   |     ^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `baz` found for struct `A` in the current scope
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:23:8
+   |
+LL | struct A {
+   | -------- method `baz` not found for this struct
+...
+LL |     _a.baz(0);
+   |     ---^^^---
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `A::baz(0)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `M`
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:10:5
+   |
+LL |     fn baz(_a: i32);
+   |     ^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `bar` found for struct `A` in the current scope
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:27:8
+   |
+LL | struct A {
+   | -------- method `bar` not found for this struct
+...
+LL |     _b.bar();
+   |     ---^^^--
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `A::bar(_b)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `M`
+  --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:9:5
+   |
+LL |     fn bar(_a: Self);
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/suggestions/suggest-change-mut.stderr b/tests/ui/suggestions/suggest-change-mut.stderr
index d194afeaf93..216d1e810fd 100644
--- a/tests/ui/suggestions/suggest-change-mut.stderr
+++ b/tests/ui/suggestions/suggest-change-mut.stderr
@@ -27,9 +27,6 @@ error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its
    |
 LL |         stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
    |                       ^^^^^^^^^^ method cannot be called on `BufReader<&T>` due to unsatisfied trait bounds
-  --> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
-   |
-   = note: doesn't satisfy `BufReader<&T>: BufRead`
    |
    = note: the following trait bounds were not satisfied:
            `&T: std::io::Read`
diff --git a/tests/ui/symbol-mangling-version/bad-value.bad.stderr b/tests/ui/symbol-mangling-version/bad-value.bad.stderr
index c36c73c6069..a12e5e241c0 100644
--- a/tests/ui/symbol-mangling-version/bad-value.bad.stderr
+++ b/tests/ui/symbol-mangling-version/bad-value.bad.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `bad-value` for codegen option `symbol-mangling-version` - either `legacy` or `v0` (RFC 2603) was expected
+error: incorrect value `bad-value` for codegen option `symbol-mangling-version` - one of: `legacy`, `v0` (RFC 2603), or `hashed` was expected
 
diff --git a/tests/ui/symbol-mangling-version/bad-value.blank.stderr b/tests/ui/symbol-mangling-version/bad-value.blank.stderr
index 0e70af5b8ff..95456587781 100644
--- a/tests/ui/symbol-mangling-version/bad-value.blank.stderr
+++ b/tests/ui/symbol-mangling-version/bad-value.blank.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `` for codegen option `symbol-mangling-version` - either `legacy` or `v0` (RFC 2603) was expected
+error: incorrect value `` for codegen option `symbol-mangling-version` - one of: `legacy`, `v0` (RFC 2603), or `hashed` was expected
 
diff --git a/tests/ui/symbol-mangling-version/bad-value.no-value.stderr b/tests/ui/symbol-mangling-version/bad-value.no-value.stderr
index 77013b72b6c..325e47a281f 100644
--- a/tests/ui/symbol-mangling-version/bad-value.no-value.stderr
+++ b/tests/ui/symbol-mangling-version/bad-value.no-value.stderr
@@ -1,2 +1,2 @@
-error: codegen option `symbol-mangling-version` requires either `legacy` or `v0` (RFC 2603) (C symbol-mangling-version=<value>)
+error: codegen option `symbol-mangling-version` requires one of: `legacy`, `v0` (RFC 2603), or `hashed` (C symbol-mangling-version=<value>)
 
diff --git a/tests/ui/symbol-mangling-version/unstable.hashed.stderr b/tests/ui/symbol-mangling-version/unstable.hashed.stderr
new file mode 100644
index 00000000000..f2ae18290f2
--- /dev/null
+++ b/tests/ui/symbol-mangling-version/unstable.hashed.stderr
@@ -0,0 +1,2 @@
+error: `-C symbol-mangling-version=hashed` requires `-Z unstable-options`
+
diff --git a/tests/ui/symbol-mangling-version/unstable.rs b/tests/ui/symbol-mangling-version/unstable.rs
index df87a39cdfb..42750a64574 100644
--- a/tests/ui/symbol-mangling-version/unstable.rs
+++ b/tests/ui/symbol-mangling-version/unstable.rs
@@ -1,6 +1,9 @@
-// revisions: legacy legacy-ok
+// revisions: legacy legacy-ok hashed hashed-ok
 // [legacy] compile-flags: -Csymbol-mangling-version=legacy
 // [legacy-ok] check-pass
 // [legacy-ok] compile-flags: -Zunstable-options -Csymbol-mangling-version=legacy
+// [hashed] compile-flags: -Csymbol-mangling-version=hashed
+// [hashed-ok] check-pass
+// [hashed-ok] compile-flags: -Zunstable-options -Csymbol-mangling-version=hashed
 
 fn main() {}
diff --git a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
index 84c2ab68da9..397e80197b9 100644
--- a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
+++ b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound-2.stderr
@@ -2,10 +2,7 @@ error[E0599]: the method `get` exists for struct `Victim<'_, Self>`, but its tra
   --> $DIR/impl-derived-implicit-sized-bound-2.rs:28:19
    |
 LL | struct Victim<'a, T: Perpetrator + ?Sized> {
-   | ------------------------------------------
-   | |
-   | method `get` not found for this struct
-   | doesn't satisfy `Victim<'_, Self>: VictimTrait`
+   | ------------------------------------------ method `get` not found for this struct because it doesn't satisfy `Victim<'_, Self>: VictimTrait`
 ...
 LL |     self.getter().get();
    |                   ^^^ method cannot be called on `Victim<'_, Self>` due to unsatisfied trait bounds
diff --git a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
index c597ad0b572..abcd915c699 100644
--- a/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
+++ b/tests/ui/trait-bounds/impl-derived-implicit-sized-bound.stderr
@@ -2,10 +2,7 @@ error[E0599]: the method `get` exists for struct `Victim<'_, Self>`, but its tra
   --> $DIR/impl-derived-implicit-sized-bound.rs:31:19
    |
 LL | struct Victim<'a, T: Perpetrator + ?Sized>
-   | ------------------------------------------
-   | |
-   | method `get` not found for this struct
-   | doesn't satisfy `Victim<'_, Self>: VictimTrait`
+   | ------------------------------------------ method `get` not found for this struct because it doesn't satisfy `Victim<'_, Self>: VictimTrait`
 ...
 LL |     self.getter().get();
    |                   ^^^ method cannot be called on `Victim<'_, Self>` due to unsatisfied trait bounds
diff --git a/tests/ui/traits/bad-sized.stderr b/tests/ui/traits/bad-sized.stderr
index fb9900bc57b..857495f4a15 100644
--- a/tests/ui/traits/bad-sized.stderr
+++ b/tests/ui/traits/bad-sized.stderr
@@ -23,7 +23,7 @@ error[E0277]: the size for values of type `dyn Trait` cannot be known at compila
   --> $DIR/bad-sized.rs:4:37
    |
 LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
-   |                                     ^^^^^^^^ doesn't have a size known at compile-time
+   |                                     ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn Trait`
 note: required by a bound in `Vec::<T>::new`
diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr
index 8d0e40be788..6d56851bf34 100644
--- a/tests/ui/traits/bound/not-on-bare-trait.stderr
+++ b/tests/ui/traits/bound/not-on-bare-trait.stderr
@@ -7,18 +7,10 @@ LL | fn foo(_x: Foo + Send) {
    = 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 a new generic type parameter, constrained by `Foo + Send`
+help: use `dyn`
    |
-LL | fn foo<T: Foo + Send>(_x: T) {
-   |       +++++++++++++++     ~
-help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference
-   |
-LL | fn foo(_x: impl Foo + Send) {
-   |            ++++
-help: alternatively, use a trait object to accept any type that implements `Foo + Send`, accessing its methods at runtime using dynamic dispatch
-   |
-LL | fn foo(_x: &(dyn Foo + Send)) {
-   |            +++++           +
+LL | fn foo(_x: dyn Foo + Send) {
+   |            +++
 
 error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
   --> $DIR/not-on-bare-trait.rs:7:8
diff --git a/tests/ui/traits/inductive-overflow/lifetime.stderr b/tests/ui/traits/inductive-overflow/lifetime.stderr
index b34bb0361f1..406f4d25dce 100644
--- a/tests/ui/traits/inductive-overflow/lifetime.stderr
+++ b/tests/ui/traits/inductive-overflow/lifetime.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `Box<X<C<'static>>>: NotAuto`
   --> $DIR/lifetime.rs:29:5
    |
 LL |     is_send::<X<C<'static>>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: required for `X<C<'static>>` to implement `NotAuto`
   --> $DIR/lifetime.rs:19:12
diff --git a/tests/ui/traits/inductive-overflow/simultaneous.stderr b/tests/ui/traits/inductive-overflow/simultaneous.stderr
index b9a746e44ba..29456d88b1b 100644
--- a/tests/ui/traits/inductive-overflow/simultaneous.stderr
+++ b/tests/ui/traits/inductive-overflow/simultaneous.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `{integer}: Tweedledum`
   --> $DIR/simultaneous.rs:18:5
    |
 LL |     is_ee(4);
-   |     ^^^^^
+   |     ^^^^^^^^
    |
 note: required for `{integer}` to implement `Combo`
   --> $DIR/simultaneous.rs:11:34
diff --git a/tests/ui/traits/inductive-overflow/supertrait.stderr b/tests/ui/traits/inductive-overflow/supertrait.stderr
index f2dccbbbb2c..99e9c8f93b8 100644
--- a/tests/ui/traits/inductive-overflow/supertrait.stderr
+++ b/tests/ui/traits/inductive-overflow/supertrait.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `NoClone: Magic`
   --> $DIR/supertrait.rs:13:18
    |
 LL |     let (a, b) = copy(NoClone);
-   |                  ^^^^
+   |                  ^^^^^^^^^^^^^
    |
 note: required for `NoClone` to implement `Magic`
   --> $DIR/supertrait.rs:5:16
diff --git a/tests/ui/traits/inductive-overflow/two-traits.stderr b/tests/ui/traits/inductive-overflow/two-traits.stderr
index 0d0bf88616c..6092c194a87 100644
--- a/tests/ui/traits/inductive-overflow/two-traits.stderr
+++ b/tests/ui/traits/inductive-overflow/two-traits.stderr
@@ -18,7 +18,7 @@ error[E0275]: overflow evaluating the requirement `*mut (): Magic`
   --> $DIR/two-traits.rs:20:5
    |
 LL |     wizard::<*mut ()>();
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^
    |
 note: required by a bound in `wizard`
   --> $DIR/two-traits.rs:17:14
diff --git a/tests/ui/traits/invalid_operator_trait.rs b/tests/ui/traits/invalid_operator_trait.rs
deleted file mode 100644
index 7ea3b0d5bac..00000000000
--- a/tests/ui/traits/invalid_operator_trait.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-#![crate_type = "lib"]
-#![feature(lang_items)]
-#![feature(no_core)]
-#![no_core]
-
-#[lang="sized"]
-pub trait Sized {
-    // Empty.
-}
-
-#[lang = "add"]
-trait Add<RHS=Self> {
-    type Output;
-
-    fn add<Y>(self, _: RHS) -> Self::Output;
-    //~^ ERROR `add` must not have any generic parameters
-}
-
-#[allow(unreachable_code)]
-fn ice(a: usize) {
-    let r = loop {};
-    r = r + a;
-}
diff --git a/tests/ui/traits/invalid_operator_trait.stderr b/tests/ui/traits/invalid_operator_trait.stderr
deleted file mode 100644
index f2e5e9080b1..00000000000
--- a/tests/ui/traits/invalid_operator_trait.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: `add` must not have any generic parameters
-  --> $DIR/invalid_operator_trait.rs:15:5
-   |
-LL |     fn add<Y>(self, _: RHS) -> Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr
index 592cfd970c6..bffad037fba 100644
--- a/tests/ui/traits/issue-77982.stderr
+++ b/tests/ui/traits/issue-77982.stderr
@@ -44,8 +44,9 @@ LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
    |                                            type must be known at this point
    |
    = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate:
+           - impl From<Char> for u32;
            - impl From<Ipv4Addr> for u32;
-           - impl From<NonZeroU32> for u32;
+           - impl From<NonZero<u32>> for u32;
            - impl From<bool> for u32;
            - impl From<char> for u32;
            - impl From<u16> for u32;
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs
index 8fddbd7ecdc..a520bf6c25b 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.rs
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs
@@ -16,14 +16,13 @@ trait Foo {
 
 impl Foo for () {
     type Item = String where String: Copy;
-    //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Copy`
+    //~^ ERROR overflow evaluating the requirement `String: Copy`
 }
 
 fn main() {
     let x = String::from("hello, world");
     drop(<() as Foo>::copy_me(&x));
-    //~^ ERROR overflow evaluating the requirement `<() as Foo>::Item: Sized`
-    //~| ERROR overflow evaluating the requirement `String <: <() as Foo>::Item`
+    //~^ ERROR overflow evaluating the requirement `String <: <() as Foo>::Item`
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed`
     //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed`
     //~| ERROR overflow evaluating the requirement `<() as Foo>::Item == _`
diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
index 874644317eb..2408e05728a 100644
--- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr
+++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr
@@ -1,15 +1,17 @@
-error[E0275]: overflow evaluating the requirement `<() as Foo>::Item: Copy`
-  --> $DIR/alias-bound-unsound.rs:18:17
+error[E0275]: overflow evaluating the requirement `String: Copy`
+  --> $DIR/alias-bound-unsound.rs:18:38
    |
 LL |     type Item = String where String: Copy;
-   |                 ^^^^^^
+   |                                      ^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
-note: required by a bound in `Foo::Item`
-  --> $DIR/alias-bound-unsound.rs:8:16
+note: the requirement `String: Copy` appears on the `impl`'s associated type `Item` but not on the corresponding trait's associated type
+  --> $DIR/alias-bound-unsound.rs:8:10
    |
+LL | trait Foo {
+   |       --- in this trait
 LL |     type Item: Copy
-   |                ^^^^ required by this bound in `Foo::Item`
+   |          ^^^^ this trait's associated type doesn't have the requirement `String: Copy`
 
 error[E0275]: overflow evaluating the requirement `String <: <() as Foo>::Item`
   --> $DIR/alias-bound-unsound.rs:24:31
@@ -27,15 +29,6 @@ LL |     drop(<() as Foo>::copy_me(&x));
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
 
-error[E0275]: overflow evaluating the requirement `<() as Foo>::Item: Sized`
-  --> $DIR/alias-bound-unsound.rs:24:10
-   |
-LL |     drop(<() as Foo>::copy_me(&x));
-   |          ^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
-   = note: the return type of a function must have a statically known size
-
 error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
   --> $DIR/alias-bound-unsound.rs:24:31
    |
@@ -61,6 +54,6 @@ LL |     drop(<() as Foo>::copy_me(&x));
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_cant_be_furthur_normalized.rs
index 04d1b949692..04d1b949692 100644
--- a/tests/ui/traits/next-solver/alias_eq_cant_be_furthur_normalized.rs
+++ b/tests/ui/traits/next-solver/alias-relate/alias_eq_cant_be_furthur_normalized.rs
diff --git a/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
index 48157192a10..48157192a10 100644
--- a/tests/ui/traits/next-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
+++ b/tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
diff --git a/tests/ui/traits/next-solver/alias_eq_simple.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_simple.rs
index 21ad1a4fa3c..21ad1a4fa3c 100644
--- a/tests/ui/traits/next-solver/alias_eq_simple.rs
+++ b/tests/ui/traits/next-solver/alias-relate/alias_eq_simple.rs
diff --git a/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.rs
index 4717aa80499..4717aa80499 100644
--- a/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.rs
+++ b/tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.rs
diff --git a/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.stderr
index 8c6840f72a7..8c6840f72a7 100644
--- a/tests/ui/traits/next-solver/alias_eq_substs_eq_not_intercrate.stderr
+++ b/tests/ui/traits/next-solver/alias-relate/alias_eq_substs_eq_not_intercrate.stderr
diff --git a/tests/ui/traits/next-solver/tait-eq-proj-2.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs
index a3df053dd83..915643f1d2a 100644
--- a/tests/ui/traits/next-solver/tait-eq-proj-2.rs
+++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj-2.rs
@@ -3,7 +3,7 @@
 
 #![feature(type_alias_impl_trait)]
 
-// Similar to tests/ui/traits/next-solver/tait-eq-proj.rs
+// Similar to tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs
 // but check the alias-sub relation in the other direction.
 
 type Tait = impl Iterator<Item = impl Sized>;
diff --git a/tests/ui/traits/next-solver/tait-eq-proj.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs
index 871e8e1e9fc..871e8e1e9fc 100644
--- a/tests/ui/traits/next-solver/tait-eq-proj.rs
+++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-proj.rs
diff --git a/tests/ui/traits/next-solver/tait-eq-tait.rs b/tests/ui/traits/next-solver/alias-relate/tait-eq-tait.rs
index 2629a124c3a..2629a124c3a 100644
--- a/tests/ui/traits/next-solver/tait-eq-tait.rs
+++ b/tests/ui/traits/next-solver/alias-relate/tait-eq-tait.rs
diff --git a/tests/ui/traits/next-solver/assembly/ambig-projection-self-is-ambig.rs b/tests/ui/traits/next-solver/assembly/ambig-projection-self-is-ambig.rs
new file mode 100644
index 00000000000..99a368a746f
--- /dev/null
+++ b/tests/ui/traits/next-solver/assembly/ambig-projection-self-is-ambig.rs
@@ -0,0 +1,19 @@
+// check-pass
+// compile-flags: -Znext-solver
+
+trait Reader: Default {
+    fn read_u8_array<A>(&self) -> Result<A, ()> {
+        todo!()
+    }
+
+    fn read_u8(&self) -> Result<u8, ()> {
+        let a: [u8; 1] = self.read_u8_array::<_>()?;
+        // This results in a nested `<Result<?0, ()> as Try>::Residual: Sized` goal.
+        // The self type normalizes to `?0`. We previously did not force that to be
+        // ambiguous but instead incompletely applied the `Self: Sized` candidate
+        // from the `ParamEnv`, resulting in a type error.
+        Ok(a[0])
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr
new file mode 100644
index 00000000000..bafc4ba18a7
--- /dev/null
+++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.is_send.stderr
@@ -0,0 +1,16 @@
+error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18
+   |
+LL |     needs_send::<Foo>();
+   |                  ^^^
+   |
+   = note: cannot satisfy `Foo: Send`
+note: required by a bound in `needs_send`
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:12:18
+   |
+LL | fn needs_send<T: Send>() {}
+   |                  ^^^^ required by this bound in `needs_send`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
index 076dab29d89..bafc4ba18a7 100644
--- a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
+++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.not_send.stderr
@@ -1,12 +1,12 @@
 error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
-  --> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:15:18
    |
 LL |     needs_send::<Foo>();
    |                  ^^^
    |
    = note: cannot satisfy `Foo: Send`
 note: required by a bound in `needs_send`
-  --> $DIR/dont-type_of-tait-in-defining-scope.rs:13:18
+  --> $DIR/dont-type_of-tait-in-defining-scope.rs:12:18
    |
 LL | fn needs_send<T: Send>() {}
    |                  ^^^^ required by this bound in `needs_send`
diff --git a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs
index a1f38e69e53..ef0360248b5 100644
--- a/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs
+++ b/tests/ui/traits/next-solver/dont-type_of-tait-in-defining-scope.rs
@@ -1,6 +1,5 @@
 // revisions: is_send not_send
 // compile-flags: -Znext-solver
-//[is_send] check-pass
 
 #![feature(type_alias_impl_trait)]
 
@@ -14,7 +13,7 @@ fn needs_send<T: Send>() {}
 
 fn test(_: Foo) {
     needs_send::<Foo>();
-    //[not_send]~^ ERROR type annotations needed: cannot satisfy `Foo: Send`
+    //~^ ERROR type annotations needed: cannot satisfy `Foo: Send`
 }
 
 fn defines(_: Foo) {
diff --git a/tests/ui/traits/next-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr
index e3be2931e12..1b776d7198e 100644
--- a/tests/ui/traits/next-solver/more-object-bound.stderr
+++ b/tests/ui/traits/next-solver/more-object-bound.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
   --> $DIR/more-object-bound.rs:12:5
    |
 LL |     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
    |
 note: required by a bound in `foo`
   --> $DIR/more-object-bound.rs:18:8
diff --git a/tests/ui/traits/next-solver/normalize-path-for-method.rs b/tests/ui/traits/next-solver/normalize-path-for-method.rs
new file mode 100644
index 00000000000..b95454306cd
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-path-for-method.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+struct Foo;
+impl Foo {
+    fn new() -> Self { Foo }
+}
+
+fn main() {
+    <Foo as Mirror>::Assoc::new();
+}
diff --git a/tests/ui/traits/next-solver/normalize-region-obligations.rs b/tests/ui/traits/next-solver/normalize-region-obligations.rs
new file mode 100644
index 00000000000..13c86b630f6
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-region-obligations.rs
@@ -0,0 +1,22 @@
+// revisions: normalize_param_env normalize_obligation
+// check-pass
+// compile-flags: -Znext-solver
+
+trait Foo {
+    #[cfg(normalize_param_env)]
+    type Gat<'a> where <Self as Mirror>::Assoc: 'a;
+    #[cfg(normalize_obligation)]
+    type Gat<'a> where Self: 'a;
+}
+
+trait Mirror { type Assoc: ?Sized; }
+impl<T: ?Sized> Mirror for T { type Assoc = T; }
+
+impl<T> Foo for T {
+    #[cfg(normalize_param_env)]
+    type Gat<'a> = i32 where T: 'a;
+    #[cfg(normalize_obligation)]
+    type Gat<'a> = i32 where <T as Mirror>::Assoc: 'a;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr
index ee38c256e5f..eedca879b0c 100644
--- a/tests/ui/traits/next-solver/object-unsafety.stderr
+++ b/tests/ui/traits/next-solver/object-unsafety.stderr
@@ -46,10 +46,7 @@ error[E0277]: the size for values of type `<dyn Setup<From = T> as Setup>::From`
   --> $DIR/object-unsafety.rs:12:5
    |
 LL |     copy::<dyn Setup<From=T>>(t)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^---
-   |     |
-   |     doesn't have a size known at compile-time
-   |     this returned value is of type `<dyn Setup<From = T> as Setup>::From`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `<dyn Setup<From = T> as Setup>::From`
    = note: the return type of a function must have a statically known size
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
index 71b1502d775..983a0fec653 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs
@@ -16,6 +16,8 @@ fn test<T: Foo1<Assoc1 = <T as Foo2>::Assoc2> + Foo2<Assoc2 = <T as Foo1>::Assoc
     //~^ ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
     //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
     //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Sized`
     //~| ERROR overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar`
 }
 
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
index bad6820f738..ed87404d573 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr
@@ -1,3 +1,11 @@
+error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
+  --> $DIR/recursive-self-normalization-2.rs:15:17
+   |
+LL |     needs_bar::<T::Assoc1>();
+   |                 ^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
+
 error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1: Bar`
   --> $DIR/recursive-self-normalization-2.rs:15:17
    |
@@ -11,6 +19,23 @@ note: required by a bound in `needs_bar`
 LL | fn needs_bar<S: Bar>() {}
    |                 ^^^ required by this bound in `needs_bar`
 
+error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1: Sized`
+  --> $DIR/recursive-self-normalization-2.rs:15:17
+   |
+LL |     needs_bar::<T::Assoc1>();
+   |                 ^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
+note: required by a bound in `needs_bar`
+  --> $DIR/recursive-self-normalization-2.rs:12:14
+   |
+LL | fn needs_bar<S: Bar>() {}
+   |              ^ required by this bound in `needs_bar`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn needs_bar<S: Bar + ?Sized>() {}
+   |                     ++++++++
+
 error[E0275]: overflow evaluating the requirement `<T as Foo1>::Assoc1 == _`
   --> $DIR/recursive-self-normalization-2.rs:15:5
    |
@@ -35,7 +60,8 @@ LL |     needs_bar::<T::Assoc1>();
    |                 ^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
index 809a6a59ca6..40e2aa9e63f 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs
@@ -12,6 +12,8 @@ fn test<T: Foo<Assoc = <T as Foo>::Assoc>>() {
     //~^ ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
     //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
     //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc == _`
+    //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Sized`
     //~| ERROR overflow evaluating the requirement `<T as Foo>::Assoc: Bar`
 }
 
diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
index 80005d344ba..e4ef2f60740 100644
--- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
+++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr
@@ -1,3 +1,11 @@
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
+  --> $DIR/recursive-self-normalization.rs:11:17
+   |
+LL |     needs_bar::<T::Assoc>();
+   |                 ^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
+
 error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc: Bar`
   --> $DIR/recursive-self-normalization.rs:11:17
    |
@@ -11,6 +19,23 @@ note: required by a bound in `needs_bar`
 LL | fn needs_bar<S: Bar>() {}
    |                 ^^^ required by this bound in `needs_bar`
 
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc: Sized`
+  --> $DIR/recursive-self-normalization.rs:11:17
+   |
+LL |     needs_bar::<T::Assoc>();
+   |                 ^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
+note: required by a bound in `needs_bar`
+  --> $DIR/recursive-self-normalization.rs:8:14
+   |
+LL | fn needs_bar<S: Bar>() {}
+   |              ^ required by this bound in `needs_bar`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn needs_bar<S: Bar + ?Sized>() {}
+   |                     ++++++++
+
 error[E0275]: overflow evaluating the requirement `<T as Foo>::Assoc == _`
   --> $DIR/recursive-self-normalization.rs:11:5
    |
@@ -35,7 +60,8 @@ LL |     needs_bar::<T::Assoc>();
    |                 ^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`)
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs
index ff25656a7ff..e7de564877d 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.rs
+++ b/tests/ui/traits/next-solver/specialization-transmute.rs
@@ -1,4 +1,5 @@
 // compile-flags: -Znext-solver
+//~^ ERROR cannot normalize `<T as Default>::Id`
 
 #![feature(specialization)]
 //~^ WARN the feature `specialization` is incomplete
diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr
index a5459165587..a1cf5b761e3 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.stderr
+++ b/tests/ui/traits/next-solver/specialization-transmute.stderr
@@ -1,5 +1,5 @@
 warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/specialization-transmute.rs:3:12
+  --> $DIR/specialization-transmute.rs:4:12
    |
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
@@ -8,12 +8,14 @@ LL | #![feature(specialization)]
    = help: consider using `min_specialization` instead, which is more stable and complete
    = note: `#[warn(incomplete_features)]` on by default
 
+error: cannot normalize `<T as Default>::Id`
+
 error[E0282]: type annotations needed
-  --> $DIR/specialization-transmute.rs:13:23
+  --> $DIR/specialization-transmute.rs:14:23
    |
 LL |     default type Id = T;
    |                       ^ cannot infer type for associated type `<T as Default>::Id`
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/traits/next-solver/specialization-unconstrained.stderr b/tests/ui/traits/next-solver/specialization-unconstrained.stderr
index ed4dafa1484..68232aacc0c 100644
--- a/tests/ui/traits/next-solver/specialization-unconstrained.stderr
+++ b/tests/ui/traits/next-solver/specialization-unconstrained.stderr
@@ -12,7 +12,7 @@ error[E0284]: type annotations needed: cannot satisfy `<u32 as Default>::Id == (
   --> $DIR/specialization-unconstrained.rs:20:5
    |
 LL |     test::<u32, ()>();
-   |     ^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id == ()`
+   |     ^^^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id == ()`
    |
 note: required by a bound in `test`
   --> $DIR/specialization-unconstrained.rs:17:20
diff --git a/tests/ui/traits/next-solver/temporary-ambiguity.rs b/tests/ui/traits/next-solver/temporary-ambiguity.rs
deleted file mode 100644
index 6102de7e446..00000000000
--- a/tests/ui/traits/next-solver/temporary-ambiguity.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// compile-flags: -Znext-solver
-// check-pass
-
-// Checks that we don't explode when we assemble >1 candidate for a goal.
-
-struct Wrapper<T>(T);
-
-trait Foo {}
-
-impl Foo for Wrapper<i32> {}
-
-impl Foo for Wrapper<()> {}
-
-fn needs_foo(_: impl Foo) {}
-
-fn main() {
-    let mut x = Default::default();
-    let w = Wrapper(x);
-    needs_foo(w);
-    x = 1;
-    let _ = x;
-}
diff --git a/tests/ui/traits/next-solver/unsound-region-obligation.rs b/tests/ui/traits/next-solver/unsound-region-obligation.rs
new file mode 100644
index 00000000000..b8bfa035388
--- /dev/null
+++ b/tests/ui/traits/next-solver/unsound-region-obligation.rs
@@ -0,0 +1,13 @@
+//~ ERROR the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime
+// compile-flags: -Znext-solver
+// Regression test for rust-lang/trait-system-refactor-initiative#59
+
+trait StaticTy {
+    type Item<'a>: 'static;
+}
+
+impl StaticTy for () {
+    type Item<'a> = &'a ();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/unsound-region-obligation.stderr b/tests/ui/traits/next-solver/unsound-region-obligation.stderr
new file mode 100644
index 00000000000..518de7ea3e0
--- /dev/null
+++ b/tests/ui/traits/next-solver/unsound-region-obligation.stderr
@@ -0,0 +1,7 @@
+error[E0477]: the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime
+   |
+   = note: type must satisfy the static lifetime
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr
index d5f2bfef192..4694e7da500 100644
--- a/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr
+++ b/tests/ui/traits/non_lifetime_binders/bad-copy-cond.stderr
@@ -11,7 +11,7 @@ error[E0277]: the trait bound `T: Copy` is not satisfied
   --> $DIR/bad-copy-cond.rs:7:5
    |
 LL |     foo();
-   |     ^^^ the trait `Copy` is not implemented for `T`
+   |     ^^^^^ the trait `Copy` is not implemented for `T`
    |
 note: required by a bound in `foo`
   --> $DIR/bad-copy-cond.rs:4:26
diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
index d8db07277c5..f4deb169516 100644
--- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
+++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr
@@ -11,7 +11,7 @@ error[E0277]: the size for values of type `V` cannot be known at compilation tim
   --> $DIR/bad-sized-cond.rs:17:5
    |
 LL |     foo();
-   |     ^^^ doesn't have a size known at compile-time
+   |     ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `V`
 note: required by a bound in `foo`
@@ -27,7 +27,7 @@ error[E0277]: `V` is not an iterator
   --> $DIR/bad-sized-cond.rs:20:5
    |
 LL |     bar();
-   |     ^^^ `V` is not an iterator
+   |     ^^^^^ `V` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `V`
    = note: required for `V` to implement `IntoIterator`
@@ -44,7 +44,7 @@ error[E0277]: the size for values of type `V` cannot be known at compilation tim
   --> $DIR/bad-sized-cond.rs:20:5
    |
 LL |     bar();
-   |     ^^^ doesn't have a size known at compile-time
+   |     ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `V`
    = note: required for `V` to implement `IntoIterator`
diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr
index 240bcef7df5..9a324c95293 100644
--- a/tests/ui/traits/non_lifetime_binders/fail.stderr
+++ b/tests/ui/traits/non_lifetime_binders/fail.stderr
@@ -11,7 +11,7 @@ error[E0277]: the trait bound `T: Trait` is not satisfied
   --> $DIR/fail.rs:19:5
    |
 LL |     fail();
-   |     ^^^^ the trait `Trait` is not implemented for `T`
+   |     ^^^^^^ the trait `Trait` is not implemented for `T`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/fail.rs:6:1
@@ -31,7 +31,7 @@ error[E0277]: `T` cannot be sent between threads safely
   --> $DIR/fail.rs:21:5
    |
 LL |     auto_trait();
-   |     ^^^^^^^^^^ `T` cannot be sent between threads safely
+   |     ^^^^^^^^^^^^ `T` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `T`
 note: required by a bound in `auto_trait`
diff --git a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr
index 8cf32c89416..abbdecf2fe1 100644
--- a/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr
+++ b/tests/ui/traits/non_lifetime_binders/foreach-partial-eq.stderr
@@ -11,7 +11,7 @@ error[E0277]: can't compare `T` with `T`
   --> $DIR/foreach-partial-eq.rs:10:5
    |
 LL |     auto_trait();
-   |     ^^^^^^^^^^ no implementation for `T < T` and `T > T`
+   |     ^^^^^^^^^^^^ no implementation for `T < T` and `T > T`
    |
    = help: the trait `PartialOrd` is not implemented for `T`
 note: required by a bound in `auto_trait`
diff --git a/tests/ui/traits/static-method-generic-inference.stderr b/tests/ui/traits/static-method-generic-inference.stderr
index 44c7c099832..80bdbbf350d 100644
--- a/tests/ui/traits/static-method-generic-inference.stderr
+++ b/tests/ui/traits/static-method-generic-inference.stderr
@@ -5,7 +5,7 @@ LL |         fn new() -> T;
    |         -------------- `HasNew::new` defined here
 ...
 LL |     let _f: base::Foo = base::HasNew::new();
-   |                         ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |                         ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
diff --git a/tests/ui/traits/track-obligations.stderr b/tests/ui/traits/track-obligations.stderr
index 89477475970..822fc91e43f 100644
--- a/tests/ui/traits/track-obligations.stderr
+++ b/tests/ui/traits/track-obligations.stderr
@@ -2,10 +2,7 @@ error[E0599]: the method `check` exists for struct `Client<()>`, but its trait b
   --> $DIR/track-obligations.rs:83:16
    |
 LL | struct ALayer<C>(C);
-   | ----------------
-   | |
-   | doesn't satisfy `<_ as Layer<()>>::Service = <ALayer<()> as ParticularServiceLayer<()>>::Service`
-   | doesn't satisfy `ALayer<()>: ParticularServiceLayer<()>`
+   | ---------------- doesn't satisfy `<_ as Layer<()>>::Service = <ALayer<()> as ParticularServiceLayer<()>>::Service` or `ALayer<()>: ParticularServiceLayer<()>`
 ...
 LL | struct Client<C>(C);
    | ---------------- method `check` not found for this struct
diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr
index 50d060cd474..805862d6c4a 100644
--- a/tests/ui/transmutability/region-infer.stderr
+++ b/tests/ui/transmutability/region-infer.stderr
@@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `W<'_>` in the defining scop
   --> $DIR/region-infer.rs:20:5
    |
 LL |     test();
-   |     ^^^^ The size of `()` is smaller than the size of `W<'_>`
+   |     ^^^^^^ The size of `()` is smaller than the size of `W<'_>`
    |
 note: required by a bound in `test`
   --> $DIR/region-infer.rs:11:12
diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.rs b/tests/ui/treat-err-as-bug/eagerly-emit.rs
index 5f32f5a1d94..ede190575d5 100644
--- a/tests/ui/treat-err-as-bug/eagerly-emit.rs
+++ b/tests/ui/treat-err-as-bug/eagerly-emit.rs
@@ -6,6 +6,5 @@ fn main() {}
 
 fn f() -> impl Foo {
     //~^ ERROR the trait bound `i32: Foo` is not satisfied
-    //~| ERROR `report_selection_error` did not emit an error
     1i32
 }
diff --git a/tests/ui/treat-err-as-bug/eagerly-emit.stderr b/tests/ui/treat-err-as-bug/eagerly-emit.stderr
index 3d25741d52d..4ae596435aa 100644
--- a/tests/ui/treat-err-as-bug/eagerly-emit.stderr
+++ b/tests/ui/treat-err-as-bug/eagerly-emit.stderr
@@ -1,9 +1,3 @@
-error: `report_selection_error` did not emit an error
-  --> $DIR/eagerly-emit.rs:7:11
-   |
-LL | fn f() -> impl Foo {
-   |           ^^^^^^^^
-
 error: trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
@@ -11,7 +5,7 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied
    |
 LL | fn f() -> impl Foo {
    |           ^^^^^^^^ the trait `Foo` is not implemented for `i32`
-...
+LL |
 LL |     1i32
    |     ---- return type was inferred to be `i32` here
    |
@@ -21,8 +15,6 @@ help: this trait has no implementations, consider adding one
 LL | trait Foo {}
    | ^^^^^^^^^
 
-error: expected fulfillment errors
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr
index 97fbbdbf8f8..7e5b68353fb 100644
--- a/tests/ui/try-trait/bad-interconversion.stderr
+++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -11,7 +11,8 @@ LL |     Ok(Err(123_i32)?)
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              <u8 as From<bool>>
-             <u8 as From<NonZeroU8>>
+             <u8 as From<NonZero<u8>>>
+             <u8 as From<Char>>
    = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
 
 error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
index af1c18bbb59..b6906f68ded 100644
--- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
+++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -4,20 +4,14 @@
 // revisions: current next
 //[next] compile-flags: -Znext-solver
 // check-pass
-
 #![feature(type_alias_impl_trait)]
 
-trait Dummy {}
-impl Dummy for () {}
-
-type F = impl Dummy;
-fn f() -> F {}
-
 trait Test {
     fn test(self);
 }
 
-impl Test for F {
+
+impl Test for define::F {
     fn test(self) {}
 }
 
@@ -27,7 +21,17 @@ impl Test for i32 {
     fn test(self) {}
 }
 
+mod define {
+    use super::*;
+
+    pub trait Dummy {}
+    impl Dummy for () {}
+
+    pub type F = impl Dummy;
+    pub fn f() -> F {}
+}
+
 fn main() {
-    let x: F = f();
+    let x = define::f();
     x.test();
 }
diff --git a/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
new file mode 100644
index 00000000000..39f0b9a02ee
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/struct-assignment-validity.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Zvalidate-mir
+// check-pass
+
+// Check that we don't cause cycle errors when validating pre-`Reveal::All` MIR
+// that assigns opaques through normalized projections.
+
+#![feature(impl_trait_in_assoc_type)]
+
+struct Bar;
+
+trait Trait {
+    type Assoc;
+    fn foo() -> Foo;
+}
+
+impl Trait for Bar {
+    type Assoc = impl std::fmt::Debug;
+    fn foo() -> Foo
+    where
+        Self::Assoc:,
+    {
+        let x: <Bar as Trait>::Assoc = ();
+        Foo { field: () }
+    }
+}
+
+struct Foo {
+    field: <Bar as Trait>::Assoc,
+}
+
+fn main() {}
diff --git a/tests/ui/type/issue-101866.stderr b/tests/ui/type/issue-101866.stderr
index 6f4b380b4e7..4d02153ebe2 100644
--- a/tests/ui/type/issue-101866.stderr
+++ b/tests/ui/type/issue-101866.stderr
@@ -5,7 +5,7 @@ LL |     fn func();
    |     ---------- `TraitA::func` defined here
 ...
 LL |     TraitA::<i32>::func();
-   |     ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
+   |     ^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
    |
 help: use the fully-qualified path to the only available implementation
    |
diff --git a/tests/ui/typeck/derive-sugg-arg-arity.stderr b/tests/ui/typeck/derive-sugg-arg-arity.stderr
index 41b16a772ca..382b324c4cc 100644
--- a/tests/ui/typeck/derive-sugg-arg-arity.stderr
+++ b/tests/ui/typeck/derive-sugg-arg-arity.stderr
@@ -2,11 +2,7 @@ error[E0599]: the function or associated item `partial_cmp` exists for struct `A
   --> $DIR/derive-sugg-arg-arity.rs:5:23
    |
 LL | pub struct A;
-   | ------------
-   | |
-   | function or associated item `partial_cmp` not found for this struct
-   | doesn't satisfy `A: Iterator`
-   | doesn't satisfy `A: PartialOrd<_>`
+   | ------------ function or associated item `partial_cmp` not found for this struct because it doesn't satisfy `A: Iterator` or `A: PartialOrd<_>`
 ...
 LL |         _ => match A::partial_cmp() {},
    |                       ^^^^^^^^^^^ function or associated item cannot be called on `A` due to unsatisfied trait bounds
diff --git a/tests/ui/typeck/issue-31173.stderr b/tests/ui/typeck/issue-31173.stderr
index d65c4306a5f..0983147a5f0 100644
--- a/tests/ui/typeck/issue-31173.stderr
+++ b/tests/ui/typeck/issue-31173.stderr
@@ -35,12 +35,6 @@ LL | |         .collect();
    | |         -^^^^^^^ method cannot be called due to unsatisfied trait bounds
    | |_________|
    | 
-  --> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
-   |
-   = note: doesn't satisfy `<_ as Iterator>::Item = &_`
-  --> $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
-   |
-   = note: doesn't satisfy `_: Iterator`
    |
    = note: the following trait bounds were not satisfied:
            `<TakeWhile<&mut std::vec::IntoIter<u8>, {closure@$DIR/issue-31173.rs:7:21: 7:25}> as Iterator>::Item = &_`
diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index ae0a06e6328..e90784a54ae 100644
--- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -59,7 +59,7 @@ error[E0277]: cannot add `u32` to `i32`
   --> $DIR/ufcs-qpath-self-mismatch.rs:4:5
    |
 LL |     <i32 as Add<u32>>::add(1, 2);
-   |     ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32`
    |
    = help: the trait `Add<u32>` is not implemented for `i32`
    = help: the following other types implement trait `Add<Rhs>`:
diff --git a/tests/ui/union/issue-81199.rs b/tests/ui/union/issue-81199.rs
index b8b0d9d33e7..2083ee15d87 100644
--- a/tests/ui/union/issue-81199.rs
+++ b/tests/ui/union/issue-81199.rs
@@ -9,7 +9,7 @@ union PtrRepr<T: ?Sized> {
 
 #[repr(C)]
 struct PtrComponents<T: Pointee + ?Sized> {
-    data_address: *const (),
+    data_pointer: *const (),
     metadata: <T as Pointee>::Metadata,
 }
 
diff --git a/tests/ui/union/union-derive-clone.stderr b/tests/ui/union/union-derive-clone.stderr
index 39f1e32e6eb..a2b81f0dba1 100644
--- a/tests/ui/union/union-derive-clone.stderr
+++ b/tests/ui/union/union-derive-clone.stderr
@@ -17,10 +17,7 @@ error[E0599]: the method `clone` exists for union `U5<CloneNoCopy>`, but its tra
   --> $DIR/union-derive-clone.rs:35:15
    |
 LL | union U5<T> {
-   | -----------
-   | |
-   | method `clone` not found for this union
-   | doesn't satisfy `U5<CloneNoCopy>: Clone`
+   | ----------- method `clone` not found for this union because it doesn't satisfy `U5<CloneNoCopy>: Clone`
 ...
 LL | struct CloneNoCopy;
    | ------------------ doesn't satisfy `CloneNoCopy: Copy`
diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr
index a7f57e3fd15..8a2ecf0f6c3 100644
--- a/tests/ui/unsized-locals/unsized-exprs.stderr
+++ b/tests/ui/unsized-locals/unsized-exprs.stderr
@@ -26,7 +26,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
   --> $DIR/unsized-exprs.rs:26:22
    |
 LL |     udrop::<A<[u8]>>(A(*foo()));
-   |                      ^ doesn't have a size known at compile-time
+   |                      ^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `A<[u8]>`, the trait `Sized` is not implemented for `[u8]`
 note: required because it appears within the type `A<[u8]>`
diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
index 4c15497d530..6de4caa76ee 100644
--- a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
+++ b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `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 `fn(&'b ())`
+   |     ^^^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&'b ())`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/higher-ranked-fn-type.rs:6:1
diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
index 3318c70f1bb..4cb3cdd69ad 100644
--- a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
+++ b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_t
   --> $DIR/higher-ranked-fn-type.rs:20:5
    |
 LL |     called()
-   |     ^^^^^^ the trait `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b))> Foo` is not implemented for `fn(&ReBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b) }) ())`
+   |     ^^^^^^^^ the trait `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b))> Foo` is not implemented for `fn(&ReBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b) }) ())`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/higher-ranked-fn-type.rs:6:1
diff --git a/triagebot.toml b/triagebot.toml
index 264f6efd982..bf898819cfc 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -476,7 +476,7 @@ of `ObligationCtxt`.
 """
 cc = ["@lcnr", "@compiler-errors"]
 
-[mentions."compiler/rustc_error_codes/src/error_codes.rs"]
+[mentions."compiler/rustc_error_codes/src/lib.rs"]
 message = "Some changes occurred in diagnostic error codes"
 cc = ["@GuillaumeGomez"]
 
@@ -488,6 +488,13 @@ cc = ["@Nadrieril"]
 message = "Some changes might have occurred in exhaustiveness checking"
 cc = ["@Nadrieril"]
 
+[mentions."library/core/src/intrinsics/simd.rs"]
+message = """
+Some changes occurred to the platform-builtins intrinsics. Make sure the
+LLVM backend as well as portable-simd gets adapted for the changes.
+"""
+cc = ["@antoyo", "@GuillaumeGomez", "@bjorn3", "@calebzulawski", "@programmerjake"]
+
 [mentions."library/portable-simd"]
 message = """
 Portable SIMD is developed in its own repository. If possible, consider \
@@ -652,6 +659,7 @@ compiler-team-contributors = [
     "@TaKO8Ki",
     "@b-naber",
     "@nnethercote",
+    "@fmease",
 ]
 compiler = [
     "compiler-team",
@@ -662,7 +670,6 @@ libs = [
     "@joshtriplett",
     "@Mark-Simulacrum",
     "@m-ou-se",
-    "@thomcc",
 ]
 bootstrap = [
     "@Mark-Simulacrum",
@@ -717,6 +724,7 @@ arena = [
 mir = [
     "@davidtwco",
     "@oli-obk",
+    "@matthewjasper"
 ]
 mir-opt = [
     "@oli-obk",
@@ -733,6 +741,7 @@ types = [
 borrowck = [
     "@davidtwco",
     "@pnkfelix",
+    "@matthewjasper"
 ]
 ast_lowering = [
     "@compiler-errors",
@@ -776,6 +785,7 @@ project-stable-mir = [
 "/compiler/rustc_data_structures/src/stable_hasher.rs" = ["compiler", "incremental"]
 "/compiler/rustc_hir_analysis" =                         ["compiler", "types"]
 "/compiler/rustc_incremental" =                          ["compiler", "incremental"]
+"/compiler/rustc_borrowck" =                             ["compiler", "borrowck"]
 "/compiler/rustc_lexer" =                                ["compiler", "lexer"]
 "/compiler/rustc_llvm" =                                 ["@cuviper"]
 "/compiler/rustc_codegen_llvm/src/debuginfo" =           ["compiler", "debuginfo"]
@@ -785,6 +795,7 @@ project-stable-mir = [
 "/compiler/rustc_const_eval/src/interpret" =             ["compiler", "mir"]
 "/compiler/rustc_const_eval/src/transform" =             ["compiler", "mir-opt"]
 "/compiler/rustc_mir_build/src/build" =                  ["compiler", "mir"]
+"/compiler/rustc_mir_transform" =                        ["compiler", "mir", "mir-opt"]
 "/compiler/rustc_smir" =                                 ["project-stable-mir"]
 "/compiler/rustc_parse" =                                ["compiler", "parser"]
 "/compiler/rustc_parse/src/lexer" =                      ["compiler", "lexer"]
@@ -802,7 +813,7 @@ project-stable-mir = [
 "/library/panic_unwind" =                                ["libs"]
 "/library/proc_macro" =                                  ["@petrochenkov"]
 "/library/std" =                                         ["libs"]
-"/library/std/src/sys/pal/windows" =                     ["@ChrisDenton", "@thomcc"]
+"/library/std/src/sys/pal/windows" =                     ["@ChrisDenton"]
 "/library/stdarch" =                                     ["libs"]
 "/library/test" =                                        ["libs"]
 "/src/bootstrap" =                                       ["bootstrap"]